Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        // 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);
        }