Beruflich Dokumente
Kultur Dokumente
package Box2D.Collision.Shapes{
import Box2D.Common.Math.*;
import Box2D.Common.*;
import Box2D.Collision.Shapes.*;
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Common.b2internal;
use namespace b2internal;
/**
* Convex polygon. The vertices must be in CCW order for a right-handed
* coordinate system with the z-axis coming out of the screen.
* @see b2PolygonDef
*/
/**
* Copy vertices. This assumes the vertices define a convex polygon.
* It is assumed that the exterior is the the right of each edge.
*/
public function SetAsArray(vertices:Array, vertexCount:Number = 0):void
{
var v:Vector.<b2Vec2> = new Vector.<b2Vec2>();
for each(var tVec:b2Vec2 in vertices)
{
v.push(tVec);
}
SetAsVector(v, vertexCount);
}
/**
* Copy vertices. This assumes the vertices define a convex polygon.
* It is assumed that the exterior is the the right of each edge.
*/
public function SetAsVector(vertices:Vector.<b2Vec2>, vertexCount:Number =
0):void
{
if (vertexCount == 0)
vertexCount = vertices.length;
Reserve(vertexCount);
var i:int;
// Copy vertices
for (i = 0; i < m_vertexCount; i++)
{
m_vertices[i].SetV(vertices[i]);
}
/**
* Build vertices to represent an axis-aligned box.
* @param hx the half-width.
* @param hy the half-height.
*/
public function SetAsBox(hx:Number, hy:Number) : void
{
m_vertexCount = 4;
Reserve(4);
m_vertices[0].Set(-hx, -hy);
m_vertices[1].Set( hx, -hy);
m_vertices[2].Set( hx, hy);
m_vertices[3].Set(-hx, hy);
m_normals[0].Set(0.0, -1.0);
m_normals[1].Set(1.0, 0.0);
m_normals[2].Set(0.0, 1.0);
m_normals[3].Set(-1.0, 0.0);
m_centroid.SetZero();
}
/**
* Build vertices to represent an oriented box.
* @param hx the half-width.
* @param hy the half-height.
* @param center the center of the box in local coordinates.
* @param angle the rotation of the box in local coordinates.
*/
static private var s_mat:b2Mat22 = new b2Mat22();
public function SetAsOrientedBox(hx:Number, hy:Number, center:b2Vec2 = null,
angle:Number = 0.0) : void
{
m_vertexCount = 4;
Reserve(4);
m_vertices[0].Set(-hx, -hy);
m_vertices[1].Set( hx, -hy);
m_vertices[2].Set( hx, hy);
m_vertices[3].Set(-hx, hy);
m_normals[0].Set(0.0, -1.0);
m_normals[1].Set(1.0, 0.0);
m_normals[2].Set(0.0, 1.0);
m_normals[3].Set(-1.0, 0.0);
m_centroid = center;
/**
* Set this as a single edge.
*/
public function SetAsEdge(v1:b2Vec2, v2:b2Vec2):void
{
m_vertexCount = 2;
Reserve(2);
m_vertices[0].SetV(v1);
m_vertices[1].SetV(v2);
m_centroid.x = 0.5 * (v1.x + v2.x);
m_centroid.y = 0.5 * (v1.y + v2.y);
m_normals[0] = b2Math.CrossVF(b2Math.SubtractVV(v2, v1), 1.0);
m_normals[0].Normalize();
m_normals[1].x = -m_normals[0].x;
m_normals[1].y = -m_normals[0].y;
}
/**
* Set this as a single edge.
*/
static public function AsEdge(v1:b2Vec2, v2:b2Vec2):b2PolygonShape
{
var polygonShape:b2PolygonShape = new b2PolygonShape();
polygonShape.SetAsEdge(v1, v2);
return polygonShape;
}
/**
* @inheritDoc
*/
public override function TestPoint(xf:b2Transform, p:b2Vec2) : Boolean{
var tVec:b2Vec2;
return true;
}
/**
* @inheritDoc
*/
public override function RayCast(output:b2RayCastOutput,
input:b2RayCastInput, transform:b2Transform):Boolean
{
var lower:Number = 0.0;
var upper:Number = input.maxFraction;
var tX:Number;
var tY:Number;
var tMat:b2Mat22;
var tVec:b2Vec2;
// Put the ray into the polygon's frame of reference. (AS3 Port Manual
inlining follows)
//b2Vec2 p1 = b2MulT(transform.R, segment.p1 - transform.position);
tX = input.p1.x - transform.position.x;
tY = input.p1.y - transform.position.y;
tMat = transform.R;
var p1X:Number = (tX * tMat.col1.x + tY * tMat.col1.y);
var p1Y:Number = (tX * tMat.col2.x + tY * tMat.col2.y);
//b2Vec2 p2 = b2MulT(transform.R, segment.p2 - transform.position);
tX = input.p2.x - transform.position.x;
tY = input.p2.y - transform.position.y;
tMat = transform.R;
var p2X:Number = (tX * tMat.col1.x + tY * tMat.col1.y);
var p2Y:Number = (tX * tMat.col2.x + tY * tMat.col2.y);
//b2Vec2 d = p2 - p1;
var dX:Number = p2X - p1X;
var dY:Number = p2Y - p1Y;
var index:int = -1;
if (denominator == 0.0)
{
if (numerator < 0.0)
{
return false;
}
}
else
{
// Note: we want this predicate without division:
// lower < numerator / denominator, where denominator < 0
// Since denominator < 0, we have to flip the inequality:
// lower < numerator / denominator <==> denominator * lower
> numerator.
if (denominator < 0.0 && numerator < lower * denominator)
{
// Increase lower.
// The segment enters this half-space.
lower = numerator / denominator;
index = i;
}
else if (denominator > 0.0 && numerator < upper *
denominator)
{
// Decrease upper.
// The segment exits this half-space.
upper = numerator / denominator;
}
}
if (index >= 0)
{
output.fraction = lower;
//output.normal = b2Mul(transform.R, m_normals[index]);
tMat = transform.R;
tVec = m_normals[index];
output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
return true;
}
return false;
}
/**
* @inheritDoc
*/
public override function ComputeAABB(aabb:b2AABB, xf:b2Transform) : void
{
//var lower:b2Vec2 = b2Math.MulX(xf, m_vertices[0]);
var tMat:b2Mat22 = xf.R;
var tVec:b2Vec2 = m_vertices[0];
var lowerX:Number = xf.position.x + (tMat.col1.x * tVec.x + tMat.col2.x
* tVec.y);
var lowerY:Number = xf.position.y + (tMat.col1.y * tVec.x + tMat.col2.y
* tVec.y);
var upperX:Number = lowerX;
var upperY:Number = lowerY;
/**
* @inheritDoc
*/
public override function ComputeMass(massData:b2MassData, density:Number) :
void{
// Polygon mass, centroid, and inertia.
// Let rho be the polygon density in mass per unit area.
// Then:
// mass = rho * int(dA)
// centroid.x = (1/mass) * rho * int(x * dA)
// centroid.y = (1/mass) * rho * int(y * dA)
// I = rho * int((x*x + y*y) * dA)
//
// We can compute these integrals by summing all the integrals
// for each triangle of the polygon. To evaluate the integral
// for a single triangle, we make a change of variables to
// the (u,v) coordinates of the triangle:
// x = x0 + e1x * u + e2x * v
// y = y0 + e1y * u + e2y * v
// where 0 <= u && 0 <= v && u + v <= 1.
//
// We integrate u from [0,1-v] and then v from [0,1].
// We also need to use the Jacobian of the transformation:
// D = cross(e1, e2)
//
// Simplification: triangle centroid = (1/3) * (p1 + p2 + p3)
//
// The rest of the derivation is handled by computer algebra.
//b2Vec2 e1 = p2 - p1;
var e1X:Number = p2.x - p1X;
var e1Y:Number = p2.y - p1Y;
//b2Vec2 e2 = p3 - p1;
var e2X:Number = p3.x - p1X;
var e2Y:Number = p3.y - p1Y;
I += D * (intx2 + inty2);
}
// Total mass
massData.mass = density * area;
// Center of mass
//b2Settings.b2Assert(area > Number.MIN_VALUE);
//center *= 1.0f / area;
centerX *= 1.0 / area;
centerY *= 1.0 / area;
//massData->center = center;
massData.center.Set(centerX, centerY);
/**
* @inheritDoc
*/
public override function ComputeSubmergedArea(
normal:b2Vec2,
offset:Number,
xf:b2Transform,
c:b2Vec2):Number
{
// Transform plane into shape co-ordinates
var normalL:b2Vec2 = b2Math.MulTMV(xf.R, normal);
var offsetL:Number = offset - b2Math.Dot(normal, xf.position);
// Initialize accumulator
var area:Number = 0;
var center:b2Vec2 = new b2Vec2();
var p2:b2Vec2 = m_vertices[intoIndex2];
var p3:b2Vec2;
p2 = p3;
}
return area;
}
/**
* Get the vertex count.
*/
public function GetVertexCount() : int{
return m_vertexCount;
}
/**
* Get the vertices in local coordinates.
*/
public function GetVertices() : Vector.<b2Vec2>{
return m_vertices;
}
/**
* Get the edge normal vectors. There is one for each vertex.
*/
public function GetNormals() : Vector.<b2Vec2>
{
return m_normals;
}
/**
* Get the supporting vertex index in the given direction.
*/
public function GetSupport(d:b2Vec2):int
{
var bestIndex:int = 0;
var bestValue:Number = m_vertices[0].x * d.x + m_vertices[0].y * d.y;
for (var i:int= 1; i < m_vertexCount; ++i)
{
var value:Number = m_vertices[i].x * d.x + m_vertices[i].y * d.y;
if (value > bestValue)
{
bestIndex = i;
bestValue = value;
}
}
return bestIndex;
}
/**
* @private
*/
public function b2PolygonShape(){
//b2Settings.b2Assert(def.type == e_polygonShape);
m_type = e_polygonShape;
/**
* Computes the centroid of the given polygon
* @param vs vector of b2Vec specifying a polygon
* @param count length of vs
* @return the polygon centroid
*/
static public function ComputeCentroid(vs:Vector.<b2Vec2>, count:uint) :
b2Vec2
{
//b2Settings.b2Assert(count >= 3);
//b2Vec2 e1 = p2 - p1;
var e1X:Number = p2.x - p1X;
var e1Y:Number = p2.y - p1Y;
//b2Vec2 e2 = p3 - p1;
var e2X:Number = p3.x - p1X;
var e2Y:Number = p3.y - p1Y;
// Centroid
//beSettings.b2Assert(area > Number.MIN_VALUE);
//c *= 1.0 / area;
c.x *= 1.0 / area;
c.y *= 1.0 / area;
return c;
}
/**
* Computes a polygon's OBB
* @see http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf
*/
static b2internal function ComputeOBB(obb:b2OBB, vs:Vector.<b2Vec2>,
count:int) : void
{
var i:int;
var p:Vector.<b2Vec2> = new Vector.<b2Vec2>(count + 1);
for (i = 0; i < count; ++i)
{
p[i] = vs[i];
}
p[count] = p[0];
};