コード例 #1
0
			/// <summary>
			/// 检查vertices中索引为current的顶点是否为耳朵.
			/// </summary>
			static bool CheckIsEar(ArrayLinkedList<EarVertex> vertices, int current)
			{
				if (vertices.Count < 3) { return false; }

				int prev = vertices.PrevIndex(current);
				int next = vertices.NextIndex(current);

				Vector3[] points = new Vector3[]
				{
					vertices[prev].vertex.Position, 
					vertices[current].vertex.Position,
					vertices[next].vertex.Position 
				};

				// 三点共线, 必然不是耳朵.
				if (MathUtility.Approximately(points[0].cross2(points[2], points[1]), 0f))
				{
					return false;
				}

				// 检查prev, current, next组成的三角形, 是否包含其它点.
				for (var e = vertices.GetEnumerator(); e.MoveNext(); )
				{
					if (e.CurrentIndex == current || e.CurrentIndex == prev || e.CurrentIndex == next)
					{
						continue;
					}

					if (MathUtility.PolygonContains(points, vertices[e.CurrentIndex].vertex.Position))
					{
						return false;
					}
				}

				// 如果不包含其它点, 那么该点为耳朵.
				return true;
			}
コード例 #2
0
			/// <summary>
			/// 对vertices组成的多边形三角形化.
			/// <para>earTips为当前的耳朵的索引.</para>
			static List<Vertex> DoTriangulate(ArrayLinkedList<EarVertex> vertices, ArrayLinkedList<int> earTips)
			{
				// N边行, 形成N-2个三角形, 共3*(N-2)个顶点.
				List<Vertex> answer = new List<Vertex>((vertices.Count - 2) * 3);

				// 被移除的耳朵.
				EarVertex[] removedEars = new EarVertex[2];
				int removedEarCount = 0;

				// 需要被移除的耳朵的在earTips中的索引.
				int earTipIndex = -1;
				for (var e = earTips.GetEnumerator(); e.MoveNext(); )
				{
					if (earTipIndex >= 0) { earTips.RemoveAt(earTipIndex); }

					earTipIndex = e.CurrentIndex;

					// 需要移除的耳朵的在vertices中的索引.
					int earTipVertexIndex = earTips[earTipIndex];
					// 需要移除的耳朵节点.
					EarVertex earTipVertex = vertices[earTipVertexIndex];

					// 耳朵节点的上一个节点.
					int prevIndex = vertices.PrevIndex(earTipVertexIndex);
					EarVertex prevVertex = vertices.PrevValue(earTipVertexIndex);

					// 耳朵节点的下一个节点.
					int nextIndex = vertices.NextIndex(earTipVertexIndex);
					EarVertex nextVertex = vertices.NextValue(earTipVertexIndex);

					// 构成新的三角形.
					answer.Add(prevVertex.vertex);
					answer.Add(earTipVertex.vertex);
					answer.Add(nextVertex.vertex);

					// 以该节点为耳尖的耳朵已被"切掉", 移除这个节点.
					vertices.RemoveAt(earTipVertexIndex);

					// 更新该节点的上节点的状态.
					int state = UpdateEarVertexState(vertices, prevIndex);
					// 加入新的耳朵.
					if (state > 0)
					{
						prevVertex.earListIndex = earTips.Add(prevIndex);
					}
					// 收集之前是, 而现在不再是耳朵的节点.
					else if (state < 0)
					{
						removedEars[removedEarCount++] = prevVertex;
					}

					// 更新该节点的下节点的状态.
					state = UpdateEarVertexState(vertices, nextIndex);
					if (state > 0)
					{
						nextVertex.earListIndex = earTips.Add(nextIndex);
					}
					else if (state < 0)
					{
						removedEars[removedEarCount++] = nextVertex;
					}

					// 在earTips中移除之前是, 现在不是耳朵的节点.
					for (int i = 0; i < removedEarCount; ++i)
					{
						Utility.Verify(removedEars[i].earListIndex >= 0);
						earTips.RemoveAt(removedEars[i].earListIndex);
						removedEars[i].earListIndex = -1;
					}

					removedEarCount = 0;
				}

				// 移除最后一个耳朵, 清空earTips.
				if (earTipIndex >= 0) { earTips.RemoveAt(earTipIndex); }

				return answer;
			}