// 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); }