//四角形のポリゴン割りをフリップ(割り方を変更)。アルゴリズムのための未チェックの線分を返す private static LDIndexLineList flipTriangles(LDTriangle ta, LDTriangle tb, LDIndexLine l, LDTriangleList triangles) { Debug.Assert(!(ta == tb)); Debug.Assert(ta.isSharedLine(tb)); LDIndexLineList uncheckedLines = new LDIndexLineList(); //指定の線で繋がっていない点を取得 int index1 = ta.getIndexWithoutLine(l); int index2 = tb.getIndexWithoutLine(l); LDTriangle tc = new LDTriangle(index1, index2, l.getIndex1()); LDTriangle td = new LDTriangle(index1, index2, l.getIndex2()); triangles.RemoveAll(triangle => triangle == ta); triangles.RemoveAll(triangle => triangle == tb); triangles.Add(tc); triangles.Add(td); uncheckedLines.Add(new LDIndexLine(index1, l.getIndex1())); uncheckedLines.Add(new LDIndexLine(index2, l.getIndex1())); uncheckedLines.Add(new LDIndexLine(index1, l.getIndex2())); uncheckedLines.Add(new LDIndexLine(index2, l.getIndex2())); return uncheckedLines; }
//四角形のポリゴン割りをフリップ(割り方を変更)。アルゴリズムのための未チェックの線分を返す private static LDIndexLineList flipTriangles(LDTriangle ta, LDTriangle tb, LDIndexLine l, LDTriangleList triangles) { Debug.Assert(!(ta == tb)); Debug.Assert(ta.isSharedLine(tb)); LDIndexLineList uncheckedLines = new LDIndexLineList(); //指定の線で繋がっていない点を取得 int index1 = ta.getIndexWithoutLine(l); int index2 = tb.getIndexWithoutLine(l); LDTriangle tc = new LDTriangle(index1, index2, l.getIndex1()); LDTriangle td = new LDTriangle(index1, index2, l.getIndex2()); triangles.RemoveAll(triangle => triangle == ta); triangles.RemoveAll(triangle => triangle == tb); triangles.Add(tc); triangles.Add(td); uncheckedLines.Add(new LDIndexLine(index1, l.getIndex1())); uncheckedLines.Add(new LDIndexLine(index2, l.getIndex1())); uncheckedLines.Add(new LDIndexLine(index1, l.getIndex2())); uncheckedLines.Add(new LDIndexLine(index2, l.getIndex2())); return(uncheckedLines); }
public void getRelatedLinesTest_simple() { LDTriangleList triangles = simpleTriangle(); LDIndexLineList compare=new LDIndexLineList(); compare.Add(new LDIndexLine(0, 1)); compare.Add(new LDIndexLine(0, 2)); LDIndexLineList result = triangles.getRelatedLines(0); TestUtil.COMPARE(result, compare); }
//特定の三角形から始めて、周辺の四角形をフリップすることで分割形状を最適化する。 private static void optimizePolygonSeparate(LDPointList form, LDTriangle firstTriangle, LDTriangleList triangles) { LDIndexLineList uncheckedLines = new LDIndexLineList(); uncheckedLines.Add(firstTriangle.getLine1()); uncheckedLines.Add(firstTriangle.getLine2()); uncheckedLines.Add(firstTriangle.getLine3()); //A2-2) スタックSが空になるまで以下を繰り返す while (uncheckedLines.size() != 0) { //A2-2-1) スタックSの一番上のedgeをpopする.これを辺ABとする LDIndexLine lineAB = uncheckedLines.Last(); uncheckedLines.RemoveAt(uncheckedLines.Count - 1); //線と接する2つの三角形を取得 LDTriangleList relatedTriangles = triangles.find(lineAB); //外周はチェックしない if (relatedTriangles.size() == 1) { continue; } //三角形がダブってるのは不正。隣接0もなにかおかしい Debug.Assert(relatedTriangles.size() == 2); //A2-2-2) 辺ABを含む2個の三角形をABCとABDとする // if(三角形ABCの外接円内にDが入 る) 辺ABをflipし,辺AD/DB/BC/CAをスタックSにpushする //else 何もしない LDTriangle triangleABC = relatedTriangles.at(0); LDTriangle triangleABD = relatedTriangles.at(1); int index = triangleABD.getIndexWithoutLine(lineAB); Debug.Assert(form.length() > index); LDPoint pd = form[index]; // 外接円を求める LDCircle c = LDCircle.getCircumscribedCirclesOfTriangle(form, triangleABC); double dist = PointUtil.distance(c.center, pd); //誤差の範囲ならフリップしない if (dist < c.radius && Math.Abs(c.radius - dist) > 0.00001) { //不正な辺 uncheckedLines.AddRange(flipTriangles(triangleABC, triangleABD, lineAB, triangles)); } } }
public void constructTest() { List<int> int_list = new List<int>(); int_list.Add(0); int_list.Add(1); int_list.Add(2); int_list.Add(3); // int_list.push_back(0); LDIndexLineList list = new LDIndexLineList(int_list); LDIndexLineList compare = new LDIndexLineList(); compare.Add(new LDIndexLine(0, 1)); compare.Add(new LDIndexLine(1, 2)); compare.Add(new LDIndexLine(2, 3)); compare.Add(new LDIndexLine(3, 0)); TestUtil.COMPARE(list, compare); }
//特定の三角形から始めて、周辺の四角形をフリップすることで分割形状を最適化する。 private static void optimizePolygonSeparate(LDPointList form, LDTriangle firstTriangle, LDTriangleList triangles) { LDIndexLineList uncheckedLines = new LDIndexLineList(); uncheckedLines.Add(firstTriangle.getLine1()); uncheckedLines.Add(firstTriangle.getLine2()); uncheckedLines.Add(firstTriangle.getLine3()); //A2-2) スタックSが空になるまで以下を繰り返す while (uncheckedLines.size() != 0) { //A2-2-1) スタックSの一番上のedgeをpopする.これを辺ABとする LDIndexLine lineAB = uncheckedLines.Last(); uncheckedLines.RemoveAt(uncheckedLines.Count - 1); //線と接する2つの三角形を取得 LDTriangleList relatedTriangles = triangles.find(lineAB); //外周はチェックしない if (relatedTriangles.size() == 1) continue; //三角形がダブってるのは不正。隣接0もなにかおかしい Debug.Assert(relatedTriangles.size() == 2); //A2-2-2) 辺ABを含む2個の三角形をABCとABDとする // if(三角形ABCの外接円内にDが入 る) 辺ABをflipし,辺AD/DB/BC/CAをスタックSにpushする //else 何もしない LDTriangle triangleABC = relatedTriangles.at(0); LDTriangle triangleABD = relatedTriangles.at(1); int index = triangleABD.getIndexWithoutLine(lineAB); Debug.Assert(form.length() > index); LDPoint pd = form[index]; // 外接円を求める LDCircle c = LDCircle.getCircumscribedCirclesOfTriangle(form, triangleABC); double dist = PointUtil.distance(c.center, pd); //誤差の範囲ならフリップしない if (dist < c.radius && Math.Abs(c.radius - dist) > 0.00001) { //不正な辺 uncheckedLines.AddRange(flipTriangles(triangleABC, triangleABD, lineAB, triangles)); } } }
public LDIndexLineList getInnerIndexLines() { LDIndexLineList result=new LDIndexLineList(); for (int row = 0; row < getRowArrayLength(); ++row) { if (row == 0 || row + 1 == getRowArrayLength()) { continue; } for (int col = 0; col < getColumnArrayLength(); ++col) { if (col == 0 || col + 1 == getColumnArrayLength()) { continue; } //その点から左と上 result.Add(getIndexLine(row, col - 1, row, col)); result.Add(getIndexLine(row - 1, col, row, col)); if (row + 2 == getRowArrayLength()) { //最後だけ下も追加 result.Add(new LDIndexLine(getPointIndex(row, col), getPointIndex(row + 1, col))); } if (col + 2 == getColumnArrayLength()) { //最後だけ右も追加 result.Add(new LDIndexLine(getPointIndex(row, col), getPointIndex(row, col + 1))); } } } return result; }
public LDIndexLineList getRelatedLines(int pointIndex) { LDIndexLineList result=new LDIndexLineList(); LDIndexLine line1 = getLine1(); LDIndexLine line2 = getLine2(); LDIndexLine line3 = getLine3(); if (line1.hasIndex(pointIndex)) { result.Add(line1); } if (line2.hasIndex(pointIndex)) { result.Add(line2); } if (line3.hasIndex(pointIndex)) { result.Add(line3); } return result; }
public void toIndexLineListTest_simple() { LDTriangleList triangles = simpleTriangle(); LDIndexLineList compare=new LDIndexLineList(); LDIndexLine line_1=new LDIndexLine(0, 1); LDIndexLine line_2=new LDIndexLine(1, 2); LDIndexLine line_3 = new LDIndexLine(2, 0); compare.Add(line_1); compare.Add(line_2); compare.Add(line_3); LDIndexLineList result = triangles.toIndexLineList(); TestUtil.COMPARE(result, compare); }