Example #1
0
        //HalfEdgeData2
        public HalfEdgeData2 UnNormalize(HalfEdgeData2 data)
        {
            foreach (HalfEdgeVertex2 v in data.vertices)
            {
                MyVector2 vUnNormalized = UnNormalize(v.position);

                v.position = vUnNormalized;
            }

            return(data);
        }
Example #2
0
        //Help method to calculate the average normal of two line segments
        private static MyVector2 GetAverageNormal(MyVector2 a, MyVector2 b, MyVector2 c)
        {
            MyVector2 normal_1 = GetNormal(a, b);
            MyVector2 normal_2 = GetNormal(b, c);

            MyVector2 averageNormal = (normal_1 + normal_2) * 0.5f;

            averageNormal = MyVector2.Normalize(averageNormal);

            return(averageNormal);
        }
        //
        // Does a point p lie to the left, to the right, or on a vector going from a to b
        //
        //https://gamedev.stackexchange.com/questions/71328/how-can-i-add-and-subtract-convex-polygons
        private static float GetPointInRelationToVectorValue(MyVector2 a, MyVector2 b, MyVector2 p)
        {
            float x1 = a.x - p.x;
            float x2 = a.y - p.y;
            float y1 = b.x - p.x;
            float y2 = b.y - p.y;

            float determinant = MathUtility.Det2(x1, x2, y1, y2);

            return(determinant);
        }
        //HalfEdgeData2
        public static HalfEdgeData2 UnNormalize(HalfEdgeData2 data, AABB2 aabb, float dMax)
        {
            foreach (HalfEdgeVertex2 v in data.vertices)
            {
                MyVector2 vUnNormalized = HelpMethods.UnNormalize(v.position, aabb, dMax);

                v.position = vUnNormalized;
            }

            return(data);
        }
        //Smooth the points that are between the corners of a square, to get a smoother mesh
        //They are currently halfway between the corners
        private static void SmoothSquare(Square square)
        {
            MyVector2 R_inter = GetLerpedMidpoint(square.TR.pos, square.TR.value, square.BR.pos, square.BR.value);
            MyVector2 B_inter = GetLerpedMidpoint(square.BR.pos, square.BR.value, square.BL.pos, square.BL.value);
            MyVector2 L_inter = GetLerpedMidpoint(square.BL.pos, square.BL.value, square.TL.pos, square.TL.value);
            MyVector2 T_inter = GetLerpedMidpoint(square.TL.pos, square.TL.value, square.TR.pos, square.TR.value);

            square.R.pos = R_inter;
            square.B.pos = B_inter;
            square.L.pos = L_inter;
            square.T.pos = T_inter;
        }
        //This is a useful method to find the intersection coordinate if we know we are intersecting
        //Is used for ray-plane, line-plane, plane-plane
        private static MyVector2 GetIntersectionCoordinate(MyVector2 planePos, MyVector2 planeNormal, MyVector2 rayStart, MyVector2 rayDir)
        {
            float denominator = MyVector2.Dot(-planeNormal, rayDir);

            MyVector2 vecBetween = planePos - rayStart;

            float t = MyVector2.Dot(vecBetween, -planeNormal) / denominator;

            MyVector2 intersectionPoint = rayStart + rayDir * t;

            return(intersectionPoint);
        }
Example #7
0
        //The angle between two vectors 0 <= angle <= 180
        //Same as Vector2.Angle() but we are using MyVector2
        public static float AngleBetween(MyVector2 from, MyVector2 to)
        {
            //dot(a_normalized, b_normalized) = cos(alpha) -> acos(dot(a_normalized, b_normalized)) = alpha
            float dot = MyVector2.Dot(MyVector2.Normalize(from), MyVector2.Normalize(to));

            //This shouldn't happen but may happen because of floating point precision issues
            dot = Mathf.Clamp(dot, -1f, 1f);

            float angleRad = Mathf.Acos(dot);

            return(angleRad);
        }
Example #8
0
        //
        // Line, plane, ray intersection with plane
        //

        //This is a useful method to find the intersection coordinate if we know we are intersecting
        //Is used for ray-plane, line-plane, plane-plane
        //2d
        private static MyVector2 GetIntersectionCoordinate(Plane2 plane, Ray2 ray)
        {
            float denominator = MyVector2.Dot(-plane.normal, ray.dir);

            MyVector2 vecBetween = plane.pos - ray.origin;

            float t = MyVector2.Dot(vecBetween, -plane.normal) / denominator;

            MyVector2 intersectionPoint = ray.origin + ray.dir * t;

            return(intersectionPoint);
        }
Example #9
0
        //
        // Arrow
        //
        public static HashSet <Triangle2> Arrow(MyVector2 p1, MyVector2 p2, float lineWidth, float arrowSize)
        {
            HashSet <Triangle2> arrowTriangles = new HashSet <Triangle2>();

            //An arrow consists of two parts: the pointy part and the rectangular part

            //First we have to see if we can fit the parts
            MyVector2 lineDir = p2 - p1;

            float lineLength = MyVector2.Magnitude(lineDir);

            if (lineLength < arrowSize)
            {
                Debug.Log("Cant make arrow because line is too short");

                return(null);
            }


            //Make the arrow tip
            MyVector2 lineDirNormalized = MyVector2.Normalize(lineDir);

            MyVector2 arrowBottom = p2 - lineDirNormalized * arrowSize;

            MyVector2 lineNormal = MyVector2.Normalize(new MyVector2(lineDirNormalized.y, -lineDirNormalized.x));

            MyVector2 arrowBottom_R = arrowBottom + lineNormal * arrowSize * 0.5f;
            MyVector2 arrowBottom_L = arrowBottom - lineNormal * arrowSize * 0.5f;

            Triangle2 arrowTipTriangle = new Triangle2(p2, arrowBottom_R, arrowBottom_L);

            arrowTriangles.Add(arrowTipTriangle);


            //Make the arrow rectangle
            float halfWidth = lineWidth * 0.5f;

            MyVector2 p1_T = p1 + lineNormal * halfWidth;
            MyVector2 p1_B = p1 - lineNormal * halfWidth;

            MyVector2 p2_T = arrowBottom + lineNormal * halfWidth;
            MyVector2 p2_B = arrowBottom - lineNormal * halfWidth;

            HashSet <Triangle2> rectangle = LineSegment(p1_T, p1_B, p2_T, p2_B);

            foreach (Triangle2 t in rectangle)
            {
                arrowTriangles.Add(t);
            }

            return(arrowTriangles);
        }
        //
        // Split triangle edge
        //
        //Split an edge at a point on the edge to form four new triangles, while removing two old
        //public static void SplitTriangleEdge(HalfEdge e, Vector3 splitPosition)
        //{

        //}



        //
        // Split triangle face
        //
        //Split a face (which we know is a triangle) at a point to create three new triangles while removing the old triangle
        //Could maybe make it more general so we can split a face, which consists of n edges
        public static void SplitTriangleFaceAtPoint(HalfEdgeFace2 f, MyVector2 splitPosition, HalfEdgeData2 data)
        {
            //The edges that belongs to this face
            HalfEdge2 e_1 = f.edge;
            HalfEdge2 e_2 = e_1.nextEdge;
            HalfEdge2 e_3 = e_2.nextEdge;

            //A list with new edges so we can connect the new edges with an edge on the opposite side
            HashSet <HalfEdge2> newEdges = new HashSet <HalfEdge2>();

            CreateNewFace(e_1, splitPosition, data, newEdges);
            CreateNewFace(e_2, splitPosition, data, newEdges);
            CreateNewFace(e_3, splitPosition, data, newEdges);

            //Debug.Log("New edges " + newEdges.Count);

            //Find the opposite connections
            foreach (HalfEdge2 e in newEdges)
            {
                //If we have already found a opposite
                if (e.oppositeEdge != null)
                {
                    continue;
                }

                MyVector2 eGoingTo   = e.v.position;
                MyVector2 eGoingFrom = e.prevEdge.v.position;

                foreach (HalfEdge2 eOpposite in newEdges)
                {
                    if (e == eOpposite || eOpposite.oppositeEdge != null)
                    {
                        continue;
                    }

                    MyVector2 eGoingTo_Other   = eOpposite.v.position;
                    MyVector2 eGoingFrom_Other = eOpposite.prevEdge.v.position;

                    if (eGoingTo.Equals(eGoingFrom_Other) && eGoingFrom.Equals(eGoingTo_Other))
                    {
                        e.oppositeEdge = eOpposite;
                        //Might as well connect it from the other way as well
                        eOpposite.oppositeEdge = e;

                        //Debug.Log("Found opposite");
                    }
                }
            }

            //Delete the old triangle
            DeleteTriangleFace(f, data, false);
        }
Example #11
0
        //
        // Add the constraints to the delaunay triangulation
        //

        private static HalfEdgeData2 AddConstraints(HalfEdgeData2 triangleData, List <MyVector2> constraints, bool shouldRemoveTriangles)
        {
            //Validate the data
            if (constraints == null)
            {
                return(triangleData);
            }


            //First create a list with all unique edges
            //In the half-edge data structure, we have for each edge an half edge going in each direction,
            //making it unneccessary to loop through all edges for intersection tests
            //The report suggest we should do a triangle walk, but it will not work if the mesh has holes
            List <HalfEdge2> uniqueEdges = triangleData.GetUniqueEdges();


            //The steps numbering is from the report
            //Step 1. Loop over each constrained edge. For each of these edges, do steps 2-4
            for (int i = 0; i < constraints.Count; i++)
            {
                //Let each constrained edge be defined by the vertices:
                MyVector2 c_p1 = constraints[i];
                MyVector2 c_p2 = constraints[MathUtility.ClampListIndex(i + 1, constraints.Count)];

                //Check if this constraint already exists in the triangulation,
                //if so we are happy and dont need to worry about this edge
                if (IsEdgeInListOfEdges(uniqueEdges, c_p1, c_p2))
                {
                    continue;
                }

                //Step 2. Find all edges in the current triangulation that intersects with this constraint
                Queue <HalfEdge2> intersectingEdges = FindIntersectingEdges_BruteForce(uniqueEdges, c_p1, c_p2);

                //Debug.Log("Intersecting edges: " + intersectingEdges.Count);

                //Step 3. Remove intersecting edges by flipping triangles
                List <HalfEdge2> newEdges = RemoveIntersectingEdges(c_p1, c_p2, intersectingEdges);

                //Step 4. Try to restore delaunay triangulation
                //Because we have constraints we will never get a delaunay triangulation
                RestoreDelaunayTriangulation(c_p1, c_p2, newEdges);
            }

            //Step 5. Remove superfluous triangles, such as the triangles "inside" the constraints
            if (shouldRemoveTriangles)
            {
                RemoveSuperfluousTriangles(triangleData, constraints);
            }

            return(triangleData);
        }
        //Insert intersection vertex
        private static ClipVertex InsertIntersectionVertex(MyVector2 a, MyVector2 b, MyVector2 intersectionPoint, ClipVertex currentVertex)
        {
            //Calculate alpha which is how far the intersection coordinate is between a and b
            //so we can insert this vertex at the correct position
            //pos = start + dir * alpha
            float alpha = MyVector2.SqrMagnitude(a - intersectionPoint) / MyVector2.SqrMagnitude(a - b);

            //Debug.Log(alpha);

            //Create a new vertex
            ClipVertex intersectionVertex = new ClipVertex(intersectionPoint);

            intersectionVertex.isIntersection = true;
            intersectionVertex.alpha          = alpha;

            //Now we need to insert this intersection point somewhere after currentVertex
            ClipVertex insertAfterThisVertex = currentVertex;

            int safety = 0;

            while (true)
            {
                //If the next vertex is an intersectionvertex with a higher alpha
                //or if the next vertex is not an intersectionvertex, we cant improve, so break
                if (insertAfterThisVertex.next.alpha > alpha || !insertAfterThisVertex.next.isIntersection)
                {
                    break;
                }

                insertAfterThisVertex = insertAfterThisVertex.next;

                safety += 1;

                if (safety > 100000)
                {
                    Debug.Log("Stuck in loop in insert intersection vertices");

                    break;
                }
            }

            //Connect the vertex to the surrounding vertices
            intersectionVertex.next = insertAfterThisVertex.next;

            intersectionVertex.prev = insertAfterThisVertex;

            insertAfterThisVertex.next.prev = intersectionVertex;

            insertAfterThisVertex.next = intersectionVertex;

            return(intersectionVertex);
        }
        //
        // Calculate the center of circle in 2d space given three coordinates
        //
        //http://paulbourke.net/geometry/circlesphere/
        public static MyVector2 CalculateCircleCenter(MyVector2 a, MyVector2 b, MyVector2 c)
        {
            float ma = (b.y - a.y) / (b.x - a.x);
            float mb = (c.y - b.y) / (c.x - b.x);

            float centerX = (ma * mb * (a.y - c.y) + mb * (a.x + b.x) - ma * (b.x + c.x)) / (2 * (mb - ma));

            float centerY = (-1f / ma) * (centerX - (a.x + b.x) / 2f) + (a.y + b.y) / 2f;

            MyVector2 center = new MyVector2(centerX, centerY);

            return(center);
        }
Example #14
0
        //
        // Is a triangle in 2d space oriented clockwise or counter-clockwise
        //
        //https://math.stackexchange.com/questions/1324179/how-to-tell-if-3-connected-points-are-connected-clockwise-or-counter-clockwise
        //https://en.wikipedia.org/wiki/Curve_orientation
        public static bool IsTriangleOrientedClockwise(MyVector2 p1, MyVector2 p2, MyVector2 p3)
        {
            bool isClockWise = true;

            float determinant = p1.x * p2.y + p3.x * p1.y + p2.x * p3.y - p1.x * p3.y - p3.x * p2.y - p2.x * p1.y;

            if (determinant > 0f)
            {
                isClockWise = false;
            }

            return(isClockWise);
        }
        //Help method to make code smaller
        //Is p to the right or on the line a-b
        private static bool IsPointToTheRightOrOnLine(MyVector2 a, MyVector2 b, MyVector2 p)
        {
            bool isToTheRight = false;

            LeftOnRight pointPos = _Geometry.IsPoint_Left_On_Right_OfVector(a, b, p);

            if (pointPos == LeftOnRight.Right || pointPos == LeftOnRight.On)
            {
                isToTheRight = true;
            }

            return(isToTheRight);
        }
Example #16
0
        //List<MyVector2>
        public static List <MyVector2> UnNormalize(List <MyVector2> normalized, AABB2 aabb, float dMax)
        {
            List <MyVector2> unNormalized = new List <MyVector2>();

            foreach (MyVector2 p in normalized)
            {
                MyVector2 pUnNormalized = UnNormalize(p, aabb, dMax);

                unNormalized.Add(pUnNormalized);
            }

            return(unNormalized);
        }
        //List<MyVector2>
        public List <MyVector2> UnNormalize(List <MyVector2> normalized)
        {
            List <MyVector2> unNormalized = new List <MyVector2>();

            foreach (MyVector2 p in normalized)
            {
                MyVector2 pUnNormalized = UnNormalize(p);

                unNormalized.Add(pUnNormalized);
            }

            return(unNormalized);
        }
Example #18
0
        //Generate two triangles if we know the corners of the rectangle
        public static HashSet <Triangle2> LineSegment(MyVector2 p1_T, MyVector2 p1_B, MyVector2 p2_T, MyVector2 p2_B)
        {
            HashSet <Triangle2> lineTriangles = new HashSet <Triangle2>();

            //Create the triangles
            Triangle2 t1 = new Triangle2(p1_T, p1_B, p2_T);
            Triangle2 t2 = new Triangle2(p1_B, p2_B, p2_T);

            lineTriangles.Add(t1);
            lineTriangles.Add(t2);

            return(lineTriangles);
        }
        //Find all triangles opposite of vertex p
        //But we will find all edges opposite to p, and from these edges we can find the triangles
        private static void AddTrianglesOppositePToStack(MyVector2 p, Stack <HalfEdge2> trianglesOppositeP, HalfEdgeData2 triangulationData)
        {
            //Find a vertex at position p and then rotate around it, triangle-by-triangle, to find all opposite edges
            HalfEdgeVertex2 rotateAroundThis = null;

            foreach (HalfEdgeVertex2 v in triangulationData.vertices)
            {
                if (v.position.Equals(p))
                {
                    rotateAroundThis = v;
                }
            }

            //Which triangle is this vertex a part of, so we know when we have rotated all the way around
            HalfEdgeFace2 tStart = rotateAroundThis.edge.face;

            HalfEdgeFace2 tCurrent = null;

            int safety = 0;

            while (tCurrent != tStart)
            {
                safety += 1;

                if (safety > 10000)
                {
                    Debug.Log("Stuck in endless loop when finding opposite edges in Delaunay Sloan");

                    break;
                }

                //The edge opposite to p
                HalfEdge2 edgeOppositeRotateVertex = rotateAroundThis.edge.nextEdge.oppositeEdge;

                //Try to add the edge to the list iof triangles we are interested in
                //Null might happen if we are at the border
                //A stack might include duplicates so we have to check for that as well
                if (edgeOppositeRotateVertex != null && !trianglesOppositeP.Contains(edgeOppositeRotateVertex))
                {
                    trianglesOppositeP.Push(edgeOppositeRotateVertex);
                }

                //Rotate left - this assumes we can always rotate left so no holes are allowed
                //and neither can we investigate one of the vertices thats a part of the supertriangle
                //which we dont need to worry about because p is never a part of the supertriangle
                rotateAroundThis = rotateAroundThis.edge.oppositeEdge.v;

                //In which triangle are we now?
                tCurrent = rotateAroundThis.edge.face;
            }
        }
Example #20
0
        //Optimize a new triangle according to Delaunay triangulation
        //TODO: This process would have been easier if we had used the HalfEdge data structure
        private static void OptimizeTriangle(Triangle2 t, HashSet <Triangle2> triangulation)
        {
            bool hasOppositeEdge;

            Triangle2 tOpposite;

            Edge2 edgeToSwap;

            FindEdgeInTriangulation(t, triangulation, out hasOppositeEdge, out tOpposite, out edgeToSwap);

            //If it has no opposite edge we just add triangle to the triangulation because it can't be improved
            if (!hasOppositeEdge)
            {
                triangulation.Add(t);

                return;
            }

            //Debug.Log("Has opposite edge");

            //Step 3. Check if we should swap this edge according to Delaunay triangulation rules
            //a, b, c belongs to the triangle and d is the point on the other triangle
            //a-c is the edge, which is important so we can flip it, by making the edge b-d
            MyVector2 a = edgeToSwap.p2;
            MyVector2 c = edgeToSwap.p1;
            MyVector2 b = t.GetVertexWhichIsNotPartOfEdge(edgeToSwap);
            MyVector2 d = tOpposite.GetVertexWhichIsNotPartOfEdge(edgeToSwap);

            bool shouldFlipEdge = DelaunayMethods.ShouldFlipEdge(a, b, c, d);

            //bool shouldFlipEdge = DelaunayMethods.ShouldFlipEdgeStable(a, b, c, d);

            if (shouldFlipEdge)
            {
                //First remove the old triangle
                triangulation.Remove(tOpposite);

                //Build two new triangles
                Triangle2 t1 = new Triangle2(a, b, d);
                Triangle2 t2 = new Triangle2(b, c, d);

                triangulation.Add(t1);
                triangulation.Add(t2);

                //Debug.Log("Flipped edge");
            }
            else
            {
                triangulation.Add(t);
            }
        }
Example #21
0
        //Find a triangle which has an edge going from p1 to p2
        //private static HalfEdgeFace2 FindTriangleWithEdge(MyVector2 p1, MyVector2 p2, HalfEdgeData2 triangleData)
        //{
        //    HashSet<HalfEdge2> edges = triangleData.edges;

        //    foreach (HalfEdge2 e in edges)
        //    {
        //        //An edge is going TO a vertex
        //        MyVector2 e_p1 = e.prevEdge.v.position;
        //        MyVector2 e_p2 = e.v.position;

        //        if (e_p1.Equals(p1) && e_p2.Equals(p2))
        //        {
        //            return e.face;
        //        }
        //    }

        //    return null;
        //}



        //Find all half-edges that are constraint
        private static HashSet <HalfEdge2> FindAllConstraintEdges(List <MyVector2> constraints, HalfEdgeData2 triangleData)
        {
            HashSet <HalfEdge2> constrainEdges = new HashSet <HalfEdge2>();


            //Create a new set with all constrains, and as we discover new constraints, we delete constrains, which will make searching faster
            //A constraint can only exist once!
            HashSet <Edge2> constraintsEdges = new HashSet <Edge2>();

            for (int i = 0; i < constraints.Count; i++)
            {
                MyVector2 c_p1 = constraints[i];
                MyVector2 c_p2 = constraints[MathUtility.ClampListIndex(i + 1, constraints.Count)];

                constraintsEdges.Add(new Edge2(c_p1, c_p2));
            }


            //All edges we have to search
            HashSet <HalfEdge2> edges = triangleData.edges;

            foreach (HalfEdge2 e in edges)
            {
                //An edge is going TO a vertex
                MyVector2 e_p1 = e.prevEdge.v.position;
                MyVector2 e_p2 = e.v.position;

                //Is this edge a constraint?
                foreach (Edge2 c_edge in constraintsEdges)
                {
                    if (e_p1.Equals(c_edge.p1) && e_p2.Equals(c_edge.p2))
                    {
                        constrainEdges.Add(e);

                        constraintsEdges.Remove(c_edge);

                        //Move on to the next edge
                        break;
                    }
                }

                //We have found all constraint, so don't need to search anymore
                if (constraintsEdges.Count == 0)
                {
                    break;
                }
            }

            return(constrainEdges);
        }
Example #22
0
        //
        // Edge stuff
        //

        //Are two edges the same edge?
        private static bool AreTwoEdgesTheSame(MyVector2 e1_p1, MyVector2 e1_p2, MyVector2 e2_p1, MyVector2 e2_p2)
        {
            //Is e1_p1 part of this constraint?
            if ((e1_p1.Equals(e2_p1) || e1_p1.Equals(e2_p2)))
            {
                //Is e1_p2 part of this constraint?
                if ((e1_p2.Equals(e2_p1) || e1_p2.Equals(e2_p2)))
                {
                    return(true);
                }
            }

            return(false);
        }
        //
        // Line-point calculations
        //
        //From https://stackoverflow.com/questions/3120357/get-closest-point-to-a-line
        //and https://www.youtube.com/watch?v=_ENEsV_kNx8
        public static MyVector2 GetClosestPointOnLine(Edge2 e, MyVector2 p, bool withinSegment)
        {
            MyVector2 a = e.p1;
            MyVector2 b = e.p2;

            //Assume the line goes from a to b
            MyVector2 ab = b - a;
            //Vector from "start" of the line to the point outside of line
            MyVector2 ap = p - a;

            //Scalar projection https://en.wikipedia.org/wiki/Scalar_projection
            //The scalar projection is a scalar, equal to the length of the orthogonal projection of ap on ab, with a negative sign if the projection has an opposite direction with respect to ab.
            //scalarProjection = Dot(ap, ab) / Magnitude(ab) where the magnitude of ab is the distance between a and b
            //If ab is normalized, we get scalarProjection = Dot(ap, ab)

            //The distance from a to q (the closes point on the line):
            //float aq_distance = MyVector2.Dot(ap, ab) / MyVector2.Magnitude(ab);

            //To get the closest point on the line:
            //MyVector2 q = a + MyVector2.Normalize(ab) * aq_distance;


            //Can we do better?
            //Magnitude is defined as: Mathf.Sqrt((ab * ab))
            //Normalization is defined as (ab / magnitude(ab))
            //We get: q = a + (ab / magnitude(ab)) * (1 / magnitude(ab)) * dot(ap, ab)
            //Ignore the q and the dot and we get: (ab / Mathf.Sqrt((ab * ab))) * (1 / Mathf.Sqrt((ab * ab))) = ab / (ab * ab)
            //So we can use the square magnitude of ab and then we don't need to normalize ab (to get q), so we save two square roots, which is good because square root is a slow operation

            //The normalized "distance" from a to the closest point, so between 0 and 1 if we are within the line segment
            float distance = MyVector2.Dot(ap, ab) / MyVector2.SqrMagnitude(ab);

            //This point may not be on the line segment, if so return one of the end points
            float epsilon = MathUtility.EPSILON;

            if (withinSegment && distance < 0f - epsilon)
            {
                return(a);
            }
            else if (withinSegment && distance > 1f + epsilon)
            {
                return(b);
            }
            else
            {
                //This works because a_b is not normalized and distance is [0,1] if distance is within ab
                return(a + ab * distance);
            }
        }
        private static MyVector2 GetLerpedMidpoint(MyVector2 v1, float weight1, MyVector2 v2, float weight2)
        {
            float weight = (1f - weight1) / (weight2 - weight1);

            //MyVector2 interpolatedPos =  v1 + (v2 - v1) * weight;

            MyVector2 interpolatedPos = _Interpolation.BezierLinear(v1, v2, weight);

            //float interX = _Interpolation.Sinerp(v1.x, v2.x, weight);
            //float interY = _Interpolation.Sinerp(v1.y, v2.y, weight);

            //MyVector2 interpolatedPos = new MyVector2(interX, interY);

            return(interpolatedPos);
        }
Example #25
0
        //Is an edge between p1 and p2 a constraint?
        private static bool IsEdgeAConstraint(MyVector2 p1, MyVector2 p2, List <MyVector2> constraints)
        {
            for (int i = 0; i < constraints.Count; i++)
            {
                MyVector2 c_p1 = constraints[i];
                MyVector2 c_p2 = constraints[MathUtility.ClampListIndex(i + 1, constraints.Count)];

                if (AreTwoEdgesTheSame(p1, p2, c_p1, c_p2))
                {
                    return(true);
                }
            }

            return(false);
        }
Example #26
0
 //Find the opposite edge to a vertex
 public Edge2 FindOppositeEdgeToVertex(MyVector2 p)
 {
     if (p.Equals(p1))
     {
         return(new Edge2(p2, p3));
     }
     else if (p.Equals(p2))
     {
         return(new Edge2(p3, p1));
     }
     else
     {
         return(new Edge2(p1, p2));
     }
 }
Example #27
0
 //Alternative 2 in 2d space [radians]
 public static float AngleFromToCCW(MyVector2 from, MyVector2 to)
 {
     //The determinant is similar to the dot product
     //The dot product is always 0 no matter in which direction the perpendicular vector is pointing
     //But the determinant is -1 or 1 depending on which way the perpendicular vector is pointing (up or down)
     //AngleBetween goes from 0 to 180 so we can now determine if we need to compensate to get 360 degrees
     if (MathUtility.Det2(from, to) > 0f)
     {
         return(AngleBetween(from, to));
     }
     else
     {
         return((Mathf.PI * 2f) - AngleBetween(from, to));
     }
 }
Example #28
0
        private static float CalculateInteriorAngle(MyVector2 p_prev, MyVector2 p, MyVector2 p_next)
        {
            //Two vectors going from the vertex
            //You (most likely) don't need to normalize these
            MyVector2 p_to_p_prev = p_prev - p;
            MyVector2 p_to_p_next = p_next - p;

            //The angle between the two vectors [rad]
            //This will calculate the outside angle
            float angle = MathUtility.AngleFromToCCW(p_to_p_prev, p_to_p_next);

            //The interior angle is the opposite of the outside angle
            float interiorAngle = (Mathf.PI * 2f) - angle;

            return(interiorAngle);
        }
Example #29
0
        public static bool IsPointLeftOfVector(MyVector2 a, MyVector2 b, MyVector2 p)
        {
            float relationValue = GetPointInRelationToVectorValue(a, b, p);

            bool isToLeft = true;

            //to avoid floating point precision issues we can add a small value
            float epsilon = MathUtility.EPSILON;

            if (relationValue < 0f - epsilon)
            {
                isToLeft = false;
            }

            return(isToLeft);
        }
Example #30
0
        //2d
        public static MyVector2 GetPosition(MyVector2 a, MyVector2 b, float t)
        {
            t = Mathf.Clamp01(t);

            //float lerpX = _Interpolation.Lerp(a.x, b.x, t);
            //float lerpY = _Interpolation.Lerp(a.y, b.y, t);

            //MyVector2 interpolatedPos = new MyVector2(lerpX, lerpY);

            //Above is same as
            //(1-t)A + tB = A - At + Bt

            MyVector2 interpolatedPos = a - a * t + b * t;

            return(interpolatedPos);
        }