Parallelogram


Known direct subclasses
ImmutableParallelogram

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

MutableParallelogram

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


This class represents a parallelogram defined by its center, width, height, rotationDegrees, and skew.

The shape of the parallelogram with width w, height h, and skew s is this before rotation:

         s*h
|------|__________ Displaced horizontal edge
/ /
/ /
/ /
h / /
/ /
/ /
/_________/ Undisplaced horizontal edge
|---------|
w

The parallelogram is then translated so that its center is in the correct position and rotated by rotation θ (in radians in the equations below).

These 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(θ))}

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. One of the two horizontal edges before rotation is vertically displaced by height from the other. The sign of the height corresponds to the sign of the angle between the two semi-axes.

A Parallelogram may have a positive or negative skew (aka shear). The horizontal edge before rotation that is displaced vertically by height is also displaced horizontally by skew times height. The skew can be positive or negative, a positive skew corresponds to a smaller absolute angle between the two semi-axes. The skew is equal to the cotangent of the absolute angle between the two semi-axes.

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 180 to the angle of rotation, and normalizing rotation to the range [0, 360).

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 skew. A Parallelogram that has both width and height of zero is effectively a point, and so rotation and skew do not affect the values of the axes or corners. A Parallelogram that has height of zero is effectively a horizontal line, and so is unaffected by skew.

A few geometric objects can be represented as special cases of a Parallelogram. A rectangle is a Parallelogram with skew 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 skew of zero.

Summary

Public functions

ImmutableBox

Returns the minimum bounding box containing the Parallelogram.

android
MutableBox

Returns the minimum bounding box containing the Parallelogram.

android
List<ImmutableVec>

Returns a list containing the 4 corners of the Parallelogram.

android
Unit
computeCorners(
    outCorner1: MutableVec,
    outCorner2: MutableVec,
    outCorner3: MutableVec,
    outCorner4: MutableVec
)

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

android
List<ImmutableVec>

Returns the semi axes of this Parallelogram.

android
Unit
computeSemiAxes(outAxis1: MutableVec, outAxis2: MutableVec)

Fills the MutableVecs with the semi axes of this Parallelogram.

android
Float

Returns the signed area of the Parallelogram.

android
operator Boolean

Returns whether the given point is contained within the Box.

android
Boolean
isAlmostEqual(other: Parallelogram, tolerance: @FloatRange(from = 0.0) Float)

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 skew.

android

Public properties

abstract Vec
android
abstract Float

The height of the Parallelogram.

android
abstract Float

The rotation of the Parallelogram in degrees from its original axis-aligned orientation in the direction from the positive x-axis towards the positive y-axis.

android
abstract Float

The horizontal displacement between the two horizontal edges of the Parallelogram pre-rotation, as a multiple of the height.

android
abstract Float

The width of the Parallelogram.

android

Public functions

computeBoundingBox

fun computeBoundingBox(): ImmutableBox

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

fun computeBoundingBox(outBox: MutableBox): MutableBox

Returns the minimum bounding box containing the Parallelogram.

computeCorners

fun computeCorners(): List<ImmutableVec>

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 skew 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

fun computeCorners(
    outCorner1: MutableVec,
    outCorner2: MutableVec,
    outCorner3: MutableVec,
    outCorner4: MutableVec
): Unit

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

For explanation of order, please see computeCorners above.

computeSemiAxes

fun computeSemiAxes(): List<ImmutableVec>

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 = skew

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

fun computeSemiAxes(outAxis1: MutableVec, outAxis2: MutableVec): Unit

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

computeSignedArea

fun computeSignedArea(): Float

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

operator fun contains(point: ImmutableVec): Boolean

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

isAlmostEqual

fun isAlmostEqual(other: Parallelogram, tolerance: @FloatRange(from = 0.0) Float): Boolean

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 skew.

Public properties

center

abstract val centerVec

height

abstract val heightFloat

The height of the Parallelogram. May be positive or negative, corresponding to whether the angle from the first semi-axis to the second is also positive or negative.

rotationDegrees

abstract val rotationDegreesFloat

The rotation of the Parallelogram in degrees from its original axis-aligned orientation in the direction from the positive x-axis towards the positive y-axis.

skew

abstract val skewFloat

The horizontal displacement between the two horizontal edges of the Parallelogram pre-rotation, as a multiple of the height. Equivalently, this is the cotangent of the absolute angle between the semi-axes. A Parallelogram may have a positive or negative skew, a greater skew indicates a smaller absolute angle between the semi-axes.

width

abstract val widthFloat

The width of the Parallelogram. 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 180 to rotationDegrees and normalizing that to the range [0, 360).