Private
accuracy_How close in space we need to be to a collision, to decide to handle it, as a percentage of the targetGap = distanceTol/2.
Protected
angular_angular velocity about center of mass
Private
body_coordinate system of this body in its last known position prior to the present
Private
body_Keep LocalCoords to avoid allocating a new one, for better performance.
Private
bottom_bottom of bounds in body coordinates
Private
centroidcached centroid radius = max distance between center of mass and any point on body
Private
centroid_Geometric center of this Polygon, in body coords
Protected
cm_center of mass in body coordinates
Protected
coscosine of angle.
Private
distancedistance tolerance, for determining if RigidBody is in contact with another RigidBody
Private
edges_list of Edges in this Polygon
Private
elasticity_elasticity of this body, from 0 to 1.
Private
finished_whether Polygon is finished being constructed
Private
left_left side of bounds in body coordinates
Protected
minthe minimum value the vertical position of this body can take on, used in energy calculations
Protected
moment_moment about center of mass divided by mass
Private
nonlist of objects this body does not collide with
Private
nonA set of Edges on some other Polygon that this Polygon never collides with.
Private
paths_list of starting Vertex for each sub-path
Private
right_right side of bounds in body coordinates
Protected
sinsine of angle
Private
specialAn Edge that takes priority for collision handling, as in a wall object, when this is not null then special proximity testing is done. Note that the other Edges of this object will have zero centroid radius and therefore will be inactive for collisions; and this allows objects to penetrate into this body thru those inactive Edges.
Private
specialthe special normal Edge (if any) in world coords. This is a cache to avoid costs of doing rotateBodyToWorld and getNormalBody method.
Private
startstart Vertex of current path; only used during construction
Private
top_top of bounds in body coordinates
Private
varsthe index into the variables array for this Polygon, or -1 if not in vars array
Private
velocityvelocity tolerance, for determining if RigidBody is in contact with another RigidBody
Private
vertices_list of Vertexes in this Polygon
Protected
zerothe vertical coordinate where this body has zero potential energy; or null to use the default zero energy level.
Static
IDCounter used for naming SimObjects.
Static
Readonly
OPEN_Counter used for naming Polygons.
Static
Readonly
PRINT_print Edge & Vertex info for each Polygon when created.
Static
Readonly
SHOW_add small circle at all Vertexes, including mid-point Vertexes
Static
Readonly
SHOW_add small circle at end point Vertexes
Adds a CircularEdge to the open path of this Polygon, starting at the current last Vertex and ending at the given point, with the given center for the circular arc, and moving clockwise or counter-clockwise from the start Vertex. See lastOpenVertex and startPath.
the endpoint of the new Edge, in body coordinates
the center point in body coordinates
true moves clockwise, false moves counter-clockwise
true
means that any point outside the circle is outside
of this body; false
means the opposite, that any point inside the circle is
outside this body.
the Edge that is created
if Polygon does not have an open path to add Edges to
if p_body
and last point are not equidistant from center_body
within CircularEdge.TINY_POSITIVE
tolerance
Adds a CircularEdge to the open path of this Polygon, starting at the current last Vertex and ending at the given point, with the given radius for the circular arc, and moving clockwise or counter-clockwise from the start Vertex. See lastOpenVertex and startPath.
The center point is calculated from the two end-points, the radius, the direction
(clockwise or counter-clockwise), and the aboveRight
parameter. The center is at the
vertex of an isoceles triangle with edges of length radius
and base being the line
from the last point to p_body
.
There are two choices for where to put the center in relation to the line connecting the
two given points: either above or below the line. The aboveRight
parameter specifies
which choice to make. For a vertical connecting line, the choice is right or left of the
line.
the endpoint of the new Edge, in body coordinates
the radius of the CircularEdge
if true
, then the center of CircularEdge is located
above or right of the line connecting vertex1
and vertex2
;
if false
, then center is located below or left of the connecting line.
true moves clockwise, false moves counter-clockwise
true
means that any point outside the circle is outside
of this body; false
means the opposite, that any point inside the circle is
outside this body.
the Edge that is created
if Polygon does not have an open path to add Edges to
Adds the Edge to current open path. The start Vertex of the Edge must match the end Vertex of last Edge in open path as given by lastOpenVertex. See startPath.
the Edge to add to current open path
if there is no open path, or the start Vertex of the Edge does not match the end Vertex of last Edge in open path.
Adds to set of RigidBodys that do not collide with this body. No collisions or contacts are generated between this body and the given bodies. See doesNotCollide.
array of RigidBodys that should not be collided with
Adds a StraightEdge to the open path of this Polygon, starting at the current last Vertex and ending at the given point. See lastOpenVertex and startPath.
the end point of the new Edge, in body coordinates
true means that any point above this Edge is on the outside of this body (for vertical lines a point to the right is outside); false means the opposite, that any point below (or left) is outside this body.
the Edge that is created
if Polygon does not have an open path to add Edges to
Moves this body so that a certain point on this body is aligned to the given world
coordinates location; optionally sets the angle of this body by rotating around the
center of mass angle
radians counter-clockwise from the body coordinates
orientation.
the point on this body to be
aligned to the new p_world
location, in body coordinates
the world coordinates location to
move the specified p_body
point to
Optional
opt_angle: numberthe angle in radians to rotate this body counter-clockwise from 'body coordinates' orientation; if not specified then leave the angle as is.
if this MassObject is immoveable
Returns the world coordinates of the given body coordinates point, based on current position of this object.
the point, in body coordinates
the point in world coordinates
Returns the AffineTransform from body to world coordinates.
the AffineTransform from body to world coordinates.
Private
calculateCalculates the bounding box for this object. See getBoundsBody.
Checks if this RigidBody has a collision or contact with another RigidBody, if so adds a new RigidBodyCollision to the list of collisions.
the list of collisions to add to
the RigidBody to check for collisions with
current simulation time
Closes the current path of the Polygon. Connects the starting Vertex of the open path with the last Edge of the open path. See startPath, lastOpenEdge, and getStartVertex.
true
if there was an open path that was successfully closed
if Polygon construction was previously finished
if start and end Vertex of the path are not at the same location
Private
closeCloses an open path by connecting the Edges whose given Vertexes are at the same location.
Each Vertex must be connected to only one Edge. The previous Edge for v1 must be null. The next Edge for v2 must be null. Both Vertexes must be at (nearly) the same location in space (the distance between them can be at most 1E-8).
The situation on entry is:
prevEdge vertex nextEdge
-------- ------ --------
null v1 edgeA
edgeB v2 null
On exit the situation is:
prevEdge vertex nextEdge
-------- ------ --------
edgeB v1 edgeA
and Vertex v2 is deleted.
Creates the JavaScript Canvas path that represents the shape of this object
in the given Canvas context using body coordinates. Note that this calls
CanvasRenderingContext2D.beginPath()
which discards any currently defined path and
begins a new one. Also, this concept of 'path' is different from the path of Edges
that makes up a Polygon (though the Canvas path is created from those Polygon
paths).
the CanvasRenderingContext2D to create the path in
Returns true if this body does not collide with the given body. See addNonCollide.
the RigidBody of interest
true if this body does not collide with the given body
Erases any recently saved local coordinate system. See saveOldCoords, getOldCoords.
Returns the collision distance accuracy, a fraction between zero and one; when the
collision distance is within accuracy * targetGap
of the target gap distance, then
the collision is considered close enough to handle (apply an impulse).
the collision accuracy, a fraction between 0 (exclusive) and 1 (inclusive)
Returns the counter-clockwise angle of rotation of this body about its center of mass, in radians, relative to 'body coordinates' orientation.
the counter-clockwise angle of rotation of this body about its center of mass, in radians, relative to 'body coordinates' orientation
Returns vertical coordinate of bottom-most point of this body, based on its current position and orientation, in world coordinates. This is approximate when the body has curved edges; because this looks at all the Vertex's of the body, and curved edges have a series of 'decorated' Vertexes on them which don't capture the exact nature of the geometric curve.
vertical coordinate of bottom-most point of this body, in world coordinates
Returns rectangle that contains this body in body coordinates.
rectangle that contains this body in body coordinates
Returns a rectangle that contains this SimObject in world coordinates.
rectangle that contains this SimObject in world coordinates
Returns the center of the circle to use for proximity testing, in body coords. A
circle centered at this location with radius getCentroidRadius()
should enclose this
MassObject. See getCentroidRadius,
getCentroidWorld.
the center of the circle to use for proximity testing, in body coords
Returns the radius of the circle to use for proximity testing. A circle
centered at getCentroidBody()
with this radius should enclose this MassObject.
See getCentroidBody, getCentroidWorld.
the radius of the circle to use for proximity testing.
Returns the center of the circle to use for proximity testing, in world coords. A
circle centered at this location with radius getCentroidRadius()
should enclose this
MassObject. See getCentroidBody,
getCentroidRadius.
the center of the circle to use for proximity testing, in world coords
Returns the elasticity used when calculating collisions; a value of 1.0 means perfect elasticity where the kinetic energy after collision is the same as before (extremely bouncy), while a value of 0 means no elasticity (no bounce). A collision uses the lesser elasticity value of the two bodies involved.
elasticity used when calculating collisions, a number from 0 to 1.
Returns the expiration time, when this SimObject should be removed from the SimList. This is intended for temporary SimObjects that illustrate, for example, contact forces or collisions.
the expiration time, in time frame of the Simulation clock
Returns vertical coordinate of left-most point of this body, based on its current position and orientation, in world coordinates. This is approximate when the body has curved edges; because this looks at all the Vertex's of the body, and curved edges have a series of 'decorated' Vertexes on them which don't capture the exact nature of the geometric curve.
vertical coordinate of left-most point of this body, in world coordinates
Returns the minimum height that this body's center of gravity can reach, used for potential energy calculations. Put another way: this is how low the center of gravity of this body can be when resting on the ground, and the ground is at height zero.
the minimum height this body can reach.
Private
getName of this SimObject, either the language-independent name for scripting purposes or the localized name for display to user.
The language-independent name should be the same as the English version but capitalized and with spaces and dashes replaced by underscore, see Util.toName, nameEquals.
The name should give an idea of the role of the SimObject in the simulation. This allows us to to treat an object in a special way depending on its name. For example, we might use the name to decide what type of DisplayObject to create to represent the SimObject.
Optional
opt_localized: booleantrue
means return the localized version of the name;
default is false
which means return the language independent name.
name of this SimObject
Returns the recently saved local coordinate system. See saveOldCoords.
the recently saved local coordinate system.
Returns vertical coordinate of right-most point of this body, based on its current position and orientation, in world coordinates. This is approximate when the body has curved edges; because this looks at all the Vertex's of the body, and curved edges have a series of 'decorated' Vertexes on them which don't capture the exact nature of the geometric curve.
vertical coordinate of right-most point of this body, in world coordinates
The normal vector (if any) used in the special edge proximity test. When a special
edge has been specified, that Edge that takes priority for collision handling, as in a
wall object, and this method returns the normal vector to use for special proximity
testing. Otherwise this returns null
and regular proximity testing is done. A normal
is a unit-length Vector that is perpendicular to an Edge. This maintains a cache to
avoid computational costs.
See Special Edge for Proximity Testing
normal vector for special edge, in world coordinates, or null when there is no special edge
Returns vertical coordinate of top-most point of this body, based on its current position and orientation, in world coordinates. This is approximate when the body has curved edges; because this looks at all the Vertex's of the body, and curved edges have a series of 'decorated' Vertexes on them which don't capture the exact nature of the geometric curve.
vertical coordinate of top-most point of this body, in world coordinates
Returns the name of the specified variable. For more understandable code, you can use the enum RB instead of these index numbers.
which variable name is desired: 0 = x-position, 1 = x-velocity, 2 = y-position, 3 = y-velocity, 4 = angle, 5 = angular velocity
whether to return localized variable name
the name of the specified variable for this particular body
Returns the index into the VarsList for this RigidBody's first variable (the x-position). The VarsList contains 6 variables for each RigidBody,
0. x-position,
1. x-velocity,
2. y-position,
3. y-velocity,
4. angle,
5. angular velocity
For more understandable code, you can use the enum RB instead of these index numbers.
the index of the x-position in the VarsList for this body;
or -1
if this body is not in the VarsList.
Returns velocity of the given point on this object. The point is specified in body coordinates, but the velocity is in world coordinates.
Optional
p_body: GenericVectorthe point to find the velocity of, in body coordinates; if undefined, then center of mass is used
the velocity of the given point, in world coordinates
Returns velocity tolerance used to determine if this RigidBody is in contact with another RigidBody.
Velocity tolerance is set on each RigidBody, but we expect it to be the same for all RigidBodys. ImpulseSim 'owns' the velocity tolerance, it is merely passed along to the RigidBody because it is needed during collision finding and RigidBody has no way of finding ImpulseSim.
Note however that because Scrim is immutable, it always returns zero for velocity tolerance. In this case, use the velocity tolerance of the other non-Scrim RigidBody involved in the collision.
velocity tolerance used to determine if this RigidBody is in contact with another RigidBody
Returns the vertical coordinate where the body has zero potential gravitational energy under standard constant gravity when the body's center of mass is at this vertical coordinate.
the vertical world coordinate where this body has zero potential energy; or null to use the default zero energy level
Whether this implements the MassObject interface.
Whether this implements the MassObject interface.
Returns last Vertex in current open path. This is the ending Vertex of the last Edge in the linked list of Edges that makes up the open path. If there is no Edge in the path then this is the starting Vertex, see startPath and getStartVertex.
last Vertex in current open path
if there is no open path
Private
maxReturns the square of the maximum distance from the given point in body coords to any Vertex of this Polygon.
the point in body coords
the square of the maximum distance from the given point in body coords to any Vertex of this Polygon
Returns moment of inertia about center of mass. This measures how much force is needed to rotate the body about the center of mass. Note that this is the number set via setMomentAboutCM multiplied by the mass of the body.
moment of inertia about center of mass
Returns the linear and angular momentum of this body. Angular momentum about a fixed point in space is defined as
I_cm vw k + r x m v_cm
where:
I_cm = moment about center of mass
vw = angular velocity
k = unit z vector,
r = vector from a fixed point to the center of mass (cm)
m = mass
v_cm = velocity of center of mass
cross product in the plane is (ax,ay,0) x (bx,by,0) = k(ax by - ay bx)
so we get
I_cm w + m (rx vy - ry vx)
take the fixed point to be the origin (0,0)
, so (rx,ry)
is center of mass.
the momentum of this body as array containing horizontal, vertical and angular momentum in that order.
Whether this SimObject has the given name, adjusting for transformation to the language-independent form of the name, as is done by Util.toName.
the English or language-independent version of the name
whether this SimObject has the given name (adjusted to language-independent form)
Whether this RigidBody cannot collide with an Edge or Vertex of another RigidBody.
Returns true
when passing null
for the Edge.
an Edge of another body, or null
true if this body cannot collide with the given Edge;
returns true if edge
is null.
Returns true if the given body coords point is probably inside this polygon.
WARNING* For debugging only. Does not work for complex (non-convex) shapes.
the point in body coords
true if the given body coords point is probably inside this polygon
Removes from set of RigidBodys that do not collide with this body.
array of RigidBodys that should be collided with
Rotates a body coordinates vector to its orientation in world coordinates. The vector goes from the origin (0, 0), to the given point in body coordinates. The vector is rotated about the origin by the current angle of this body.
the vector, in body coordinates
the rotated vector in world coordinates.
Rotates a world coordinates vector to its orientation in body coordinates, the
inverse of rotateBodyToWorld method.
The vector goes from the origin (0, 0)
, to the given point in world coordinates. The
vector is rotated about the origin by the opposite of the current angle of this body.
the the vector to be rotated, in world coordinates
the rotated vector in body coordinates.
Makes an internal copy of the geometry of this RigidBody, which is used for future collision checking. This copy is a record of the last location of this object, so that collision checking can determine how the object moved over the last time step. For example, a small object moving at high velocity can pass through a narrow object in a single time step; there is then no interpenetration of the two objects, but if you use the previous position of the small fast object you can see that it has passed through the narrow object. See getOldCoords, eraseOldCoords.
Sets the collision distance accuracy, a fraction between zero and one; when the
collision distance is within accuracy * targetGap
of the target gap distance, then
the collision is considered close enough to handle (apply an impulse).
how close in distance to be in order to handle a collision
if value is out of the range 0 to 1, or is exactly zero
Sets the angle in radians of counter-clockwise rotation of this object around its
center of mass. Angle zero draws the object in the same orientation as in body
coordinates. Angle Math.PI/2
rotates the body clockwise 90 degrees from its
body coordinates orientation.
the angle in radians to rotate this object counter-clockwise about its center of mass from 'body coordinates' orientation
Sets location of center of mass, in body coordinates.
the position of the center of mass, in body coordinates.
Sets the center of the circle to use for proximity testing and also calculates the
radius of the circle. A circle centered at this centroid with radius
getCentroidRadius()
should encompass this Polygon.
the center of the circle to use for proximity testing in world coords, in body coordinates
this Polygon, for chaining setters
when setCentroid
is called while the Polygon is 'open' in process of
adding edges, before the Polygon is closed with finish()
method
Sets the locations where a mouse can drag this object, in body coordinates.
the locations where a mouse can drag this object, in body coordinates
Sets the elasticity used when calculating collisions; a value of 1.0 means perfect elasticity where the kinetic energy after collision is the same as before (extremely bouncy), while a value of 0 means no elasticity (no bounce). A collision uses the lesser elasticity value of the two bodies involved.
elasticity used when calculating collisions, a number from 0 to 1.
Sets the expiration time, when this SimObject should be removed from the SimList. This is intended for temporary SimObjects that illustrate, for example, contact forces or collisions.
the expiration time, in time frame of the Simulation clock
Set the mass of this MassObject.
Note that when setting the mass on a MassObject you should also set accordingly the moment of inertia about center of mass, see setMomentAboutCM.
the mass of this MassObject
Sets the moment of inertia about the center of mass for this body divided by the
mass of this body. The moment of inertia, Icm
, measures how much force is needed to
rotate the body about the center of mass. Icm
depends on the shape of the object and
how mass is distributed. For a thin rectangular plate:
Icm = mass * (width^2 + height^2) / 12
For a thin circular plate:
Icm = mass * radius^2 / 2
Note that momentAboutCM returns the number specified here multiplied by the mass of the body.
the moment of inertia about the center of mass for this body divided by the mass of this body
Specifies that this Polygon does not collide with the given set of Edges of other Polygons; replaces any existing non-collide EdgeSet. No collisions or contacts are generated between this Polygon and the Edges in the given EdgeSet. Use this when some parts of a Polygon DO interact. If NO parts interact then see RigidBody.addNonCollide.
the set of other body edges to not collide with
Moves this body so that the center of mass is at the given world coordinates location; rotates this body counter-clockwise about center of mass from 'body coordinates' orientation by the given angle in radians.
the location in world coordinates
Optional
angle: numberthe angle in radians to rotate this body counter-clockwise from 'body coordinates' orientation; if undefined then angle is not changed
Sets which Edge takes priority for collision handling, as in a wall object. Can only be called on a rectangular Polygon. Sets the centroid radius of the non-special edges on this Polygon to zero, which makes all those non-special edges inoperative for collision detection purposes. See Special Edge for Proximity Testing. See getSpecialNormalWorld.
the index of the Edge that takes priority for collision handling, within the Polygon's list of edges
the radius of the circle to use for proximity testing.
if this is not a rectangular Polygon, or the edgeIndex
is not in range
Sets the index into the VarsList for this RigidBody's first variable (the x-position). The VarsList contains 6 variables for each RigidBody,
0. x-position,
1. x-velocity,
2. y-position,
3. y-velocity,
4. angle,
5. angular velocity
For more understandable code, you can use the enum RB instead of these index numbers.
the index of the x-position in the VarsList for this RigidBody;
or -1
if this RigidBody is not in the VarsList.
Set the linear velocity of this objects's center of mass, and (optional) angular velocity of rotation about the objects's center of mass.
the velocity in world coordinates/second
Optional
angular_velocity: numberthe angular velocity, in radians/second, with positive meaning counter-clockwise rotation about the body's center of mass; if undefined, then angular velocity is not changed
Sets the vertical coordinate where the body has zero potential gravitational energy under standard constant gravity when the body's center of mass is at this vertical coordinate.
Optional
height: numberthe vertical world coordinate where this body has zero
potential energy; NaN
means to use default level;
undefined
means use the body's current vertical location is used
Returns true if the given SimObject is similar to this SimObject for display purposes. SimObjects are similar when they are the same type and nearly the same size and location. Mainly used when showing forces - to avoid adding too many objects to the display. See SimList.getSimilar.
the SimObject to compare to
Optional
_opt_tolerance: numberthe amount the object components can differ by
true if this SimObject is similar to obj
for display purposes
Returns a minimal string representation of this object, usually giving just identity information like the class name and name of the object.
For an object whose main purpose is to represent another Printable object, it is
recommended to include the result of calling toStringShort
on that other object.
For example, calling toStringShort()
on a DisplayShape might return something like
this:
DisplayShape{polygon:Polygon{'chain3'}}
a minimal string representation of this object.
Returns the body coordinates of the given world coordinates point, based on current position of this object.
the point, in world coordinates
the point in body coordinates
Generated using TypeDoc
A RigidBody made of connected Edges and Vertexes.
See 2D Physics Engine Overview about the rigid body physics engine.
Body Coordinates
For explanation of body vs. world coordinates see Body Coordinates, MassObject and CoordType.
Methods that return a location often have names ending with either 'body' or 'world' to indicate the coordinate system. Similarly, parameters of methods often end with 'body' or 'world'.
Structure of a Polygon
A Polygon consists of a set of connected Edges, which together form one or more paths. A Polygon can have more than one path, for example a donut shape would have 2 paths: one for the outer Edge and one for the inner Edge.
A path in a Polygon consists of a linked list of Edges and Vertexes:
An Edge has a starting and ending Vertex, and a Vertex has a previous and next Edge. So we can follow a path from the starting Vertex until returning again to the starting Vertex when the path is then closed.
The list of paths is simply a list of starting Vertexes. Each path wraps around to its starting Vertex to form a closed loop. A path must have at least one Vertex and one Edge.
A path is used when drawing the Polygon. For collision handling, the collection of Edges and Vertexes are what matters, how they are linked into a path is irrelevant.
The Edges in a Polygon are stored in an array, and Edges can be referred to by their index in this array, see RigidBody.getEdges and Edge.getIndex.
The list of Vertexes may include automatically generated 'mid-point Vertexes' for curved Edges. These Vertexes are added to give better collision detection for curved Edges. See Vertex about end-point vs. mid-point Vertexes.
Creating a Polygon
First create a Polygon with the constructor; it has no Vertexes or Edges.
Call startPath to begin making a path. You can start with a single Vertex or an Edge.
Use addEdge as many times as desired to add Edges. Or use the shortcut methods addStraightEdge, addCircularEdge or addCircularEdge2.
(optional) Use closePath if you want to add another path with
startPath
.Call finish which will close the current path and calculate the centroid for the Polygon.
Note that just creating an Edge can add it to the existing linked list of Vertexes and Edges being formed in the currently open path. The addEdge method completes the process of adding the Edge to the Polygon.
For examples of creating a Polygon see Shapes.
Centroids & Proximity Testing
We need a quick way to know if objects are close enough to warrant the more expensive tests that are done to find collisions and contacts. To this end, we find the smallest circle that encloses the object. The center of this circle is the 'centroid' or geometric center of the object. The radius is the "centroid radius".
There is a similar centroid and centroid radius for each Edge, which gives the smallest circle that encloses that Edge.
Some of the proximity tests can be found in UtilCollision.checkVertexes. Of note is that we expand the centroid radius by the distance that the Vertex has travelled during the current time step. And that we use the distance squared in these tests, to avoid the computational cost of the square root function.
Special Edge for Proximity Testing
Walls are a special case for proximity testing. Because they are typically long and thin, their proximity circle is huge compared to the wall object; and so the proximity test fires many false positives.
To remedy this, we allow specifying a 'special edge' via setSpecialEdge which changes how the proximity testing is done for this object.
When there is a special edge (there can only be one per object), then the proximity test still looks at the distance between the centroid of each object, but now only the portion of that distance that is normal to the special edge. Also, a special centroid radius is defined for the object that is used in this proximity test. For a wall, this special centroid radius is half of the (short) width of the wall object.
Only the special edge is tested for collisions, so care should be taken to avoid objects being able to collide into any of the non-special edge walls.
Old Coords Is Used For Collision Detection
A Polygon keeps a copy of its local coordinate system before the last time step of the differential equation solver. The copy is used for collision detection, to determine how a collision may have happened; for example whether a Vertex crossed over an Edge during the last time step. See saveOldCoords, getOldCoords, and eraseOldCoords.
Minimum Height
The minimum height of a Polygon is used for potential energy calculations, see getMinHeight.
The minimum height can be explicitly set for each Polygon, see setMinHeight. If it is not set, the method getMinHeight will try to determine the minumum height by calculating the smallest distance between the center of mass and the body's Edges.
Some cautions about
getMinHeight
:The
getMinHeight
calculation can fail for more complicated shapes or when the center of mass is outside of the body.The
getMinHeight
calculation will be incorrect for a circle or oval when the center of mass is not on one of the axes of the circle/ellipse.The minimum height is cached, and should be recalculated if the center of mass changes. To do so, call
setMinHeight(NaN)
and the next timegetMinHeight
is called it will recalculate.TO DO Each collision or contact is being calculated twice. Each body is calculating all its collisions/contacts, so redundant combinations are being done. (Though some bodies don't capture all of their possible collisions/contacts: block only looks for corner contacts, not edges.)
TO DO momentAboutCM: unclear whether this is correctly calculated. Moment calculation is wrong when center of mass is offset; there's a formula for that. momentAboutCM is wrong, unless it is a rectangle object.
TO DO in addCollision(): nearness is hard coded at 0.1. Instead, base it on length of the edges.
TO DO minHeight is complicated, because not well defined. For examples: donut; concave oval Edge on rectangle; these are not easy to figure out.