TriangleArea() public static method

public static TriangleArea ( Vector3 a, Vector3 b, Vector3 c ) : float
a Vector3
b Vector3
c Vector3
return float
Ejemplo n.º 1
0
		/** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
		 * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
		 * For other node types, only the positions of the nodes will be used.
		 * 
		 * clearanceRadius will be reduced if no valid points can be found.
		 */
		public static List<Vector3> GetPointsOnNodes (List<GraphNode> nodes, int count, float clearanceRadius = 0) {
			
			if (nodes == null) throw new ArgumentNullException ("nodes");
			if (nodes.Count == 0) throw new ArgumentException ("no nodes passed");
			
			var rnd = new System.Random();
			
			var pts = ListPool<Vector3>.Claim(count);
			
			// Square
			clearanceRadius *= clearanceRadius;
			
			if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode) {
				//Assume all nodes are triangle nodes or grid nodes
				
				var accs = ListPool<float>.Claim(nodes.Count);
					
				float tot = 0;
				
				for (var i=0;i<nodes.Count;i++) {
					var tnode = nodes[i] as TriangleMeshNode;
					if (tnode != null) {
						float a = Math.Abs(Polygon.TriangleArea(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
						tot += a;
						accs.Add (tot);
					}
					 else {
						var gnode = nodes[i] as GridNode;
						
						if (gnode != null) {
							var gg = GridNode.GetGridGraph (gnode.GraphIndex);
							var a = gg.nodeSize*gg.nodeSize;
							tot += a;
							accs.Add (tot);
						} else {
							accs.Add(tot);
						}
					}
				}
				
				for (var i=0;i<count;i++) {
					
					//Pick point
					var testCount = 0;
					var testLimit = 10;
					var worked = false;
					
					while (!worked) {
						worked = true;
						
						//If no valid points can be found, progressively lower the clearance radius until such a point is found
						if (testCount >= testLimit) {
							clearanceRadius *= 0.8f;
							testLimit += 10;
							if (testLimit > 100) clearanceRadius = 0;
						}
					
						var tg = (float)rnd.NextDouble()*tot;
						var v = accs.BinarySearch(tg);
						if (v < 0) v = ~v;
						
						if (v >= nodes.Count) {
							// This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
							worked = false;
							continue;
						}
						
						var node = nodes[v] as TriangleMeshNode;
						
						Vector3 p;
						
						if (node != null) {
							// Find a random point inside the triangle
							float v1;
							float v2;
							do {
								v1 = (float)rnd.NextDouble();
								v2 = (float)rnd.NextDouble();
							} while (v1+v2 > 1);
							
							p = ((Vector3)(node.GetVertex(1)-node.GetVertex(0)))*v1 + ((Vector3)(node.GetVertex(2)-node.GetVertex(0)))*v2 + (Vector3)node.GetVertex(0);
						} else {
							var gnode = nodes[v] as GridNode;
							
							if (gnode != null) {
								var gg = GridNode.GetGridGraph (gnode.GraphIndex);
								
								var v1 = (float)rnd.NextDouble();
								var v2 = (float)rnd.NextDouble();
								p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
							} else
							{
								//Point nodes have no area, so we break directly instead
								pts.Add ((Vector3)nodes[v].position);
								break;
							}
						}
						
						// Test if it is some distance away from the other points
						if (clearanceRadius > 0) {
							for (var j=0;j<pts.Count;j++) {
								if ((pts[j]-p).sqrMagnitude < clearanceRadius) {
									worked = false;
									break;
								}
							}
						}
						
						if (worked) {
							pts.Add (p);
							break;
						} else {
							testCount++;
						}
					}
				}
				
				ListPool<float>.Release(accs);
				
			} else {
				for (var i=0;i<count;i++) {
					pts.Add ((Vector3)nodes[rnd.Next (nodes.Count)].position);
				}
			}
			
			return pts;
		}
Ejemplo n.º 2
0
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0f)
        {
            if (nodes == null)
            {
                throw new ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new ArgumentException("no nodes passed");
            }
            Random         random = new Random();
            List <Vector3> list   = ListPool <Vector3> .Claim(count);

            clearanceRadius *= clearanceRadius;
            if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode)
            {
                List <float> list2 = ListPool <float> .Claim(nodes.Count);

                float num = 0f;
                for (int i = 0; i < nodes.Count; i++)
                {
                    TriangleMeshNode triangleMeshNode = nodes[i] as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        float num2 = (float)Math.Abs(Polygon.TriangleArea(triangleMeshNode.GetVertex(0), triangleMeshNode.GetVertex(1), triangleMeshNode.GetVertex(2)));
                        num += num2;
                        list2.Add(num);
                    }
                    else
                    {
                        GridNode gridNode = nodes[i] as GridNode;
                        if (gridNode != null)
                        {
                            GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);
                            float     num3      = gridGraph.nodeSize * gridGraph.nodeSize;
                            num += num3;
                            list2.Add(num);
                        }
                        else
                        {
                            list2.Add(num);
                        }
                    }
                }
                for (int j = 0; j < count; j++)
                {
                    int  num4 = 0;
                    int  num5 = 10;
                    bool flag = false;
                    while (!flag)
                    {
                        flag = true;
                        if (num4 >= num5)
                        {
                            clearanceRadius *= 0.8f;
                            num5            += 10;
                            if (num5 > 100)
                            {
                                clearanceRadius = 0f;
                            }
                        }
                        float item = (float)random.NextDouble() * num;
                        int   num6 = list2.BinarySearch(item);
                        if (num6 < 0)
                        {
                            num6 = ~num6;
                        }
                        if (num6 >= nodes.Count)
                        {
                            flag = false;
                        }
                        else
                        {
                            TriangleMeshNode triangleMeshNode2 = nodes[num6] as TriangleMeshNode;
                            Vector3          vector;
                            if (triangleMeshNode2 != null)
                            {
                                float num7;
                                float num8;
                                do
                                {
                                    num7 = (float)random.NextDouble();
                                    num8 = (float)random.NextDouble();
                                }while (num7 + num8 > 1f);
                                vector = (Vector3)(triangleMeshNode2.GetVertex(1) - triangleMeshNode2.GetVertex(0)) * num7 + (Vector3)(triangleMeshNode2.GetVertex(2) - triangleMeshNode2.GetVertex(0)) * num8 + (Vector3)triangleMeshNode2.GetVertex(0);
                            }
                            else
                            {
                                GridNode gridNode2 = nodes[num6] as GridNode;
                                if (gridNode2 == null)
                                {
                                    list.Add((Vector3)nodes[num6].position);
                                    break;
                                }
                                GridGraph gridGraph2 = GridNode.GetGridGraph(gridNode2.GraphIndex);
                                float     num9       = (float)random.NextDouble();
                                float     num10      = (float)random.NextDouble();
                                vector = (Vector3)gridNode2.position + new Vector3(num9 - 0.5f, 0f, num10 - 0.5f) * gridGraph2.nodeSize;
                            }
                            if (clearanceRadius > 0f)
                            {
                                for (int k = 0; k < list.Count; k++)
                                {
                                    if ((list[k] - vector).sqrMagnitude < clearanceRadius)
                                    {
                                        flag = false;
                                        break;
                                    }
                                }
                            }
                            if (flag)
                            {
                                list.Add(vector);
                                break;
                            }
                            num4++;
                        }
                    }
                }
                ListPool <float> .Release(list2);
            }
            else
            {
                for (int l = 0; l < count; l++)
                {
                    list.Add((Vector3)nodes[random.Next(nodes.Count)].position);
                }
            }
            return(list);
        }