public static GetClosestPointOnEdge ( Vector3 point, Vector3 _v1, Vector3 _v2 ) : Vector2 | ||
point | Vector3 | |
_v1 | Vector3 | |
_v2 | Vector3 | |
return | Vector2 |
/// <summary> /// Returns closest point on all the given edges. Edge positions are changed to world coordinates in reference to refTransform. /// </summary> public static Vector3 GetClosestPointOnEdge(Vector3 point, List <Node> nodes, List <Edge> edges, Transform refTransform, out Edge closestEdge) { Vector3 pointOnEdge = Vector3.zero; closestEdge = edges[0]; float closestDist = Mathf.Infinity; for (int i = 0; i < edges.Count; i++) { Vector2 splitPointXZ; Node node1 = EdgeGraphUtility.GetNode(edges[i].Node1, ref nodes); if (node1 == null) { continue; } Vector3 n1Pos = node1.Position; n1Pos = refTransform.TransformPoint(n1Pos); Node node2 = EdgeGraphUtility.GetNode(edges[i].Node2, ref nodes); if (node2 == null) { continue; } Vector3 n2Pos = node2.Position; n2Pos = refTransform.TransformPoint(n2Pos); splitPointXZ = Edge.GetClosestPointOnEdge(point, n1Pos, n2Pos); Vector3 splitPoint = new Vector3(splitPointXZ.x, n1Pos.y, splitPointXZ.y); if (Vector3.Distance(point, splitPoint) < closestDist) { closestEdge = edges[i]; pointOnEdge = splitPoint; closestDist = Vector3.Distance(point, splitPoint); } } return(pointOnEdge); }
/// <summary> /// Returns closest point on the closest point with given point /// </summary> public static Vector3 GetPointOnClosestEdge(Vector3 point, List <Node> nodes, List <Edge> edges, Transform refTransform) { Edge closestEdge = GetClosestEdge(point, nodes, edges, refTransform); if (closestEdge == null) { return(Vector3.zero); } Vector2 splitPointXZ; Node node1 = EdgeGraphUtility.GetNode(closestEdge.Node1, ref nodes); if (node1 == null) { return(Vector3.zero); } Vector3 n1Pos = node1.Position; n1Pos = refTransform.TransformPoint(n1Pos); Node node2 = EdgeGraphUtility.GetNode(closestEdge.Node2, ref nodes); if (node2 == null) { return(Vector3.zero); } Vector3 n2Pos = node2.Position; n2Pos = refTransform.TransformPoint(n2Pos); splitPointXZ = Edge.GetClosestPointOnEdge(point, n1Pos, n2Pos); return(new Vector3(splitPointXZ.x, n1Pos.y, splitPointXZ.y)); }
void GenerateSubEdgeTargets() { UnityEngine.Random.seed = subEdgeRandomSeed; int safeCount = 0; int pointCount = 0; subEdgeTargets = new List <Vector3>(); while (safeCount < 1000) { safeCount++; //Get random point inside the boundaries float randX = UnityEngine.Random.Range(minX, maxX); float randZ = UnityEngine.Random.Range(minZ, maxZ); Vector3 point = new Vector3(randX, 0f, randZ); //If point is inside the polygon, proceed if (EdgeGraphUtility.PointIsInside(point, nodes, edges)) { //Check if the point is inside the margins if (subEdgeTargetMargin > 0) { float toClosest = Mathf.Infinity; //Edge closest; foreach (var edge in edges) { Vector2 closestXZ = Edge.GetClosestPointOnEdge(point, nodes.Find(x => x.ID == edge.Node1).Position, nodes.Find(x => x.ID == edge.Node2).Position); Vector3 closestPoint = new Vector3(closestXZ.x, 0f, closestXZ.y); float dist = Vector3.Distance(point, closestPoint); if (dist < toClosest) { toClosest = dist; //closest = edge; } } if (toClosest < subEdgeTargetMargin) { continue; } } //If new point is too close to existing one, discard it bool pointIsTooClose = false; foreach (var target in subEdgeTargets) { if (Vector3.Distance(point, target) < subEdgeMinDistance) { pointIsTooClose = true; break; } } if (!pointIsTooClose) { subEdgeTargets.Add(point); pointCount++; } } if (pointCount >= subEdgeTargetCount) { break; } } }