diff --git a/src/main/java/pythagoras/d/AbstractTransform.java b/src/main/java/pythagoras/d/AbstractTransform.java index 7851473..8a70678 100644 --- a/src/main/java/pythagoras/d/AbstractTransform.java +++ b/src/main/java/pythagoras/d/AbstractTransform.java @@ -97,6 +97,23 @@ public abstract class AbstractTransform implements Transform throw new UnsupportedOperationException(); } + @Override // from Transform + public Transform shear (double sx, double sy) { + shearX(sx); + shearY(sy); + return this; + } + + @Override // from Transform + public Transform shearX (double sx) { + throw new UnsupportedOperationException(); + } + + @Override // from Transform + public Transform shearY (double sy) { + throw new UnsupportedOperationException(); + } + @Override // from Transform public Transform setTx (double tx) { throw new UnsupportedOperationException(); diff --git a/src/main/java/pythagoras/d/AffineTransform.java b/src/main/java/pythagoras/d/AffineTransform.java index fa2c0db..e6154b2 100644 --- a/src/main/java/pythagoras/d/AffineTransform.java +++ b/src/main/java/pythagoras/d/AffineTransform.java @@ -231,6 +231,21 @@ public class AffineTransform extends AbstractTransform return Transforms.multiply(this, 1, 0, 0, 1, 0, ty, this); } + @Override // from Transform + public Transform shear (double sx, double sy) { + return Transforms.multiply(this, 1, sy, sx, 1, 0, 0, this); + } + + @Override // from Transform + public Transform shearX (double sx) { + return Transforms.multiply(this, 1, 0, sx, 1, 0, 0, this); + } + + @Override // from Transform + public Transform shearY (double sy) { + return Transforms.multiply(this, 1, sy, 0, 1, 0, 0, this); + } + @Override // from Transform public Transform invert () { // compute the determinant, storing the subdeterminants for later use diff --git a/src/main/java/pythagoras/d/MathUtil.java b/src/main/java/pythagoras/d/MathUtil.java index e071828..9b255ef 100644 --- a/src/main/java/pythagoras/d/MathUtil.java +++ b/src/main/java/pythagoras/d/MathUtil.java @@ -103,7 +103,7 @@ public class MathUtil public static double lerpa (double a1, double a2, double t) { double ma1 = mirrorAngle(a1), ma2 = mirrorAngle(a2); double d = Math.abs(a2 - a1), md = Math.abs(ma1 - ma2); - return (d < md) ? lerp(a1, a2, t) : mirrorAngle(lerp(ma1, ma2, t)); + return (d <= md) ? lerp(a1, a2, t) : mirrorAngle(lerp(ma1, ma2, t)); } /** @@ -166,12 +166,23 @@ public class MathUtil } /** - * Returns the mirror angle of the specified angle (assumed to be in [-pi, +pi]). + * Returns the mirror angle of the specified angle (assumed to be in [-pi, +pi]). The angle is + * mirrored around the PI/2 if it is positive, and -PI/2 if it is negative. One can visualize + * this as mirroring around the "y-axis". */ public static double mirrorAngle (double a) { return (a > 0f ? Math.PI : -Math.PI) - a; } + /** + * Returns the mirror angle of the specified angle (assumed to be in [-pi, +pi]). The angle is + * mirrored around the origin (zero degrees). One can visualize this as mirroring around the + * "x-axis". + */ + public static double mirrorAngleOrigin (double a) { + return a + (a > 0f ? -Math.PI : Math.PI); + } + /** * Sets the number of decimal places to show when formatting values. By default, they are * formatted to three decimal places. diff --git a/src/main/java/pythagoras/d/Transform.java b/src/main/java/pythagoras/d/Transform.java index b679960..7dfe8e1 100644 --- a/src/main/java/pythagoras/d/Transform.java +++ b/src/main/java/pythagoras/d/Transform.java @@ -137,6 +137,21 @@ public interface Transform * @throws UnsupportedOperationException if the transform is not rigid body or greater. */ Transform translateY (double ty); + /** Shears this transform. + * @return this instance, for chaining. + * @throws UnsupportedOperationException if the transform is not affine or greater. */ + Transform shear (double tx, double ty); + + /** Shears this transform in the x dimension. + * @return this instance, for chaining. + * @throws UnsupportedOperationException if the transform is not affine or greater. */ + Transform shearX (double tx); + + /** Shears this transform in the y dimension. + * @return this instance, for chaining. + * @throws UnsupportedOperationException if the transform is not affine or greater. */ + Transform shearY (double ty); + /** Returns a new transform that represents the inverse of this transform. * @throws NoninvertibleTransformException if the transform is not invertible. */ Transform invert ();