// http://www.geometrictools.com/Documentation/MinimumAreaRectangle.pdf public static void ComputeOBB(out OBB obb, Vec2[] vs, int count) { obb = new OBB(); Box2DXDebug.Assert(count <= Settings.MaxPolygonVertices); Vec2[] p = new Vec2[Settings.MaxPolygonVertices + 1]; for (int i = 0; i < count; ++i) { p[i] = vs[i]; } p[count] = p[0]; float minArea = Common.Settings.FLT_MAX; for (int i = 1; i <= count; ++i) { Vec2 root = p[i - 1]; Vec2 ux = p[i] - root; float length = ux.Normalize(); Box2DXDebug.Assert(length > Common.Settings.FLT_EPSILON); Vec2 uy = new Vec2(-ux.Y, ux.X); Vec2 lower = new Vec2(Common.Settings.FLT_MAX, Common.Settings.FLT_MAX); Vec2 upper = new Vec2(-Common.Settings.FLT_MAX, -Common.Settings.FLT_MAX); for (int j = 0; j < count; ++j) { Vec2 d = p[j] - root; Vec2 r = new Vec2(); r.X = Vec2.Dot(ux, d); r.Y = Vec2.Dot(uy, d); lower = Common.Math.Min(lower, r); upper = Common.Math.Max(upper, r); } float area = (upper.X - lower.X) * (upper.Y - lower.Y); if (area < 0.95f * minArea) { minArea = area; obb.R.Col1 = ux; obb.R.Col2 = uy; Vec2 center = 0.5f * (lower + upper); obb.Center = root + Common.Math.Mul(obb.R, center); obb.Extents = 0.5f * (upper - lower); } } Box2DXDebug.Assert(minArea < Common.Settings.FLT_MAX); }
public static void ComputeOBB(out OBB obb, Vec2[] vs, int count) { obb = default(OBB); Box2DXDebug.Assert(count <= Settings.MaxPolygonVertices); Vec2[] array = new Vec2[Settings.MaxPolygonVertices + 1]; for (int i = 0; i < count; i++) { array[i] = vs[i]; } array[count] = array[0]; float num = Settings.FLT_MAX; for (int i = 1; i <= count; i++) { Vec2 vec = array[i - 1]; Vec2 vec2 = array[i] - vec; float num2 = vec2.Normalize(); Box2DXDebug.Assert(num2 > Settings.FLT_EPSILON); Vec2 vec3 = new Vec2(-vec2.Y, vec2.X); Vec2 vec4 = new Vec2(Settings.FLT_MAX, Settings.FLT_MAX); Vec2 vec5 = new Vec2(-Settings.FLT_MAX, -Settings.FLT_MAX); for (int j = 0; j < count; j++) { Vec2 b = array[j] - vec; Vec2 b2 = default(Vec2); b2.X = Vec2.Dot(vec2, b); b2.Y = Vec2.Dot(vec3, b); vec4 = Box2DX.Common.Math.Min(vec4, b2); vec5 = Box2DX.Common.Math.Max(vec5, b2); } float num3 = (vec5.X - vec4.X) * (vec5.Y - vec4.Y); if (num3 < 0.95f * num) { num = num3; obb.R.Col1 = vec2; obb.R.Col2 = vec3; Vec2 v = 0.5f * (vec4 + vec5); obb.Center = vec + Box2DX.Common.Math.Mul(obb.R, v); obb.Extents = 0.5f * (vec5 - vec4); } } Box2DXDebug.Assert(num < Settings.FLT_MAX); }