Affine transforms - matrix algebra

Pavel Safrata pavel.safrata at oracle.com
Mon Jul 16 12:49:35 PDT 2012


Hello,
Ok,  Richard, thanks.

I have one more question that I asked earlier but that has not been 
addressed in this discussion: do we want to use Point3D for rotation 
axis? It would be consistent with Rotate and it would be convenient to 
use the Rotate.*_AXIS constants. In the other hand, it would often force 
users to create unnecessary Point3D instances. Or do we want both? 
Currently it means
     public void appendRotation(double theta,
double pivotX, double pivotY, double pivotZ,
double axisX, double axisY, double axisZ)
vs.
     public void appendRotation(double theta,
                                double pivotX, double pivotY, double pivotZ,
Point3D axis)
and similarly for prepend.

Here is once more the complete proposal with a few minor issues fixed 
(added 3x3 matrix handling, fixed row/col parameter order, fixed 
pivot/axis parameter order):

On Transform class:
     public Transform createConcatenation(Transform transform)
         // Creates new concatenated transform that is equivalent to
         // this transform applied first and the given transform second
         // Means multiplication on the left by the given transform
     public Transform createInverse() throws NoninvertibleTransformException
         // Creates a negated transform
     public double get(int row, int col)
         // Convenience getter for the individual elements
         // Accepts both params in range 0..3, throws IllegalArgument 
otherwise
     public double[] toArray(MatrixArrayType type)
         // Transform.MatrixArrayType is an enum { MAT_2x3, MAT_3x3, 
MAT_3x4, MAT_4x4 }
         // Returns array of length 6, 9, 12, 16, respectively
         // Throws IllegalArgument if 2x3 or 3x3 is requested for a 3D 
transform
     public double[] toArray(MatrixArrayType type, double[] array)
         // Similar to the above, just uses the passed array if it is 
big enough
     public Transform clone()
         // Of course Transform implementing Cloneable

     // in subclasses the methods returning Transform will be overridden 
and will return more specific types where possible.


On Affine class:

Constructors:
     public Affine(Transform transform)
     public Affine(double mxx, double mxy, double tx,
                   double myx, double myy, double ty)
     public Affine(double mxx, double mxy, double mxz, double tx,
                   double myx, double myy, double myz, double ty,
                   double mzx, double mzy, double mzz, double tz)
     public Affine(double[] matrix)
         // accepts arrays of length 6, 9, 12 and 16.
         // In case of 9 members the last three numbers must be 0, 0, 1
         // In case of 16 members the last four numbers must be 0, 0, 0, 1
         // throws IllegalArgument if the above conditions are not met

Setters of the entire matrix:
     public void setToTransform(Transform t)
     public void setToTransform(double mxx, double mxy, double tx,
                                double myx, double myy, double ty)
     public void setToTransform(double mxx, double mxy, double mxz, 
double mxt,
                                double myx, double myy, double myz, 
double myt,
                                double mzx, double mzy, double mzz, 
double mzt)
     public void setToTransform(double[] matrix)
         // the same acceptance criteria as the constructor
     public void setToIdentity()

Operations on the matrix (modifying it in place):
     public void invert() throws NoninvertibleTransformException
     public void append(Transform t)
     public void append(double mxx, double mxy, double tx,
                        double myx, double myy, double ty)
     public void append(double Txx, double Txy, double Txz, double Txt,
                        double Tyx, double Tyy, double Tyz, double Tyt,
                        double Tzx, double Tzy, double Tzz, double Tzt)
     public void append(double[] matrix)

     public void appendTranslation(double tx, double ty)
     public void appendTranslation(double tx, double ty, double tz)
     public void appendScale(double sx, double sy)
     public void appendScale(double sx, double sy, double pivotX, double 
pivotY)
     public void appendScale(double sx, double sy, double sz)
     public void appendScale(double sx, double sy, double sz,
                             double pivotX, double pivotY, double pivotZ)
     public void appendRotation(double theta)
     public void appendRotation(double theta, double pivotX, double pivotY)
     public void appendRotation(double theta,
                                double pivotX, double pivotY, double pivotZ,
                                double axisX, double axisY, double axisZ)
     public void appendShear(double shx, double shy)
     public void appendShear(double shx, double shy, double pivotX, 
double pivotY)

     // "append" means "add the transformation after the existing one", so
     // "append" means multiply this matrix on the left by the given matrix

     public void prepend* // 15 methods
         // Every append* method has its prepend* companion,
         // adding the transformation before the existing one,
         // multiplying on the right


Other methods:
     public void set(int row, int col, double value)
         // convenience setter for the individual elements
         // accepts row and col in range 0..3
         // allows to set the last row only to 0, 0, 0, 1
         // throws IllegalArgument if the above conditions are not met

     public double getDeterminant()

Thanks,
Pavel

On 16.7.2012 20:25, Richard Bair wrote:
> Hi Pavel,
>
> Before approving I want Jim Graham to have a look. He's been on vacation, I think he either gets back today or next week.
>
> Thanks!
> Richard
>
> On Jul 16, 2012, at 4:37 AM, Pavel Safrata wrote:
>
>> Hi Kirill,
>> it is just for convenience. The point is that if you have algorithms or other libraries that use the fourth row, you can work with the array right away.
>> Regards,
>> Pavel
>>
>> On 16.7.2012 13:28, Kirill.Prazdnikov wrote:
>>> Hi Pavel,
>>>
>>>>     public Affine(double[] matrix)
>>>>         // accepts arrays of length 6, 12 and 16.
>>>>         // In case of 16 members the last four numbers must be 0, 0, 0, 1
>>>>         // throws IllegalArgument if the above conditions are not met
>>> What is the point of setting 4x4 matrix of the last row must be 0,0,0,1 ?
>>> Should we remove 4x4 case at all ?
>>>
>>> Thanks
>>>
>>>
>>




More information about the openjfx-dev mailing list