private bool IsCircleColliding( CircleParticle p )
        {
            p.GetCardXProjection();
            double depthX = TestIntervals( p.BMin, p.BMax, minX, maxX );
            if ( depthX == 0 ) return false;

            p.GetCardYProjection();
            double depthY = TestIntervals( p.BMin, p.BMax, minY, maxY );
            if ( depthY == 0 ) return false;

            // determine if the circle's center is in a vertex voronoi region
            bool isInVertexX = Math.Abs( depthX ) < p.Radius;
            bool isInVertexY = Math.Abs( depthY ) < p.Radius;

            if ( isInVertexX && isInVertexY )
            {
                // get the closest vertex
                double vx = center.X + Sign( p.Curr.X - center.X ) * ( rectWidth / 2 );
                double vy = center.Y + Sign( p.Curr.Y - center.Y ) * ( rectHeight / 2 );

                // get the distance from the vertex to circle center
                double dx = p.Curr.X - vx;
                double dy = p.Curr.Y - vy;
                double mag = Math.Sqrt( dx * dx + dy * dy );
                double pen = p.Radius - mag;

                // if there is a collision in one of the vertex regions
                if ( pen > 0 )
                {
                    dx /= mag;
                    dy /= mag;
                    p.MTD.Set( dx * pen, dy * pen );
                    normal.Set( dx, dy );
                    return true;
                }
                return false;
            }
            else
            {
                // collision on one of the 4 edges
                p.SetXYMTD( depthX, depthY );
                normal.Set( p.MTD.X / Math.Abs( depthX ), p.MTD.Y / Math.Abs( depthY ) );
                return true;
            }
        }
 public void ResolveCircleCollision( CircleParticle p, Engine engine )
 {
     if ( IsCircleColliding( p ) )
     {
         OnContact();
         p.OnContact();
         p.ResolveCollision( normal, engine );
     }
 }
Beispiel #3
0
        private bool IsCircleColliding( CircleParticle p )
        {
            // find the closest point on the surface to the CircleParticle
            p.ClosestPoint = FindClosestPoint( p.Curr );

            // get the normal of the circle relative to the location of the closest point
            Vector circleNormal = p.ClosestPoint.MinusNew( p.Curr );
            circleNormal.Normalize();

            // if the center of the circle has broken the line keep the normal from 'flipping'
            // to the opposite direction. for small circles, this prevents break-throughs
            if ( Inequality( p.Curr ) )
            {
                double absCX = Math.Abs( circleNormal.X );
                circleNormal.X = ( faceNormal.X < 0 ) ? absCX : -absCX;
                circleNormal.Y = Math.Abs( circleNormal.Y );
            }

            // get contact point on edge of circle
            Vector contactPoint = p.Curr.PlusNew( circleNormal.Mult( p.Radius ) );

            if ( SegmentInequality( contactPoint ) )
            {
                if ( contactPoint.Distance( p.ClosestPoint ) > collisionDepth ) return false;

                double dx = contactPoint.X - p.ClosestPoint.X;
                double dy = contactPoint.Y - p.ClosestPoint.Y;
                p.MTD.Set( -dx, -dy );
                return true;
            }

            return false;
        }
Beispiel #4
0
 public virtual void ResolveCircleCollision( CircleParticle p, Engine engine, ref CollisionState state )
 {
 }
Beispiel #5
0
        protected void Create(double x, double y)
        {
            // create the bicycle
            double leftX = x - 18;
            double rightX = x + 18;
            double widthX = rightX - leftX;
            double midX = leftX + (widthX / 2);
            double topY = y + 0;

            // wheels
            wheelA = new Wheel(leftX, topY, 12);
            Add(wheelA, "wheelA");

            wheelB = new Wheel(rightX, topY, 12);
            Add(wheelB, "wheelB");

            // body
            PhysicsObject[] objs;
            SpringBox rectA = new SpringBox(midX, topY, widthX, 15, out objs);
            foreach (PhysicsObject o in objs)
            {
                Add(o);
            }

            // wheel struts
            SpringConstraint conn1 = new SpringConstraint(wheelA, rectA.P3);
            Add(conn1);

            SpringConstraint conn2 = new SpringConstraint(wheelB, rectA.P2);
            Add(conn2);

            SpringConstraint conn1a = new SpringConstraint(wheelA, rectA.P0);
            Add(conn1a);

            SpringConstraint conn2a = new SpringConstraint(wheelB, rectA.P1);
            Add(conn2a);

            // triangle top of car
            personHead = new CircleParticle(midX, topY - 30, 5);
            Add(personHead);

            personHead.Contact += delegate(object sender, EventArgs e)
            {
                Kill();
            };

            sHeadToWheelA = new SpringConstraint(personHead, wheelA);
            Add(sHeadToWheelA);

            sHeadToWheelB = new SpringConstraint(personHead, wheelB);
            Add(sHeadToWheelB);

            // angular constraint for triangle top
            sBikeAngular = new AngularConstraint(wheelA, personHead, wheelB);
            Add(sBikeAngular);

            angDefault = sBikeAngular.TargetTheta;

            personBody = new CircleParticle(midX - 5, topY - 20, 5);
            personLegs = new CircleParticle(midX, topY - 5, 5);
            aPose = new AngularConstraint(personHead, personBody, personLegs);

            sHeadToBody = new SpringConstraint(personHead, personBody);
            sHeadToBody.RestLength = 12;
            Add(sHeadToBody);
            sBodyToLegs = new SpringConstraint(personBody, personLegs);
            sBodyToLegs.RestLength = 12;
            Add(sBodyToLegs);

            Add(personBody);
            Add(personLegs);

            sLegsToWheelB = new SpringConstraint(personLegs, wheelB);
            sLegsToWheelB.RestLength = 20;
            Add(sLegsToWheelB);

            sLegsToWheelA = new SpringConstraint(personLegs, wheelA);
            sLegsToWheelA.RestLength = 20;
            Add(sLegsToWheelA);
        }
Beispiel #6
0
        private bool IsCircleColliding( CircleParticle p )
        {
            p.GetCardXProjection();
            double depthX = TestIntervals( p.BMin, p.BMax, minX, maxX );
            if ( depthX == 0 ) return false;

            p.GetCardYProjection();
            double depthY = TestIntervals( p.BMin, p.BMax, minY, maxY );
            if ( depthY == 0 ) return false;

            double dx = center.X - p.Curr.X;
            double dy = center.Y - p.Curr.Y;
            double len = Math.Sqrt( dx * dx + dy * dy );
            double pen = ( p.Radius + radius ) - len;

            if ( pen > 0 )
            {
                dx /= len;
                dy /= len;
                p.MTD.Set( -dx * pen, -dy * pen );
                normal.Set( -dx, -dy );
                return true;
            }

            return false;
        }
Beispiel #7
0
        public override void ResolveCircleCollision( CircleParticle p, Engine engine, ref CollisionState state )
        {
            if ( Collision.IsEllipseCollision( curr, Size, 0, p.curr, p.Size, 0, out state ) )
            {
                Vector normal = state.Depth.Clone().Normalize();

                Vector vel1 = curr.MinusNew( prev );
                Vector vel2 = p.curr.MinusNew( p.prev );

                p.prev = p.curr.PlusNew( state.Depth );
                prev = curr.MinusNew( state.Depth );
            }
        }