public double GetSquared() { if (DistanceSquared >= 0) { return(DistanceSquared); } // Work in the box's coordinate system. Vector2d diff = point - box.Center; // Compute squared distance and closest point on box. double sqrDistance = (double)0; double delta; Vector2d closest = Vector2d.Zero; int i; for (i = 0; i < 2; ++i) { closest[i] = diff.Dot(box.Axis(i)); if (closest[i] < -box.Extent[i]) { delta = closest[i] + box.Extent[i]; sqrDistance += delta * delta; closest[i] = -box.Extent[i]; } else if (closest[i] > box.Extent[i]) { delta = closest[i] - box.Extent[i]; sqrDistance += delta * delta; closest[i] = box.Extent[i]; } } BoxClosest = box.Center; for (i = 0; i < 2; ++i) { BoxClosest += closest[i] * box.Axis(i); } DistanceSquared = sqrDistance; return(sqrDistance); }
// 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); }