// I think this can be more efficient...no? At least could combine // all the axis-interval updates before updating Center... public void Contain(Box2d o) { Vector2d[] v = o.ComputeVertices(); for (int k = 0; k < 4; ++k) { Contain(v[k]); } }
// ported from WildMagic5 Wm5ContBox2.cpp::MergeBoxes public static Box2d Merge(ref Box2d box0, ref Box2d box1) { // Construct a box that contains the input boxes. Box2d box = new Box2d(); // The first guess at the box center. This value will be updated later // after the input box vertices are projected onto axes determined by an // average of box axes. box.Center = 0.5 * (box0.Center + box1.Center); // The merged box axes are the averages of the input box axes. The // axes of the second box are negated, if necessary, so they form acute // angles with the axes of the first box. if (box0.AxisX.Dot(box1.AxisX) >= 0) { box.AxisX = (0.5) * (box0.AxisX + box1.AxisX); box.AxisX.Normalize(); } else { box.AxisX = (0.5) * (box0.AxisX - box1.AxisX); box.AxisX.Normalize(); } box.AxisY = -box.AxisX.Perp; // Project the input box vertices onto the merged-box axes. Each axis // D[i] containing the current center C has a minimum projected value // min[i] and a maximum projected value max[i]. The corresponding end // points on the axes are C+min[i]*D[i] and C+max[i]*D[i]. The point C // is not necessarily the midpoint for any of the intervals. The actual // box center will be adjusted from C to a point C' that is the midpoint // of each interval, // C' = C + sum_{i=0}^1 0.5*(min[i]+max[i])*D[i] // The box extents are // e[i] = 0.5*(max[i]-min[i]) int i, j; double dot; Vector2d diff = new Vector2d(); Vector2d pmin = Vector2d.Zero; Vector2d pmax = Vector2d.Zero; Vector2dTuple4 vertex = new Vector2dTuple4(); box0.ComputeVertices(ref vertex); for (i = 0; i < 4; ++i) { diff = vertex[i] - box.Center; for (j = 0; j < 2; ++j) { dot = diff.Dot(box.Axis(j)); if (dot > pmax[j]) { pmax[j] = dot; } else if (dot < pmin[j]) { pmin[j] = dot; } } } box1.ComputeVertices(ref vertex); for (i = 0; i < 4; ++i) { diff = vertex[i] - box.Center; for (j = 0; j < 2; ++j) { dot = diff.Dot(box.Axis(j)); if (dot > pmax[j]) { pmax[j] = dot; } else if (dot < pmin[j]) { pmin[j] = dot; } } } // [min,max] is the axis-aligned box in the coordinate system of the // merged box axes. Update the current box center to be the center of // the new box. Compute the extents based on the new center. box.Extent[0] = 0.5 * (pmax[0] - pmin[0]); box.Extent[1] = 0.5 * (pmax[1] - pmin[1]); box.Center += box.AxisX * (0.5 * (pmax[0] + pmin[0])); box.Center += box.AxisY * (0.5 * (pmax[1] + pmin[1])); return(box); }
// build tree of boxes as sequential array void build_sequential(Polygon2d poly) { int NV = poly.VertexCount; int N = NV; int boxCount = 0; layers = 0; layer_counts = new List <int>(); // count how many boxes in each layer, building up from initial segments int bi = 0; while (N > 1) { int layer_boxes = (N / 2) + (N % 2 == 0 ? 0 : 1); boxCount += layer_boxes; N = layer_boxes; layer_counts.Add(layer_boxes); bi += layer_boxes; layers++; } boxes = new Box2d[boxCount]; bi = 0; // make first layer for (int si = 0; si < NV; si += 2) { Vector2d v1 = poly[(si + 1) % NV]; Segment2d seg1 = new Segment2d(poly[si], v1); Box2d box = new Box2d(seg1); if (si < NV - 1) { Segment2d seg2 = new Segment2d(v1, poly[(si + 2) % NV]); Box2d box2 = new Box2d(seg2); box = Box2d.Merge(ref box, ref box2); } boxes[bi++] = box; } // repeatedly build layers until we hit a single box N = bi; int prev_layer_start = 0; bool done = false; while (done == false) { int layer_start = bi; for (int k = 0; k < N; k += 2) { Box2d mbox = Box2d.Merge(ref boxes[prev_layer_start + k], ref boxes[prev_layer_start + k + 1]); boxes[bi++] = mbox; } N = (N / 2) + (N % 2 == 0 ? 0 : 1); prev_layer_start = layer_start; if (N == 1) { done = true; } } }
public DistPoint2Box2(Vector2d PointIn, Box2d boxIn) { point = PointIn; box = boxIn; }