Quantcast
Channel: Answers by "Leonardo_Temperanza"
Viewing all articles
Browse latest Browse all 6

Answer by Leonardo_Temperanza

$
0
0
Hi, I finally found the solution to my problem. I found a free physics engine in the asset store, named FarseerUnity. That asset has a class named "Bayazit Decomposer", which obviously uses Bayazit's algorithm to decompose the polygon. So I copyed the functions that were necessary and the class is now working perfectly. Here is the class: using UnityEngine; using System; using System.Collections; using System.Collections.Generic; /// /// This class is took from the "FarseerUnity" physics engine, which uses Mark Bayazit's decomposition algorithm. /// I also have to make it work with self-intersecting polygons, so I'll use another different algorithm to decompose a self-intersecting polygon into several simple polygons, /// and then I would decompose each of them into convex polygons. /// //From phed rev 36 /// /// Convex decomposition algorithm created by Mark Bayazit (http://mnbayazit.com/) /// For more information about this algorithm, see http://mnbayazit.com/406/bayazit /// public static class BayazitDecomposer { private static Vector2 At(int i, List vertices) { int s = vertices.Count; return vertices[i Copy(int i, int j, List vertices) { List p = new List(); while (j /// Decompose the polygon into several smaller non-concave polygon. /// If the polygon is already convex, it will return the original polygon, unless it is over Settings.MaxPolygonVertices. /// Precondition: Counter Clockwise polygon /// /// /// public static List> ConvexPartition(List vertices) { //We force it to CCW as it is a precondition in this algorithm. ForceCounterClockWise (vertices); List> list = new List>(); float d, lowerDist, upperDist; Vector2 p; Vector2 lowerInt = new Vector2(); Vector2 upperInt = new Vector2(); // intersection points int lowerIndex = 0, upperIndex = 0; List lowerPoly, upperPoly; for (int i = 0; i ::max(); for (int j = 0; j highestScore) { bestIndex = j; highestScore = score; } } } lowerPoly = Copy(i, (int)bestIndex, vertices); upperPoly = Copy((int)bestIndex, i, vertices); } list.AddRange(ConvexPartition(lowerPoly)); list.AddRange(ConvexPartition(upperPoly)); return list; } } // polygon is already convex list.Add(vertices); //The polygons are not guaranteed to be without collinear points. We remove //them to be sure. for (int i = 0; i = 0; i--) { if (list[i].Count == 0) list.RemoveAt(i); } return list; } private static bool CanSee(int i, int j, List vertices) { if (Reflex(i, vertices)) { if (LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices)) && RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices))) return false; } else { if (RightOn(At(i, vertices), At(i + 1, vertices), At(j, vertices)) || LeftOn(At(i, vertices), At(i - 1, vertices), At(j, vertices))) return false; } if (Reflex(j, vertices)) { if (LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices)) && RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices))) return false; } else { if (RightOn(At(j, vertices), At(j + 1, vertices), At(i, vertices)) || LeftOn(At(j, vertices), At(j - 1, vertices), At(i, vertices))) return false; } for (int k = 0; k vertices) { return Right(i, vertices); } private static bool Right(int i, List vertices) { return Right(At(i - 1, vertices), At(i, vertices), At(i + 1, vertices)); } private static bool Left(Vector2 a, Vector2 b, Vector2 c) { return Area(ref a, ref b, ref c) > 0; } private static bool LeftOn(Vector2 a, Vector2 b, Vector2 c) { return Area(ref a, ref b, ref c) >= 0; } private static bool Right(Vector2 a, Vector2 b, Vector2 c) { return Area(ref a, ref b, ref c) vertices) { if (!IsCounterClockWise(vertices)) { vertices.Reverse(); } } private static bool IsCounterClockWise(List vertices) { //We just return true for lines if (vertices.Count 0.0f); } //gets the signed area. private static float GetSignedArea(List vertices) { int i; float area = 0; for (i = 0; i a1 and b0->b1 cross. //if they do, intersectionPoint will be filled with the point of crossing. Grazing lines should not return true. private static bool LineIntersect2(Vector2 a0, Vector2 a1, Vector2 b0, Vector2 b1, out Vector2 intersectionPoint) { intersectionPoint = Vector2.zero; if (a0 == b0 || a0 == b1 || a1 == b0 || a1 == b1) return false; float x1 = a0.x; float y1 = a0.y; float x2 = a1.x; float y2 = a1.y; float x3 = b0.x; float y3 = b0.y; float x4 = b1.x; float y4 = b1.y; //AABB early exit if (Math.Max(x1, x2) private static float Area(Vector2 a, Vector2 b, Vector2 c) { return Area(ref a, ref b, ref c); } //returns a positive number if c is to the left of the line going from a to b. Positive number if point is left, negative if point is right, and 0 if points are collinear. private static float Area(ref Vector2 a, ref Vector2 b, ref Vector2 c) { return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y); } //removes all collinear points on the polygon. private static List CollinearSimplify(List vertices, float collinearityTolerance) { //We can't simplify polygons under 3 vertices if (vertices.Count simplified = new List(); for (int i = 0; i vertices, int index) { if (index == 0) { return vertices.Count - 1; } return index - 1; } //nexts the index. private static int NextIndex(List vertices, int index) { if (index == vertices.Count - 1) { return 0; } return index + 1; } private static bool Collinear(ref Vector2 a, ref Vector2 b, ref Vector2 c, float tolerance) { return FloatInRange(Area(ref a, ref b, ref c), -tolerance, tolerance); } //checks if a floating point Value is within a specified range of values (inclusive). private static bool FloatInRange(float value, float min, float max) { return (value >= min && value (); if (col == null) { Debug.LogError ("There is no 'PolygonCollider2D' attached to the object 'BayazitDecomposerTester' is attached to."); } } void OnDrawGizmos () { if (!Application.isPlaying || !show) return; Gizmos.color = Color.green; List worldColPoints = new List (); foreach (Vector2 point in col.points) { Vector2 currentWorldPoint = this.transform.TransformPoint (point); worldColPoints.Add (currentWorldPoint); } List vertices = worldColPoints; List> listOfConvexPolygonPoints = BayazitDecomposer.ConvexPartition (vertices); foreach (List pointsOfIndivualConvexPolygon in listOfConvexPolygonPoints) { List currentPolygonVertices = pointsOfIndivualConvexPolygon; for (int i = 0; i = currentPolygonVertices.Count? 0 : i + 1]; Gizmos.DrawLine (currentVertex, nextVertex); } } } }

Viewing all articles
Browse latest Browse all 6

Latest Images

Trending Articles



Latest Images