/// <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;
			}
			/// <summary>
			/// 检查vertices[index]的内角, 是否为优角.
			/// </summary>
			/// <param name="vertices"></param>
			/// <param name="index"></param>
			/// <returns></returns>
			static bool CheckIsReflex(ArrayLinkedList<EarVertex> vertices, int index)
			{
				Vertex current = vertices[index].vertex;
				Vertex prev = vertices.PrevValue(index).vertex;
				Vertex next = vertices.NextValue(index).vertex;
				return next.Position.cross2(prev.Position, current.Position) < 0f;
			}