Affine transforms - matrix algebra

Jim Graham james.graham at oracle.com
Mon Jul 23 15:02:25 PDT 2012


On 7/23/2012 5:01 AM, Pavel Safrata wrote:
>> I think that the following one is very important for performance reasons:
>>
>> void transform(double[] srcPts, int srcOffset, double[] dstPts, int
>> dstOffset, int numPts);
>>
>> with semantic identical to the one currently in the Java2D
>> AffineTransform.
>
> Unlike in J2D our Pts will have three coordinates, right? Or do we want
> transform2D and transform3D?

I'm fine with double-only for now given the rest of the FX APIs.

As far as whether the array is 2D or 3D, I'll leave that up to the 
engineers who are planning to use it.  Would 3D-only be confusing to 
them?  I could live with it either way, but it may be a culture shock 
coming from J2D.

> To me this sounds a bit frightening. I may be wrong but I believe that
> the "ulps" are there to deal with representability of certain numbers in
> floating-point types but not with different math engines producing
> different results - I believe the results may be up to one ulp wrong but
> are reliably stable among all platforms. I'm a bit afraid that providing
> unstable results would violate at least some unwritten conventions. But
> I'm not an expert here, I might be wrong.

ulp is a unit representing the minimal difference in values.  It's 
simply the only way you can realistically state errors in a floating 
point world given its sliding scale of how many bits past the decimal 
point it offers.

Stating the error should be within 1E-N is wrong because the nearest 
representable value may not be within that error bound from the true 
result depending on the magnitude of the result.  You might be able to 
guarantee that if the result is around 10, but not if the result is 
around a billion since numbers of that magnitude have fewer bits to 
devote to the fractional part.  So errors are typically stated as 
multiples of ulp.  So, saying "within 2^N ulp is the same as saying that 
the lowest N bits might be wrong".

>>> Rename the MatrixArrayType constants to MAT_2D_3x2, MAT_2D_3x3,
>>> MAT_3D_3x4, MAT_3D_4x4, do you agree?
>> I don't really have better idea at this time... I wonder if we could
>> find a way to merge with the VAT_* constants...
>
> We may use MAT for the getRow/getCol - it would specify from what matrix
> the col/row will be taken (each pair of values would provide similar
> behavior except for one of them allowing to read the last line).

Also, I don't think you can accurately determine which values to read 
without the full MAT since the 3rd row (index == 2?) of a matrix with Z 
is different from the same index row of a matrix that doesn't have Z. 
So, I think it makes sense to use the MAT types for both methods (the 
matrix and the row/col methods).

With respect to methods that don't take a MAT type - I think we should 
simply say that the default is MAT_4x4 rather than infer it from the 
size of the array - that is cleaner and avoids mistakes where they 
forgot how big their array was (as in, they allocated a temp array and 
left it around for future use and some other programmer came in and 
decided that the array should be bigger without noticing that it affects 
the values that the former code would get)...

			...jim


More information about the openjfx-dev mailing list