//2点が一定差以内(d以下)にあるかどうか。 public static bool isNearSimple(LDPoint a, LDPoint b, float d) { if (Math.Abs(a.x() - b.x()) > d) return false; if (Math.Abs(a.y() - b.y()) > d) return false; return true; }
//点 p が三角形 t(a,b,c) に含まれるか調べる。 //点 p が三角形 t の内側にある場合 1 を、 // 三角形 t の線上にある場合 -1 を、 // 三角形 t の外側にある場合 0 を返す。 public static int pointInTriangle(LDPoint p1, LDPoint p2, LDPoint p3, LDPoint p) { // 有向線分 (p2,p1), (p2,p3) の外積の z 成分を求める double p12 = LDMathUtil.crossProductValue(p1, p, p2); double p23 = LDMathUtil.crossProductValue(p2, p, p3); double p31 = LDMathUtil.crossProductValue(p3, p, p1); // 三角形の内側 if ((0 < p12) && (0 < p23) && (0 < p31)) { return(1); // 点 p が常に左側にある(時計回り) } if ((0 > p12) && (0 > p23) && (0 > p31)) { return(1); // 点 p が常に右側にある(反時計回り) } // 三角形の線上 if ((0 <= p12) && (0 <= p23) && (0 <= p31)) { return(-1); // 点 p が常に左側にある(時計回り) } if ((0 >= p12) && (0 >= p23) && (0 >= p31)) { return(-1); // 点 p が常に右側にある(反時計回り) } // 三角形の外側 return(0); }
} // static LDTriangleList exec(LDPointList form,LDIndexLineList limitedLines);//TODO ,LDProgress progress private static void triangulationFromPoint(LDPointList form, LDPoint p, LDTriangleList triangles) { // A2-1) piを含む三角形ABCを発見し, この三角形をAB pi, BC pi, CA pi の3個の三角形に分割. // この時, 辺AB, BC, CAをスタックSに積む (最初の一点のときには,super triangleが見つかる) for (int i = 0; i < triangles.length();) { LDTriangle t = triangles[i]; if (!TriangleUtil.containsPoint(t.toPolygon(form), p)) { //対象の三角形の外側なら次へ i++; continue; } // 古い三角形をリストから削除して、分割した三角形を追加 triangles.RemoveAll(item => item == t); int index = form.IndexOf(p); Debug.Assert(index >= 0); triangles.Add(new LDTriangle(index, t.getIndex1(), t.getIndex2())); triangles.Add(new LDTriangle(index, t.getIndex2(), t.getIndex3())); triangles.Add(new LDTriangle(index, t.getIndex3(), t.getIndex1())); //TODO すでにある線分で制限する機能が未移植 // if ( limitLineList.size() != 0 ) // { // flipCheckWithLimit( t.p1, t.p2, t.p3 , pg ); // } // else // { optimizePolygonSeparate(form, t, triangles); // } } }
//点p1 ,p2 ,p3 から三角形が作れるかを判定(3点が一直線上にないか判定) public static bool isTriangle(LDPoint p1, LDPoint p2, LDPoint p3) { if ((p1.x() * p2.y() + p2.x() * p3.y() + p3.x() * p1.y()) - (p1.x() * p3.y() + p2.x() * p1.y() + p3.x() * p2.y()) != 0) { return(true); } return(false); }
//三角形の高さ (底辺p12からp3までの高さ) public static float getTriangleHeight(LDPoint p1, LDPoint p2, LDPoint p3) { LDPoint ab = p2 - p1; LDPoint ac = p3 - p1; float D = Math.Abs(ab.x() * ac.y() - ab.y() * ac.x()); float L = PointUtil.distance(p1, p2); float H = D / L; return(H); }
//2点が一定差以内(d以下)にあるかどうか。 public static bool isNearSimple(LDPoint a, LDPoint b, float d) { if (Math.Abs(a.x() - b.x()) > d) { return(false); } if (Math.Abs(a.y() - b.y()) > d) { return(false); } return(true); }
//特定の三角形から始めて、周辺の四角形をフリップすることで分割形状を最適化する。 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)); } } }
//s1,s2,s3で構成される三角形とt1,t2,t3が相似な三角形であるとき、、s1とs2の線とt1とt1を対応する線分である場合のt3の点を返す public static LDPoint getSimilarityTrianglePoint(LDPoint _s0, LDPoint _s1, LDPoint _s2, LDPoint _t0, LDPoint _t1) { LDVector2 s0 = new LDVector2(_s0); LDVector2 s1 = new LDVector2(_s1); LDVector2 s2 = new LDVector2(_s2); LDVector2 t0 = new LDVector2(_t0); LDVector2 t1 = new LDVector2(_t1); LDVector2 ss2 = s2 + t0 - s0; float angle = (float)LDMathUtil.getAngle(s1 - s0, t1 - t0); LDPoint sss2 = LDMathUtil.rotatePoint(_t0, ss2.toPoint(), -angle); LDVector2 v_s = s1 - s0; LDVector2 v_t = t1 - t0; float scale = v_t.length() / v_s.length(); LDPoint t2 = LDMathUtil.scalePoint(_t0, sss2, scale); return t2; }
public static LDTriangleList exec(LDPointList form)//TODO ,LDProgress progress { //Debug.Assert(form.length() == form.toList().toSet().size()); LDTriangleList result = new LDTriangleList(); int formSize = form.size(); if (formSize < 2) { return(result); } //A1) 点群を包含する十分大きな三角形(super triangle)を追加する LDPolygon hugeTriangle = TriangleUtil.getHugeTriangle(form); int index1 = form.length(); int index2 = index1 + 1; int index3 = index2 + 1; form.Add(hugeTriangle[0]); form.Add(hugeTriangle[1]); form.Add(hugeTriangle[2]); LDTriangle t = new LDTriangle(index1, index2, index3); result.Add(t); //A2) i番目の頂点piを三角形分割図形に追加 for (int i = 0; i < formSize; i++) { LDPoint pi = form[i]; // A2-1) piを含む三角形ABCを発見し, この三角形をAB pi, BC pi, CA pi の3個の三角形に分割. triangulationFromPoint(form, pi, result); } // 最後に、外部三角形の頂点を削除 result.removePoint(index1); result.removePoint(index2); result.removePoint(index3); return(result); } // static LDTriangleList exec(LDPointList form,LDIndexLineList limitedLines);//TODO ,LDProgress progress
//点p1 ,p2 ,targetで構成される三角形で、traget点での角度が鈍角か判定 public static bool isObtuseAngle(LDPoint p1, LDPoint p2, LDPoint target) { LDVector2 a = new LDVector2(p1); LDVector2 b = new LDVector2(p2); LDVector2 c = new LDVector2(target); LDVector2 ab = a - b; LDVector2 bc = b - c; LDVector2 ca = c - a; if (LDVector2.dotProduct(bc, ca) < 0) { return(true); } return(false); }
//s1,s2,s3で構成される三角形とt1,t2,t3が相似な三角形であるとき、、s1とs2の線とt1とt1を対応する線分である場合のt3の点を返す public static LDPoint getSimilarityTrianglePoint(LDPoint _s0, LDPoint _s1, LDPoint _s2, LDPoint _t0, LDPoint _t1) { LDVector2 s0 = new LDVector2(_s0); LDVector2 s1 = new LDVector2(_s1); LDVector2 s2 = new LDVector2(_s2); LDVector2 t0 = new LDVector2(_t0); LDVector2 t1 = new LDVector2(_t1); LDVector2 ss2 = s2 + t0 - s0; float angle = (float)LDMathUtil.getAngle(s1 - s0, t1 - t0); LDPoint sss2 = LDMathUtil.rotatePoint(_t0, ss2.toPoint(), -angle); LDVector2 v_s = s1 - s0; LDVector2 v_t = t1 - t0; float scale = v_t.length() / v_s.length(); LDPoint t2 = LDMathUtil.scalePoint(_t0, sss2, scale); return(t2); }
//点 p が三角形 t(a,b,c) に含まれるか調べる。onLineがtrueなら線上にあっても範囲内にあるという判断 public static bool containsPoint(LDPoint p1, LDPoint p2, LDPoint p3, LDPoint p, bool onLine = false) { int i = pointInTriangle(p1, p2, p3, p); Debug.Assert(i == -1 || i == 0 || i == 1); if (i == 1) { // 三角形の内側 return true; } if (onLine) { if (i == -1) { // 三角形の線上にある場合も含むとみなす return true; } } // 三角形の外側 return false; }
//点 p が三角形 t(a,b,c) に含まれるか調べる。onLineがtrueなら線上にあっても範囲内にあるという判断 public static bool containsPoint(LDPoint p1, LDPoint p2, LDPoint p3, LDPoint p, bool onLine = false) { int i = pointInTriangle(p1, p2, p3, p); Debug.Assert(i == -1 || i == 0 || i == 1); if (i == 1) { // 三角形の内側 return(true); } if (onLine) { if (i == -1) { // 三角形の線上にある場合も含むとみなす return(true); } } // 三角形の外側 return(false); }
//点p1 ,p2 ,p3 で構成される三角形が鈍角三角形か判定する public static bool isObtuseTriangle(LDPoint p1, LDPoint p2, LDPoint p3) { LDVector2 __a = new LDVector2(p1); LDVector2 __b = new LDVector2(p2); LDVector2 __c = new LDVector2(p3); LDVector2 _a = __a - __b; LDVector2 _b = __b - __c; LDVector2 _c = __c - __a; //良く考えたら三角形全部の角度調べるだけでよかった。 if (LDVector2.dotProduct(_a, _b) < 0) { return(true); } if (LDVector2.dotProduct(_a, _c) < 0) { return(true); } if (LDVector2.dotProduct(_b, _c) < 0) { return(true); } return(false); // float a=_a.length(); // float b=_b.length(); // float c=_c.length(); // int longestIndex; // if ( a>=b && a >=c ) // { // longestIndex=0; // } // else if ( b >=a &&b >=c ) // { // longestIndex=1; // } // else // { // longestIndex=2; // } // if ( longestIndex==0 ) // { // if ( a*a<=b*b+c*c ) // { // return false; // } // return true; // } // if ( longestIndex==1 ) // { // if ( b*b<=a*a+c*c ) // { // return false; // } // return true; // } // if ( longestIndex==2 ) // { // if ( c*c<=b*b+a*a ) // { // return false; // } // return true; // } // //ここまでのどこかに引っかかるはず 引っかからなかったらこの関数のどこかにバグがあるはず // Debug.Assert( !" error" ); // return false; }
public static float distance(LDPoint a, LDPoint b) { return new LDVector2(a).distanceToPoint(new LDVector2(b)); }
private static void triangulationFromPoint(LDPointList form, LDPoint p, LDTriangleList triangles) { // A2-1) piを含む三角形ABCを発見し, この三角形をAB pi, BC pi, CA pi の3個の三角形に分割. // この時, 辺AB, BC, CAをスタックSに積む (最初の一点のときには,super triangleが見つかる) for (int i = 0; i < triangles.length();) { LDTriangle t = triangles[i]; if (!TriangleUtil.containsPoint(t.toPolygon(form), p)) { //対象の三角形の外側なら次へ i++; continue; } // 古い三角形をリストから削除して、分割した三角形を追加 triangles.RemoveAll(item => item == t); int index = form.IndexOf(p); Debug.Assert(index >= 0); triangles.Add(new LDTriangle(index, t.getIndex1(), t.getIndex2())); triangles.Add(new LDTriangle(index, t.getIndex2(), t.getIndex3())); triangles.Add(new LDTriangle(index, t.getIndex3(), t.getIndex1())); //TODO すでにある線分で制限する機能が未移植 // if ( limitLineList.size() != 0 ) // { // flipCheckWithLimit( t.p1, t.p2, t.p3 , pg ); // } // else // { optimizePolygonSeparate(form, t, triangles); // } } }
public static bool isHit(LDPoint pt, LDPoint target, float hitRange) { return(new LDVector2(pt).distanceToPoint(new LDVector2(target)) <= hitRange); }
public static LDPoint interporate(LDPoint p1, LDPoint p2, ld_float factor) { var d = (p2 - p1) * factor; return p1 + d; }
//文字列にする public static String toString(LDPoint p) { return "Point (" + p.x() + "," + p.y() + ")"; }
private static uint qHash(LDPoint key) { return((uint)key.x().GetHashCode());//適当。xだけでハッシュ }
//点p1 ,p2 ,p3 から三角形が作れるかを判定(3点が一直線上にないか判定) public static bool isTriangle(LDPoint p1, LDPoint p2, LDPoint p3) { if ((p1.x() * p2.y() + p2.x() * p3.y() + p3.x() * p1.y()) - (p1.x() * p3.y() + p2.x() * p1.y() + p3.x() * p2.y()) != 0) return true; return false; }
//点p1 ,p2 ,p3 で構成される三角形が鈍角三角形か判定する public static bool isObtuseTriangle(LDPoint p1, LDPoint p2, LDPoint p3) { LDVector2 __a=new LDVector2(p1); LDVector2 __b=new LDVector2(p2); LDVector2 __c=new LDVector2(p3); LDVector2 _a = __a - __b; LDVector2 _b = __b - __c; LDVector2 _c = __c - __a; //良く考えたら三角形全部の角度調べるだけでよかった。 if (LDVector2.dotProduct(_a, _b) < 0) return true; if (LDVector2.dotProduct(_a, _c) < 0) return true; if (LDVector2.dotProduct(_b, _c) < 0) return true; return false; // float a=_a.length(); // float b=_b.length(); // float c=_c.length(); // int longestIndex; // if ( a>=b && a >=c ) // { // longestIndex=0; // } // else if ( b >=a &&b >=c ) // { // longestIndex=1; // } // else // { // longestIndex=2; // } // if ( longestIndex==0 ) // { // if ( a*a<=b*b+c*c ) // { // return false; // } // return true; // } // if ( longestIndex==1 ) // { // if ( b*b<=a*a+c*c ) // { // return false; // } // return true; // } // if ( longestIndex==2 ) // { // if ( c*c<=b*b+a*a ) // { // return false; // } // return true; // } // //ここまでのどこかに引っかかるはず 引っかからなかったらこの関数のどこかにバグがあるはず // Debug.Assert( !" error" ); // return false; }
//点p1 ,p2 ,targetで構成される三角形で、traget点での角度が鈍角か判定 public static bool isObtuseAngle(LDPoint p1, LDPoint p2, LDPoint target) { LDVector2 a = new LDVector2(p1); LDVector2 b = new LDVector2(p2); LDVector2 c = new LDVector2(target); LDVector2 ab = a - b; LDVector2 bc = b - c; LDVector2 ca = c - a; if (LDVector2.dotProduct(bc, ca) < 0) return true; return false; }
public static float distance(LDPoint a, LDPoint b) { return(new LDVector2(a).distanceToPoint(new LDVector2(b))); }
public static bool isHit(LDPoint pt, LDPoint target, float hitRange) { return (new LDVector2(pt).distanceToPoint(new LDVector2(target)) <= hitRange); }
public void setPoint(LDPoint pt) { x = pt.x; y = pt.y; }
public static LDPoint interporate(LDPoint p1, LDPoint p2, ld_float factor) { var d = (p2 - p1) * factor; return(p1 + d); }
//三角形の高さ (底辺p12からp3までの高さ) public static float getTriangleHeight(LDPoint p1, LDPoint p2, LDPoint p3) { LDPoint ab = p2 - p1; LDPoint ac = p3 - p1; float D = Math.Abs(ab.x() * ac.y() - ab.y() * ac.x()); float L = PointUtil.distance(p1, p2); float H = D / L; return H; }
public static bool containsPoint(LDPolygon t, LDPoint p, bool onLine = false) { Debug.Assert(t.size() == 3); return(containsPoint(t[0], t[1], t[2], p, onLine)); }
private static uint qHash(LDPoint key) { return (uint)key.x().GetHashCode();//適当。xだけでハッシュ }
//点 p が三角形 t(a,b,c) に含まれるか調べる。 //点 p が三角形 t の内側にある場合 1 を、 // 三角形 t の線上にある場合 -1 を、 // 三角形 t の外側にある場合 0 を返す。 public static int pointInTriangle(LDPoint p1, LDPoint p2, LDPoint p3, LDPoint p) { // 有向線分 (p2,p1), (p2,p3) の外積の z 成分を求める double p12 = LDMathUtil.crossProductValue(p1, p, p2); double p23 = LDMathUtil.crossProductValue(p2, p, p3); double p31 = LDMathUtil.crossProductValue(p3, p, p1); // 三角形の内側 if ((0 < p12) && (0 < p23) && (0 < p31)) return 1; // 点 p が常に左側にある(時計回り) if ((0 > p12) && (0 > p23) && (0 > p31)) return 1; // 点 p が常に右側にある(反時計回り) // 三角形の線上 if ((0 <= p12) && (0 <= p23) && (0 <= p31)) return -1; // 点 p が常に左側にある(時計回り) if ((0 >= p12) && (0 >= p23) && (0 >= p31)) return -1; // 点 p が常に右側にある(反時計回り) // 三角形の外側 return 0; }
//文字列にする public static String toString(LDPoint p) { return("Point (" + p.x() + "," + p.y() + ")"); }
public static bool containsPoint(LDPolygon t, LDPoint p, bool onLine = false) { Debug.Assert(t.size() == 3); return containsPoint(t[0], t[1], t[2], p, onLine); }
public LDPoint(LDPoint pt) { x = pt.x; y = pt.y; }