Parallelogram


public abstract class Parallelogram

Known direct subclasses
ImmutableParallelogram

Immutable parallelogram (i.e. a quadrilateral with parallel sides), defined by its center, width, height, rotation, and shearFactor.

MutableParallelogram

Mutable parallelogram (i.e. a quadrilateral with parallel sides), defined by its center, width, height, rotation, and shearFactor.


This class represents a parallelogram (i.e. a quadrilateral with parallel sides), defined by its center, width, height, rotation, and shearFactor.

Parameters of a Parallelogram are used to define a pair of vector semi-axes:

u = {.5 * w * cos(θ), .5 * w * sin(θ)}
v = {.5 * h * (s * cos(θ) - sin(θ)), .5 * h * (s * sin(θ) + cos(θ))}

where w is the width, h is the height, s is the shearFactor and θ is the angle of rotation. From the semi-axes, we define the shape of the parallelogram as the set of all points c + 𝛼 * u + 𝛽 * v, where c is the center, and 𝛼 and 𝛽 are real numbers in the interval -1, 1.

Note: Java code should use the factory static function from* in MutableParallelogram or ImmutableParallelogram to create Parallelogram instances.

A Parallelogram may have a positive or negative height; a positive height indicates that the angle from the first semi-axis to the second will also be positive.

A Parallelogram may have a positive or negative shear factor; a positive shear factor indicates a smaller absolute angle between the semi-axes (the shear factor is, in fact, the cotangent of that angle).

A Parallelogram may not have a negative width. If an operation on a parallelogram or the construction of a parallelogram would result in a negative width, it is instead normalized, by negating both the width and the height, adding π to the angle of rotation, and normalizing rotation to the range [0, 2π).

A Parallelogram may also be degenerate; that is, its width or height, or both, may be zero. Degenerate Parallelograms may still have a non-zero rotation and/or shearFactor. A Parallelogram that has both width and height of zero is effectively a point, and so rotation and shearFactor do not affect the values of the axes or corners. A Parallelogram that has either width or height of zero (but not both) is effectively a line segment, and so is similarly unaffected by shearFactor.

More intuitively, you can think of the shape of the Parallelogram, before taking the center and rotation into account, like this:

         s*h
|------|__________
⎡ / /
⎢ / /
⎢ / /
h ⎢ / /
⎢ / /
⎢ / /
⎣ /_________/
|---------|
w

Where w is the width, h is the height, and s is the shearFactor. You then rotate, and translate such that the center is in the correct position.

A few geometric objects can be represented as special cases of a Parallelogram. A generic rectangle is a Parallelogram with shearFactor of zero. (It can be rotated with respect to the axes, and hence might have a non-zero rotation). A Box, an axis-aligned rectangle; is a Parallelogram with both rotation and shearFactor of zero.

Summary

Public methods

final @NonNull ImmutableBox

Returns the minimum bounding box containing the Parallelogram.

final @NonNull MutableBox

Returns the minimum bounding box containing the Parallelogram.

final @NonNull List<@NonNull ImmutableVec>

Returns a list containing the 4 corners of the Parallelogram.

final void
computeCorners(
    @NonNull MutableVec outCorner1,
    @NonNull MutableVec outCorner2,
    @NonNull MutableVec outCorner3,
    @NonNull MutableVec outCorner4
)

Populates the 4 output points with the corners of the Parallelogram.

final @NonNull List<@NonNull ImmutableVec>

Returns the semi axes of this Parallelogram.

final void

Fills the MutableVecs with the semi axes of this Parallelogram.

final float

Returns the signed area of the Parallelogram.

final boolean

Returns whether the given point is contained within the Box.

abstract @NonNull Vec
abstract float

A Parallelogram may have a positive or negative height; a positive height indicates that the angle from the first semi-axis to the second will also be positive.

abstract @AngleRadiansFloat float
abstract float

A Parallelogram] may have a positive or negative shear factor; a positive shear factor indicates a smaller absolute angle between the semi-axes (the shear factor is, in fact, the cotangent of that angle).

abstract @FloatRange(from = 0.0) float

A Parallelogram may not have a negative width.

final boolean
isAlmostEqual(
    @NonNull Parallelogram other,
    @FloatRange(from = 0.0) float tolerance
)

Compares this Parallelogram with other, and returns true if both center points are considered almost equal with the given tolerance, and the difference between width and other.width is less than tolerance, and likewise for height, rotation, and shearFactor.

Public methods

computeBoundingBox

Added in 1.0.0-alpha06
public final @NonNull ImmutableBox computeBoundingBox()

Returns the minimum bounding box containing the Parallelogram.

Performance-sensitive code should use the computeBoundingBox overload that takes a pre-allocated MutableBox, so that instance can be reused across multiple calls.

computeBoundingBox

Added in 1.0.0-alpha06
public final @NonNull MutableBox computeBoundingBox(@NonNull MutableBox outBox)

Returns the minimum bounding box containing the Parallelogram.

computeCorners

Added in 1.0.0-alpha06
public final @NonNull List<@NonNull ImmutableVeccomputeCorners()

Returns a list containing the 4 corners of the Parallelogram.

Corners are numbered 0, 1, 2, 3. In a Y-up coordinate system, the corners of the base rectangle are, in order: bottom-left, bottom-right, top-right, top-left. In a Y-down coordinate system, they are: top-left, top-right, bottom-right, bottom-left. The corners keep their numbering through any shear and/or rotation applied to the base rectangle. Numerically, the corners are equivalent to: C - u - v C + u - v C + u + v C - u + v Where C = center, and u and v are the semiAxes.

Performance-sensitive code should use the computeCorners overload that takes pre-allocated MutableVecs, so that instances can be reused across multiple calls.

computeCorners

Added in 1.0.0-alpha06
public final void computeCorners(
    @NonNull MutableVec outCorner1,
    @NonNull MutableVec outCorner2,
    @NonNull MutableVec outCorner3,
    @NonNull MutableVec outCorner4
)

Populates the 4 output points with the corners of the Parallelogram.

For explanation of order, please see computeCorners above.

computeSemiAxes

Added in 1.0.0-alpha06
public final @NonNull List<@NonNull ImmutableVeccomputeSemiAxes()

Returns the semi axes of this Parallelogram. These are equal to:

- (.5 * w * cos(θ), .5 * w * sin(θ))
- (.5 * h * (s * cos(θ) - sin(θ)), .5 * h * (s * sin(θ) + cos(θ)))

respectively, where w = width, h = height, θ = rotation, and s = shearFactor

The semi-axes of a parallelogram are two vectors. Each one points from the center to the midpoint of an edge. The first semi-axis points from the center to the midpoint of the edge between corners 1 and 2, and the second semi-axis points from the center to the midpoint of the edge between corners 2 and 3. In a Y-up coordinate system, on the base rectangle, these two edges are the right and top, respectively. In a Y-down coordinate system, on the base rectangle, they are the right and bottom, respectively.

Performance-sensitive code should use the computeSemiAxes overload that takes a pre-allocated MutableVecs, so that instances can be reused across multiple calls.

computeSemiAxes

Added in 1.0.0-alpha06
public final void computeSemiAxes(@NonNull MutableVec outAxis1, @NonNull MutableVec outAxis2)

Fills the MutableVecs with the semi axes of this Parallelogram. For definition please see computeSemiAxes above.

computeSignedArea

Added in 1.0.0-alpha06
public final float computeSignedArea()

Returns the signed area of the Parallelogram. If either the width or the height is zero, this will be equal to zero; if the width is non-zero, then this will have the same sign as the height.

contains

Added in 1.0.0-alpha06
public final boolean contains(@NonNull ImmutableVec point)

Returns whether the given point is contained within the Box. Points that lie exactly on the Box's boundary are considered to be contained.

getCenter

Added in 1.0.0-alpha06
public abstract @NonNull Vec getCenter()

getHeight

Added in 1.0.0-alpha06
public abstract float getHeight()

A Parallelogram may have a positive or negative height; a positive height indicates that the angle from the first semi-axis to the second will also be positive.

getRotation

Added in 1.0.0-alpha06
public abstract @AngleRadiansFloat float getRotation()

getShearFactor

Added in 1.0.0-alpha06
public abstract float getShearFactor()

A Parallelogram] may have a positive or negative shear factor; a positive shear factor indicates a smaller absolute angle between the semi-axes (the shear factor is, in fact, the cotangent of that angle).

getWidth

Added in 1.0.0-alpha06
public abstract @FloatRange(from = 0.0) float getWidth()

A Parallelogram may not have a negative width. If an operation on a parallelogram would result in a negative width, it is instead normalized, by negating both the width and the height, adding π to the angle of rotation, and normalizing rotation to the range [0, 2π).

isAlmostEqual

Added in 1.0.0-alpha06
public final boolean isAlmostEqual(
    @NonNull Parallelogram other,
    @FloatRange(from = 0.0) float tolerance
)

Compares this Parallelogram with other, and returns true if both center points are considered almost equal with the given tolerance, and the difference between width and other.width is less than tolerance, and likewise for height, rotation, and shearFactor.