ポリゴン三角形[ターン]を使用して、耳の切断方法

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

レンダリング:

 

プラクティスと原則は、このリンクを参照することができます。http://www.cnblogs.com/xignzou/p/3721494.html

 コード:

システム使用;
使用System.Collections.Generic;
使用UnityEngine;

名前空間PolygonTool
{

#region耳カット方法三角形の単純なポリゴン

/// <まとめ>
///判定ピット、バンプ、耳軸比較
/// < /要約>
パブリック列挙CompareAxle
{
X、
Y、
Z
}

/// <まとめ>
///ポリゴン処理
/// </要約>
パブリッククラス三角形
{

/// <まとめ>
///凹凸決意時間軸合わせ
/// </要約>
プライベートCompareAxle _compareAxle = CompareAxle.Y;

/// <まとめ>
///ポリゴンの頂点
/// </要約>
プライベートリスト<のVector3> = _polygonVertexs新しい新しいリスト<のVector3>() ;

/// <要約>
///頂点シーケンス
/// </要約>
プライベート一覧<整数> = _vertexsSequence新しい新しいリスト<整数>();

/// <要約>
///ノードマネージャ
/// </要約>
プライベートノードマネージャ_nodeManager =ノードマネージャ新しい新しい();

/// <まとめ>
///初期
/// </要約>
/// <PARAM NAME = "polygonVertexs">ポリゴンの頂点</ PARAM>
公共三角(リスト<のVector3> polygonVertexs)
{
この= polygonVertexs ._polygonVertexs;
_nodeManager.Init(polygonVertexs);
}

/// <まとめ>
配置///比較軸
/// </要約>
/// <PARAM NAME = "compareAxle"> </ PARAM>
公共ボイドSetCompareAxle(CompareAxle compareAxle)
{
this._compareAxle = compareAxle。
}

/// <要約>
///三角形配列の頂点を取得
/// </要約>
公共のINT [] GetTriangles()
{
ながら(_nodeManager.LinkedListLength> = 3)
{
SplitResult SplitPolygonのSR =();
//
IF (SR == NULL)
{
DEBUG.LOG( "NULL");
戻りNULL;
}
}

戻り_vertexsSequence.ToArray();
}

/// <まとめ>
///演算凹状の頂点、頂点突起、耳
/// < /要約>
プライベートSplitResult SplitPolygon()
{
//ピット
一覧<ノード> = _concaveVertexs新しい新たなリストの<node>();
//バンプ
一覧<ノード> = _raisedVertexs新しい新たなリストの<node>();
//耳の
一覧<ノード>_polygonEars =新しいリスト<ノード>();
//起始节点
ノード現ノード= _nodeManager.FirstNode。

#region计算凹顶点、凸顶点

ため(INT i = 0; iは<_nodeManager.LinkedListLength; iは++)
{
するVector3 1 = currentNode.vertex - currentNode.lastNode.vertex。
Vector3 2 = currentNode.nextNode.vertex - currentNode.vertex。
するVector3 crossRes = Vector3.Cross(一つ、二つ)。

IF(_compareAxle == CompareAxle.Y)
{
IF(crossRes.y> 0)
{
_concaveVertexs.Add(現ノード)。
}

{
_raisedVertexs.Add(現ノード)。
}
}

もし(_compareAxle == CompareAxle.X)
{
IF(crossRes.x> 0)
{
_concaveVertexs.Add(現ノード)。
}

{
_raisedVertexs.Add(現ノード)。
}
}

もし(_compareAxle == CompareAxle.Z)
{
IF(crossRes.z> 0)
{
_concaveVertexs.Add(現ノード)。
}

{
_raisedVertexs.Add(現ノード)。
}
}

_polygonEars.Add(現ノード)。
現ノード= currentNode.nextNode。
}

ため(INT i = 0; I <_concaveVertexs.Count; I ++)
{
_polygonEars.Remove(_concaveVertexs [I])。
}
#endregion

#region计算耳朵
一覧<整数> needRemoveIdList =新しいリスト<整数>();
以下のために(INT i = 0; iは<_polygonEars.Count; iは++)
{
ノードearNode = _polygonEars [I]。
ノードcompareNode = earNode.nextNode.nextNode。

(!compareNode = earNode.lastNode)一方
{
BOOL ISIN = ISIN(compareNode.vertex、earNode.lastNode.vertex、earNode.vertex、
earNode.nextNode.vertex)。

(ISINは真==)場合
、{
IF(_polygonEars.Contains(_polygonEars [I]))
{
needRemoveIdList.Add(_polygonEars [I] .ID)。
}
ブレーク;
}
compareNode = compareNode.nextNode。
}
}

のための(int型J = 0; J <needRemoveIdList.Countあり、j ++)
{
(INT i = 0; I <_polygonEars.Count; iは++)のために
{
IF(_polygonEars [I] .ID == needRemoveIdList [J])
{
_polygonEars.RemoveAt(I);
}
}
}

#endregionの

初期の#region印刷結果

DEBUG.LOGは( "バンプ")
のために(; I <_raisedVertexs.Count I ++ I = 0 INT)
{
DEBUG.LOG(_raisedVertexs [Iを] .ID);
}

DEBUG.LOG( "ピット")
のために(INT I = 0; I <_concaveVertexs.Count; Iは++)
{
DEBUG.LOG(_concaveVertexsを[I] .ID);
}

DEBUG.LOG( "耳");
)I ++は、I <_polygonEars.Countを、ため(I = 0 int型
{
[I] .ID)DEBUG.LOG(_polygonEars
}

----------------------- DEBUG.LOG(" -----------------------------------「);
#endregion

//耳が空のポリゴンのための簡単な説明ではありません三角測量の失敗
(_polygonEars場合。== 0)カウント
{
戻りNULLと、
}

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


新しいSplitResult(_raisedVertexs、_concaveVertexs、_polygonEars)を返します。
}

/// <要約>
///判断一点是否在三角形内
/// </要約>
/// <PARAM NAME = "P">一点</ PARAM>
/// <PARAM NAME = "A"> </ PARAM>
/// <PARAM NAME = "B"> </ PARAM>
/// <PARAM NAME = "C"> </ PARAM>
/// <戻る> </戻り>
パブリックブールISIN(するVector3 P 、のVector3、するVector3 B、CするVector3)
{
するVector3 PA = PA。
Vector3 PB = PB;
するVector3 PC = PC。

する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。

isIn2を返します。
}

/// <要約>
///管理多边形构成一个双向链表
/// </要約>
パブリッククラスノードマネージャ
{

プライベートリスト<ノード> _nodeList =新しいリスト<ノード>();

公共int型のLinkedListLength
{
{_nodeList.Countを返します。}
}

パブリック・ノードFirstNode
{
取得{_nodeListを返す[0]。}
}

公共ボイド初期(リスト<のVector3> vertexs)
{

(I 0 = int型のために、私はvertexs.Countを<;
I ++) {
ノードnode =新しいノード(I、vertexs [I])。
_nodeList.Add(ノード)。
}

ため(INT i = 0; I <LinkedListLength; iは++)
{
IF(I == 0)
{
_nodeList [I] .lastNode = _nodeList [LinkedListLength - 1]。
_nodeList [I] .nextNode = _nodeList [1]。
}
そうなら(I == LinkedListLength - 1)
{
_nodeList [I] .lastNode = _nodeList [LinkedListLength - 2]。
_nodeList [I] .nextNode = _nodeList [0]。
}

{
_nodeList [I] .lastNode = _nodeList [I - 1]。
_nodeList [I] .nextNode = _nodeList [I + 1]。
}
}
}

公共ボイドがremoveNode(ノードノード)
{
_nodeList.Remove(ノード)。
node.lastNode.nextNode = node.nextNode。
node.nextNode.lastNode = node.lastNode。
}
}

publicクラスノード
{

公共のint ID;
公共するVector3頂点。
公共ノードlastNode。
公共ノードNEXTNODE。

パブリック・ノード(int型のID、のVector3頂点)
{
this.id = ID。
this.vertex =頂点。
}

パブリック・ノード(int型のID、のVector3頂点、ノードlastNode、ノードNEXTNODE)
{
this.id = ID。
this.vertex =頂点。
this.lastNode = lastNode。
this.nextNode = NEXTNODE。
}
}

publicクラスのSplitResult
{
/// <要約>
///凸顶点
/// </要約>
公共の一覧<ノード> raisedVertexs。

/// <要約>
///凹顶点
/// </要約>
公共一覧<ノード> concaveVertexs。

/// <要約>
///耳朵
/// </要約>
公共一覧<ノード> polygonEars。

公共SplitResult(リストの<node> raisedVertexs、リストの<node> concaveVertexs、リストの<node> polygonEars)
{
this.raisedVertexs = raisedVertexs。
this.concaveVertexs = concaveVertexs。
this.polygonEars = polygonEars。
}
}
}

#endregion
}

 

githubの住所:https://github.com/yiwei151/PolygonTriangulation

 

おすすめ

転載: www.cnblogs.com/mazhenyu/p/11577642.html