# Affine transforms - matrix algebra

Jim Graham james.graham at oracle.com
Mon Aug 13 16:49:40 PDT 2012

```Hi Pavel,

Thanks for the revisions!

I am working on the assumption that all of the following are useful and
(not sure what word to use) ?sensical? operations:

p + v = p
v + p = p
v + v = v

p - p = v
p - v = p
v - v = v  (?)

And some which don't really make much sense:

p + p = ?
v - p = ?

On 8/13/2012 7:48 AM, Pavel Safrata wrote:
> // Creates a point with distances from origin added (adds two vectors)

or point+vector is also a common operation, no?

> public Point3D subtract(Point3D point)
> // Creates a point with the given point's distances from origin subtracted
> // (subtracts two vectors)

It is also viable to subtract a vector from a point, no?

> ? should the above three methods be named getSomething to stress that
> the operation doesn't modify the object?

getSubtractedSomething?

I can't think of any really good name using "get" there, anyone else?

In my taxonomy "getFoo" doesn't make any guarantees about the uniqueness
of foo, so if we plan to return "this" if the argument is an identity
operand, then getFoo() makes sense, but since Point3D is modifiable I
don't think we should have that philosophy.

"createFoo" always promises a new object.

Also, in many cases we provide:

Foo Foo.operate(Foo_operand, Foo_result_container)

so that code can reuse objects.  I think that makes sense here as well.

> public Point3D getCenter(Point3D)
> // Gets center between the two points

Or "midpoint"?

> public double getAngle(Point3D)
> // Gets angle between the two points when observed from the origin
> // (angle between vectors)

What about the static variant "getAngle(po, p1, p2)"?

> public double getLength()
> // Gets distance from the origin (lenght of a vector)
> ? should it be named getDistance() not to look that weird on Point?

getMagnitude?  I've heard that a vector has "direction and magnitude"
and this would be measuring that property (though I'm not sure we want
to call the angle method "getDirection"?)

> public Point3D crossProduct(Point3D point)
> public double dotProduct(Point3D point)
> // Compute product of the two vectors (I don't think we can reasonably
> document those as point operations)

If we document that a Point3D can be considered either as a point with
its location specified in 3-space as well as a vector with its direction
and magnitude specified by its relative location from the origin, then
we can document any vector-oriented operations as "the vector
represented by this Point3D object"...

> public Point3D transform(Point3D point)
> // Transforms the point
> public Point2D transform(Point2D point)
> // throws IllegalArgument for 3D transform

I think we discussed it before, but do we want "void transform(p1,
presult)"?

> public Bounds transform(Bounds bounds)
> // Transforms the bounds
> public void transform2D(double[] srcPts, int srcOffset, double[] dstPts,
> int dstOffset, int numPts)
> // similar to J2D
> public void transform3D(double[] srcPts, int srcOffset, double[] dstPts,
> int dstOffset, int numPts)
> // similar to the above but with tree coordinates per point

Perhaps call them "transformNDpoints" to disambiguate from "transform
these points as if this were a 2D or 3D transform"?

> public double getDeterminant()
> public boolean is2D()
> public boolean is3D()

isIdentity()?

Also, I'm assuming that "is2D()" returns based on the current elements
of the transform's matrix and not the "class type"?

> public double[] toArray(MatrixType type)
> // Returns flattened matrix specified by type
> public double[] toArray(MatrixType type, double[] array)
> // Similar to the above, just uses the passed array if it is big enough
> public double[] getRow(MatrixType type, int row)
> public double[] getRow(MatrixType type, int row, double[] array)
> public double[] getColumn(MatrixType type, int column)
> public double[] getColumn(MatrixType type, int column, double[] array)
> // Similar to toAarray returning the particular tuples
> // throw IndexOutOfBounds if index out of the range specified by type

Would there be a "getMatrixType"?

> // Support for the transform changed event:
> // Transform will implement EventTarget interface
> protected void transformChanged()
> // for the subclasses to call when the transform changes
> public <T extends Event> void addEventFilter(EventType<T> eventType,
> EventHandler<? super T> eventHandler)
> public <T extends Event> void removeEventFilter(EventType<T> eventType,
> EventHandler<? super T> eventHandler)
> public <T extends Event> void addEventHandler(final EventType<T> eventType,
> final EventHandler<? super T> eventHandler)
> public <T extends Event> void removeEventHandler(EventType<T> eventType,
> EventHandler<? super T> eventHandler)
> public final void setOnTransformChanged(EventHandler<? super
> TransformChangedEvent> value)

I hope someone involved more in FX events can review this.

> public void appendScale(double sx, double sy, double pivotX, double pivotY)

I wish we had called it "anchor".  "Pivot" is a bizarre name for the
origin of a scale - in retrospect.

> 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 appendRotation(double theta,
> double pivotX, double pivotY, double pivotZ,
> Point3D axis)
> public void appendShear(double shx, double shy)
> public void appendShear(double shx, double shy, double pivotX, double
> pivotY)

The appendRotation(... Point3D axis) stands out.  Should we have
variants for all of the pivotXYZ methods that take a Point2D/3D?

...jim
```