Ear cutting method using the polygon triangulation [turn]

https://blog.csdn.net/yiwei151/article/details/87946592

Renderings:

 

Practices and principles can refer to this link: http://www.cnblogs.com/xignzou/p/3721494.html

 Code:

the System the using;
the using the System.Collections.Generic;
the using UnityEngine;

namespace PolygonTool
{

#region ears cut method simple polygons of triangular

/// <Summary>
/// judgment pits, bumps, ear axis comparison
/// < / Summary>
public enum CompareAxle
{
X-,
the Y,
the Z
}

/// <Summary>
/// polygon processing
/// </ Summary>
public class Triangulation
{

/// <Summary>
/// unevenness determination time axis alignment
/// </ Summary>
Private CompareAxle _compareAxle = CompareAxle.Y;

/// <Summary>
/// polygon vertices
/// </ Summary>
Private List <Vector3> = _polygonVertexs new new List <Vector3> () ;

/// <summary>
/// vertex sequence
/// </ Summary>
Private List <int> = _vertexsSequence new new List <int> ();

/// <Summary>
/// Node Manager
/// </ Summary>
Private the NodeManager _nodeManager = the NodeManager new new ();

/// <Summary>
/// initialization
/// </ Summary>
/// <param name = "polygonVertexs"> polygon vertices </ param>
public Triangulation (List <Vector3> polygonVertexs)
{
the this = polygonVertexs ._polygonVertexs;
_nodeManager.Init (polygonVertexs);
}

/// <Summary>
/// Comparative shaft disposed
/// </ Summary>
/// <param name = "compareAxle"> </ param>
public void SetCompareAxle(CompareAxle compareAxle)
{
this._compareAxle = compareAxle;
}

/// <Summary>
/// Get apex of the triangle sequence
/// </ Summary>
public int [] GetTriangles ()
{
the while (_nodeManager.LinkedListLength> =. 3)
{
SplitResult SplitPolygon SR = ();
//
IF (SR == null)
{
Debug.Log ( "null");
return null;
}
}

return _vertexsSequence.ToArray ();
}

/// <Summary>
/// calculation concave vertex, vertex projections, ear
/// < / Summary>
Private SplitResult SplitPolygon ()
{
// pits
List <the Node> = _concaveVertexs new new List <the Node> ();
// bump
List <the Node> = _raisedVertexs new new List <the Node> ();
// ear
List < Node>_polygonEars = new List<Node>();
//起始节点
Node currentNode = _nodeManager.FirstNode;

#region 计算凹顶点,凸顶点

for (int i = 0; i < _nodeManager.LinkedListLength; i++)
{
Vector3 one = currentNode.vertex - currentNode.lastNode.vertex;
Vector3 two = currentNode.nextNode.vertex - currentNode.vertex;
Vector3 crossRes = Vector3.Cross(one, two);

if (_compareAxle == CompareAxle.Y)
{
if (crossRes.y > 0)
{
_concaveVertexs.Add(currentNode);
}
else
{
_raisedVertexs.Add(currentNode);
}
}

if (_compareAxle == CompareAxle.X)
{
if (crossRes.x > 0)
{
_concaveVertexs.Add(currentNode);
}
else
{
_raisedVertexs.Add(currentNode);
}
}

if (_compareAxle == CompareAxle.Z)
{
if (crossRes.z > 0)
{
_concaveVertexs.Add(currentNode);
}
else
{
_raisedVertexs.Add(currentNode);
}
}

_polygonEars.Add(currentNode);
currentNode = currentNode.nextNode;
}

for (int i = 0; i < _concaveVertexs.Count; i++)
{
_polygonEars.Remove(_concaveVertexs[i]);
}
#endregion

#region 计算耳朵
List<int> needRemoveIdList = new List<int>();
for (int i = 0; i < _polygonEars.Count; i++)
{
Node earNode = _polygonEars[i];
Node compareNode = earNode.nextNode.nextNode;

while (compareNode != earNode.lastNode)
{
bool isIn = IsIn(compareNode.vertex, earNode.lastNode.vertex, earNode.vertex,
earNode.nextNode.vertex);

if (isIn == true)
{
if (_polygonEars.Contains(_polygonEars[i]))
{
needRemoveIdList.Add(_polygonEars[i].id);
}
break;
}
compareNode = compareNode.nextNode;
}
}

for (int j = 0; j < needRemoveIdList.Count; j++)
{
for (int i = 0; i < _polygonEars.Count; i++)
{
if (_polygonEars[i].id == needRemoveIdList[j])
{
_polygonEars.RemoveAt (I);
}
}
}

#endregion

#region print result of the initialization

Debug.Log ( "bump");
for (int I = 0; I <_raisedVertexs.Count; I ++)
{
Debug.Log (_raisedVertexs [I ] .id);
}

Debug.Log ( "pits");
for (int I = 0; I <_concaveVertexs.Count; I ++)
{
Debug.Log (_concaveVertexs [I] .id);
}

Debug.Log ( " ears ");
for (int I = 0; I <_polygonEars.Count; I ++)
{
Debug.Log (_polygonEars [I] .id);
}

Debug.Log (" ----------------------- ----------------------------------- ");
#endregion

// ear is not a simple explanation for the empty polygons triangulation failure
if (_polygonEars.Count == 0)
{
return null;
}

_vertexsSequence.Add(_polygonEars[0].lastNode.id);
_vertexsSequence.Add(_polygonEars[0].id);
_vertexsSequence.Add(_polygonEars[0].nextNode.id);
_nodeManager.RemoveNode(_polygonEars[0]);


return new SplitResult(_raisedVertexs, _concaveVertexs, _polygonEars);
}

/// <summary>
/// 判断一点是否在三角形内
/// </summary>
/// <param name="p">一点</param>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <returns></returns>
public bool IsIn(Vector3 p,Vector3 a,Vector3 b,Vector3 c)
{
Vector3 pa = p - a;
Vector3 pb = p - b;
Vector3 pc = p - c;

Vector3 t1 = Vector3.Cross(pa, pb);
Vector3 t2 = Vector3.Cross(pb, pc);
Vector3 t3 = Vector3.Cross(pc, pa);

bool isIn2 = t1.y >= 0 && t2.y >= 0 && t3.y >= 0 || t1.y <= 0 && t2.y <= 0 && t3.y <= 0;

return isIn2;
}

/// <summary>
/// 管理多边形 构成一个双向链表
/// </summary>
public class NodeManager
{

private List<Node> _nodeList = new List<Node>();

public int LinkedListLength
{
get { return _nodeList.Count; }
}

public Node FirstNode
{
get { return _nodeList[0]; }
}

public void Init(List<Vector3> vertexs)
{

for (int i = 0; i < vertexs.Count; i++)
{
Node node = new Node(i, vertexs[i]);
_nodeList.Add(node);
}

for (int i = 0; i < LinkedListLength; i++)
{
if (i == 0)
{
_nodeList[i].lastNode = _nodeList[LinkedListLength - 1];
_nodeList[i].nextNode = _nodeList[1];
}
else if (i == LinkedListLength - 1)
{
_nodeList[i].lastNode = _nodeList[LinkedListLength - 2];
_nodeList[i].nextNode = _nodeList[0];
}
else
{
_nodeList[i].lastNode = _nodeList[i - 1];
_nodeList[i].nextNode = _nodeList[i + 1];
}
}
}

public void RemoveNode(Node node)
{
_nodeList.Remove(node);
node.lastNode.nextNode = node.nextNode;
node.nextNode.lastNode = node.lastNode;
}
}

public class Node
{

public int id;
public Vector3 vertex;
public Node lastNode;
public Node nextNode;

public Node(int id, Vector3 vertex)
{
this.id = id;
this.vertex = vertex;
}

public Node(int id, Vector3 vertex, Node lastNode, Node nextNode)
{
this.id = id;
this.vertex = vertex;
this.lastNode = lastNode;
this.nextNode = nextNode;
}
}

public class SplitResult
{
/// <summary>
/// 凸顶点
/// </summary>
public List<Node> raisedVertexs;

/// <summary>
/// 凹顶点
/// </summary>
public List<Node> concaveVertexs;

/// <summary>
/// 耳朵
/// </summary>
public List<Node> polygonEars;

public SplitResult(List<Node> raisedVertexs, List<Node> concaveVertexs, List<Node> polygonEars)
{
this.raisedVertexs = raisedVertexs;
this.concaveVertexs = concaveVertexs;
this.polygonEars = polygonEars;
}
}
}

#endregion
}

 

github Address: https://github.com/yiwei151/PolygonTriangulation

 

Guess you like

Origin www.cnblogs.com/mazhenyu/p/11577642.html