Exemplo n.º 1
0
            // Hit testing between this thing and a single segment.  If hit, the center point on
            // the segment being hit is returned, along with the spot on the line from 0 to 1 if
            // a line segment was hit.

            public bool Hit(Segment seg, ref Point ptHitCenter, ref double lineHitLocation)
            {
                double minDxSquared = size + seg.radius;
                minDxSquared *= minDxSquared;

                // See if falling thing hit this body segment
                if (seg.IsCircle())
                {
                    if (SquaredDistance(center.X, center.Y, seg.x1, seg.y1) <= minDxSquared)
                    {
                        ptHitCenter.X = seg.x1;
                        ptHitCenter.Y = seg.y1;
                        lineHitLocation = 0;
                        return true;
                    }
                }
                else
                {
                    double sqrLineSize = SquaredDistance(seg.x1, seg.y1, seg.x2, seg.y2);
                    if (sqrLineSize < 0.5)  // if less than 1/2 pixel apart, just check dx to an endpoint
                    {
                        return (SquaredDistance(center.X, center.Y, seg.x1, seg.y1) < minDxSquared) ? true : false;
                    }
                    else
                    {   // Find dx from center to line
                        double u = ((center.X - seg.x1) * (seg.x2 - seg.x1) + (center.Y - seg.y1) * (seg.y2 - seg.y1)) / sqrLineSize;
                        if ((u >= 0) && (u <= 1.0))
                        {   // Tangent within line endpoints, see if we're close enough
                            double xIntersect = seg.x1 + (seg.x2 - seg.x1) * u;
                            double yIntersect = seg.y1 + (seg.y2 - seg.y1) * u;

                            if (SquaredDistance(center.X, center.Y,
                                xIntersect, yIntersect) < minDxSquared)
                            {
                                lineHitLocation = u;
                                ptHitCenter.X = xIntersect;
                                ptHitCenter.Y = yIntersect; ;
                                return true;
                            }
                        }
                        else
                        {
                            // See how close we are to an endpoint
                            if (u < 0)
                            {
                                if (SquaredDistance(center.X, center.Y, seg.x1, seg.y1) < minDxSquared)
                                {
                                    lineHitLocation = 0;
                                    ptHitCenter.X = seg.x1;
                                    ptHitCenter.Y = seg.y1;
                                    return true;
                                }
                            }
                            else
                            {
                                if (SquaredDistance(center.X, center.Y, seg.x2, seg.y2) < minDxSquared)
                                {
                                    lineHitLocation = 1;
                                    ptHitCenter.X = seg.x2;
                                    ptHitCenter.Y = seg.y2;
                                    return true;
                                }
                            }
                        }
                    }
                    return false;
                }
                return false;
            }
Exemplo n.º 2
0
        // Update the segment's position and compute a smoothed velocity for the circle or the
        // endpoints of the segment based on  the time it took it to move from the last position
        // to the current one.  The velocity is in pixels per second.

        public void UpdateSegment(Segment s)
        {
            segLast = seg;
            seg = s;
            
            DateTime cur = DateTime.Now;
            double fMs = cur.Subtract(timeLastUpdated).TotalMilliseconds;
            if (fMs < 10.0)
                fMs = 10.0;
            double fFPS = 1000.0 / fMs;
            timeLastUpdated = cur;

            if (seg.IsCircle())
            {
                xVel = xVel * smoothing + (1.0 - smoothing) * (seg.x1 - segLast.x1) * fFPS;
                yVel = yVel * smoothing + (1.0 - smoothing) * (seg.y1 - segLast.y1) * fFPS;
            }
            else
            {
                xVel = xVel * smoothing + (1.0 - smoothing) * (seg.x1 - segLast.x1) * fFPS;
                yVel = yVel * smoothing + (1.0 - smoothing) * (seg.y1 - segLast.y1) * fFPS;
                xVel2 = xVel2 * smoothing + (1.0 - smoothing) * (seg.x2 - segLast.x2) * fFPS;
                yVel2 = yVel2 * smoothing + (1.0 - smoothing) * (seg.y2 - segLast.y2) * fFPS;
            }
        }
Exemplo n.º 3
0
            // Hit testing between this thing and a single segment.  If hit, the center point on
            // the segment being hit is returned, along with the spot on the line from 0 to 1 if
            // a line segment was hit.
            public bool Hit(Segment seg, ref System.Windows.Point hitCenter, ref double lineHitLocation)
            {
                double minDxSquared = this.Size + seg.Radius;
                minDxSquared *= minDxSquared;

                // See if falling thing hit this body segment
                if (seg.IsCircle())
                {
                    if (SquaredDistance(this.Center.X, this.Center.Y, seg.X1, seg.Y1) <= minDxSquared)
                    {
                        hitCenter.X = seg.X1;
                        hitCenter.Y = seg.Y1;
                        lineHitLocation = 0;
                        return true;
                    }
                }
                else
                {
                    double sqrLineSize = SquaredDistance(seg.X1, seg.Y1, seg.X2, seg.Y2);
                    if (sqrLineSize < 0.5)
                    {
                        // if less than 1/2 pixel apart, just check dx to an endpoint
                        return SquaredDistance(this.Center.X, this.Center.Y, seg.X1, seg.Y1) < minDxSquared;
                    }

                    // Find dx from center to line
                    double u = ((this.Center.X - seg.X1) * (seg.X2 - seg.X1)) + (((this.Center.Y - seg.Y1) * (seg.Y2 - seg.Y1)) / sqrLineSize);
                    if ((u >= 0) && (u <= 1.0))
                    {   // Tangent within line endpoints, see if we're close enough
                        double intersectX = seg.X1 + ((seg.X2 - seg.X1) * u);
                        double intersectY = seg.Y1 + ((seg.Y2 - seg.Y1) * u);

                        if (SquaredDistance(this.Center.X, this.Center.Y, intersectX, intersectY) < minDxSquared)
                        {
                            lineHitLocation = u;
                            hitCenter.X = intersectX;
                            hitCenter.Y = intersectY;
                            return true;
                        }
                    }
                    else
                    {
                        // See how close we are to an endpoint
                        if (u < 0)
                        {
                            if (SquaredDistance(this.Center.X, this.Center.Y, seg.X1, seg.Y1) < minDxSquared)
                            {
                                lineHitLocation = 0;
                                hitCenter.X = seg.X1;
                                hitCenter.Y = seg.Y1;
                                return true;
                            }
                        }
                        else
                        {
                            if (SquaredDistance(this.Center.X, this.Center.Y, seg.X2, seg.Y2) < minDxSquared)
                            {
                                lineHitLocation = 1;
                                hitCenter.X = seg.X2;
                                hitCenter.Y = seg.Y2;
                                return true;
                            }
                        }
                    }

                    return false;
                }

                return false;
            }