Box2DX.Collision.PolygonShape.ComputeSubmergedArea C# (CSharp) Метод

ComputeSubmergedArea() публичный Метод

public ComputeSubmergedArea ( Vec2 normal, float offset, XForm xf, Vec2 &c ) : float
normal Box2DX.Common.Vec2
offset float
xf Box2DX.Common.XForm
c Box2DX.Common.Vec2
Результат float
		public override float ComputeSubmergedArea(Vec2 normal, float offset, XForm xf, out Vec2 c)
		{
			//Transform plane into shape co-ordinates
			Vec2 normalL = Box2DX.Common.Math.MulT(xf.R, normal);
			float offsetL = offset - Vec2.Dot(normal, xf.Position);

			float[] depths = new float[Box2DX.Common.Settings.MaxPolygonVertices];
			int diveCount = 0;
			int intoIndex = -1;
			int outoIndex = -1;

			bool lastSubmerged = false;
			int i;
			for (i = 0; i < _vertexCount; i++)
			{
				depths[i] = Vec2.Dot(normalL, _vertices[i]) - offsetL;
				bool isSubmerged = depths[i] < -Box2DX.Common.Settings.FLT_EPSILON;
				if (i > 0)
				{
					if (isSubmerged)
					{
						if (!lastSubmerged)
						{
							intoIndex = i - 1;
							diveCount++;
						}
					}
					else
					{
						if (lastSubmerged)
						{
							outoIndex = i - 1;
							diveCount++;
						}
					}
				}
				lastSubmerged = isSubmerged;
			}
			switch (diveCount)
			{
				case 0:
					if (lastSubmerged)
					{
						//Completely submerged
						MassData md;
						ComputeMass(out md);
						c = Box2DX.Common.Math.Mul(xf, md.Center);
						return md.Mass / _density;
					}
					else
					{
						//Completely dry
						c = new Vec2();
						return 0;
					}
					break;
				case 1:
					if (intoIndex == -1)
					{
						intoIndex = _vertexCount - 1;
					}
					else
					{
						outoIndex = _vertexCount - 1;
					}
					break;
			}
			int intoIndex2 = (intoIndex + 1) % _vertexCount;
			int outoIndex2 = (outoIndex + 1) % _vertexCount;

			float intoLambda = (0 - depths[intoIndex]) / (depths[intoIndex2] - depths[intoIndex]);
			float outoLambda = (0 - depths[outoIndex]) / (depths[outoIndex2] - depths[outoIndex]);

			Vec2 intoVec = new Vec2(_vertices[intoIndex].X * (1 - intoLambda) + _vertices[intoIndex2].X * intoLambda,
							_vertices[intoIndex].Y * (1 - intoLambda) + _vertices[intoIndex2].Y * intoLambda);
			Vec2 outoVec = new Vec2(_vertices[outoIndex].X * (1 - outoLambda) + _vertices[outoIndex2].X * outoLambda,
							_vertices[outoIndex].Y * (1 - outoLambda) + _vertices[outoIndex2].Y * outoLambda);

			//Initialize accumulator
			float area = 0;
			Vec2 center = new Vec2(0, 0);
			Vec2 p2 = _vertices[intoIndex2];
			Vec2 p3;

			float k_inv3 = 1.0f / 3.0f;

			//An awkward loop from intoIndex2+1 to outIndex2
			i = intoIndex2;
			while (i != outoIndex2)
			{
				i = (i + 1) % _vertexCount;
				if (i == outoIndex2)
					p3 = outoVec;
				else
					p3 = _vertices[i];
				//Add the triangle formed by intoVec,p2,p3
				{
					Vec2 e1 = p2 - intoVec;
					Vec2 e2 = p3 - intoVec;

					float D = Vec2.Cross(e1, e2);

					float triangleArea = 0.5f * D;

					area += triangleArea;

					// Area weighted centroid
					center += triangleArea * k_inv3 * (intoVec + p2 + p3);

				}
				//
				p2 = p3;
			}

			//Normalize and transform centroid
			center *= 1.0f / area;

			c = Box2DX.Common.Math.Mul(xf, center);

			return area;
		}