Ejemplo n.º 1
0
 public static bool IsPointInCircle(Vector2 point, Vector2 circleCentre, float circleRadius, bool trueOnEdge = true)
 {
     if (trueOnEdge)
     {
         return(Vector2Ext.DistanceBetweenTwoPoints(point, circleCentre) <= circleRadius);
     }
     else
     {
         return(Vector2Ext.DistanceBetweenTwoPoints(point, circleCentre) < circleRadius);
     }
 }
Ejemplo n.º 2
0
        public void UpdateParamaters(Vector2 point0, Vector2 tangent0, Vector2 point1, Vector2 tangent1)
        {
            if (_p0 != null && _p1 != null && _t0 != null && _t1 != null)
            {
                //Only recompute arc if any of the paramaters have changed
                if (Vector2Ext.Equality(_p0, point0) && Vector2Ext.Equality(_t0, tangent0) && Vector2Ext.Equality(_p1, point1) && Vector2Ext.Equality(_t1, tangent1))
                {
                    return;
                }
            }

            SetParams(point0, tangent0, point1, tangent1);
        }
Ejemplo n.º 3
0
        public AABB(Vector2 min, Vector2 max, int unused, bool validate = false) //Dirt!
        {
            if (validate)
            {
                if (Vector2Ext.Equality(min, max))
                {
                    max.X += 1.0f;
                    max.Y += 1.0f;
                }

                if (max.X < min.X)
                {
                    var s = max.X;
                    max.X = min.X;
                    min.X = s;
                }

                if (max.Y < min.Y)
                {
                    var s = max.Y;
                    max.Y = min.Y;
                    min.Y = s;
                }
            }

            Min     = min;
            Max     = max;
            Centre  = 0.5f * (Min + Max);
            Extents = 0.5f * (Max - Min);
            Top     = Max.Y;
            Bottom  = Min.Y;
            Left    = Min.X;
            Right   = Max.X;
            Width   = Right - Left;
            Height  = Top - Bottom;
        }
Ejemplo n.º 4
0
        private void ComputeArcs()
        {
            //Using Approach as detailed in: http://www.ryanjuckett.com/programming/biarc-interpolation/

            _valid = false;

            Arc0 = new Arc();
            Arc1 = new Arc();

            //Need to ensure tangents are normalised. Technique here is to renormalise and then check for if equal zero length (which happens if the normalise fails). Can replace with more robust / direct method later, if this becomes a concern
            _t0 = _t0.Normal();
            _t1 = _t1.Normal();
            if (_t0.LengthSquared() == 0.0f || _t1.LengthSquared() == 0.0f)
            {
                return;
            }

            Vector2 v = _p1 - _p0;

            //If points equal then no interpolation required
            if (Vector2Ext.Equality(v, Vector2.Zero))
            {
                Arc0.Centre    = _p0;
                Arc0.Radius    = 0.0f;
                Arc0.Axis      = v;
                Arc0.Angle     = 0.0f;
                Arc0.ArcLength = 0.0f;

                Arc1.Centre    = _p1;
                Arc1.Radius    = 0.0f;
                Arc1.Axis      = v;
                Arc1.Angle     = 0.0f;
                Arc1.ArcLength = 0.0f;

                _valid = true;
                return;
            }

            float pi = (float)Math.PI;

            float vDotV = Vector2.Dot(v, v);

            //We are using the approach that automatically picks the values of d, where d1 = d2
            //The formula for deriving d2 is a quadratic

            /*
             * d2 = [ -(v.t) +/- sqrt((v.t)^2 + 2.(1 + t1.t2)(v.v)) ] / (2* (1 - t1.t2))
             */
            //Compute denominator of the quadratic formula as it tells us if it is solvable or not (i.e. is it = 0)

            Vector2 t           = _t0 + _t1;
            float   vDotT       = Vector2.Dot(v, t);
            float   t0DotT1     = Vector2.Dot(_t0, _t1);
            float   denominator = 2.0f * (1.0f - t0DotT1);

            float d; //Set for those cases that do not return straight away with solution

            //If quadratic formula denominator is zero. There are 2 cases here. In both cases the tangents are equal. In one the vector between the two curve points are perpendicular to them
            if (denominator == 0.0f)
            {
                float vDotT1 = Vector2.Dot(v, _t1);

                if ((float)Math.Abs(vDotT1) == 0.0f)
                {
                    //Tangents are equal to each other AND perpendicular to p0 and p1. The solution is two equal semi-circles
                    float   vMag     = v.Length();
                    float   radius   = 0.25f * vMag;
                    Vector2 quarterV = 0.25f * v;

                    Vector2 pm = _p0 + (2.0f * quarterV);

                    float vCrossT1 = (v.X * _t1.Y) - (v.Y * _t1.X);

                    Arc0.Centre    = _p0 + quarterV;
                    Arc0.Radius    = radius;
                    Arc0.Axis      = _p0 - Arc0.Centre;
                    Arc0.Angle     = vCrossT1 > 0.0f ? pi : -pi; //Need to check this > or <. standard is < then > but doesn't seem to work...
                    Arc0.ArcLength = pi * radius;

                    Arc1.Centre    = _p0 + (3.0f * quarterV);
                    Arc1.Radius    = radius;
                    Arc1.Axis      = _p1 - Arc1.Centre;
                    Arc1.Angle     = vCrossT1 > 0.0f ? pi : -pi;
                    Arc1.ArcLength = pi * radius;

                    _valid = true;
                    return;
                }
                else
                {
                    //The Tangents are equal to each other (this is the only route through where d can be negative)
                    d = vDotV / (4.0f * vDotT1);
                }
            }
            else
            {
                //Standard result, we use the positive version of the quadratic formula to calculate d
                float discriminant = (vDotT * vDotT) + (denominator * vDotV);
                d = (-vDotT + (float)Math.Sqrt(discriminant)) / denominator;
            }

            //At this stage we have either calculated the value of d (d1 = d2), or we have set the two arcs appropriately for special cases

            //Calculate the mid point
            //pm=p1+p2+d2(t1−t2)/2

            Vector2 mid = 0.5f * (_p0 + _p1 + (d * (_t0 - _t1)));

            //Caclulate Vectors from the curve points to the mid point
            Vector2 p0ToMid = mid - _p0;
            Vector2 p1ToMid = mid - _p1;

            //Calculate Arc Centre, Radius and Angle values
            Arc0 = ComputeSingleArc(_p0, _t0, p0ToMid);
            Arc1 = ComputeSingleArc(_p1, _t1, p1ToMid);


            if (d < 0.0f)
            {
                //Use longer path around if d is negative (doesn't seem to work right yet)

                /*
                 * float arc0mul = 2.0f * pi;
                 * arc0mul *= _arc0.Angle >= 0.0f ? 1.0f : -1.0f;
                 * _arc0.Angle = arc0mul - _arc0.Angle;
                 *
                 * float arc1mul = 2.0f * pi;
                 * arc1mul *= _arc1.Angle >= 0.0f ? 1.0f : -1.0f;
                 * _arc1.Angle = arc1mul - _arc1.Angle;
                 */
            }

            //Ignoring the code to check for negative d in the example, as surely should always be positive (i.e. we are taking the shorter parth around the circles)

            Arc0.Axis = _p0 - Arc0.Centre;
            Arc1.Axis = _p1 - Arc1.Centre;

            Arc0.ArcLength = Arc0.Radius == 0.0f ? p0ToMid.Length() : (float)Math.Abs(Arc0.Radius * Arc0.Angle);
            Arc1.ArcLength = Arc1.Radius == 0.0f ? p1ToMid.Length() : (float)Math.Abs(Arc1.Radius * Arc1.Angle);

            _valid = true;
        }
Ejemplo n.º 5
0
        public static LineIntersectionResult RobustLineIntersectAndResult(Vector2 a0, Vector2 a1, Vector2 b0, Vector2 b1, bool fireOnOverlap = true)
        {
            //Fail on zero length lines
            if (Vector2Ext.Equality(a0, a1) || Vector2Ext.Equality(b0, b1))
            {
                return new LineIntersectionResult()
                       {
                           Intersecting   = false,
                           CoLinear       = false,
                           IntersectPoint = Vector2.Zero
                       }
            }
            ;

            var   r     = a1 - a0;
            var   s     = b1 - b0;
            var   qMp   = b0 - a0;
            float rXs   = Vector2Ext.Cross(r, s);
            float qMpXr = Vector2Ext.Cross(qMp, r);

            //1. Colinear Check
            if (IsFuzzyZero(rXs) && IsFuzzyZero(qMpXr))
            {
                //They are colinear
                if (fireOnOverlap)
                {
                    float qMpDOTr = Vector2Ext.Dot(qMp, r);
                    float rDOTr   = Vector2Ext.Dot(r, r);
                    var   pMq     = a0 - b0;
                    float pMqDOTs = Vector2Ext.Dot(pMq, s);
                    float sDOTs   = Vector2Ext.Dot(s, s);
                    if ((qMpDOTr >= 0.0f && qMpDOTr <= rDOTr) || (pMqDOTs >= 0.0f && pMqDOTs <= sDOTs))
                    {
                        //You do not get provided a valid intersect point as the lines lie on top of each other
                        return(new LineIntersectionResult()
                        {
                            Intersecting = true,
                            CoLinear = true,
                            IntersectPoint = Vector2.Zero
                        });
                    }
                }
                //Not classifying overlap as intersection
                return(new LineIntersectionResult()
                {
                    Intersecting = false,
                    CoLinear = true,
                    IntersectPoint = Vector2.Zero
                });
            }

            //2. Paralell - Do not intersect
            if (IsFuzzyZero(rXs) && !IsFuzzyZero(qMpXr))
            {
                return(new LineIntersectionResult()
                {
                    Intersecting = false,
                    CoLinear = false,
                    IntersectPoint = Vector2.Zero
                });
            }

            //3.Intersect at Single Point
            float t = Vector2Ext.Cross(qMp, s) / rXs;
            float u = Vector2Ext.Cross(qMp, r) / rXs;

            if (!IsFuzzyZero(rXs) && t >= 0.0f && t <= 1.0f && u >= 0.0f && u <= 1.0f)
            {
                return(new LineIntersectionResult()
                {
                    Intersecting = true,
                    CoLinear = false,
                    IntersectPoint = a0 + (r * t)
                });
            }

            //4. Do not intersect
            return(new LineIntersectionResult()
            {
                Intersecting = false,
                CoLinear = false,
                IntersectPoint = Vector2.Zero
            });
        }
Ejemplo n.º 6
0
 public static float DotWith(this Vector2 v0, Vector2 v1)
 {
     return(Vector2Ext.Dot(v0, v1));
 }