/** * p1->p2とp2->p3の作る角のsin値の絶対値を得ます。 * @param p1 * @param p2 * @param p3 * @return */ public static double getAbsSin(NyARDoublePoint2d p1, NyARDoublePoint2d p2, NyARDoublePoint2d p3) { double cp = NyARDoublePoint2d.crossProduct3Point(p1, p2, p3); cp /= (Math.Sqrt(p1.sqDist(p2)) * Math.Sqrt(p2.sqDist(p3))); return(cp > 0?cp:-cp); }
public bool traceLine(NyARDoublePoint2d i_pos1, NyARDoublePoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord) { NyARIntCoordinates coord = this._coord_buf; NyARIntSize base_s = this._ref_base_raster.getSize(); // (i_area*2)の矩形が範囲内に収まるように線を引く // 移動量 // 点間距離を計算 int dist = (int)Math.Sqrt(i_pos1.sqDist(i_pos2)); // 最低AREA*2以上の大きさが無いなら、ラインのトレースは不可能。 if (dist < 4) { return(false); } // dist最大数の決定 if (dist > 12) { dist = 12; } // サンプリングサイズを決定(移動速度とサイズから) int s = i_edge * 2 + 1; int dx = (int)(i_pos2.x - i_pos1.x); int dy = (int)(i_pos2.y - i_pos1.y); int r = base_s.w - s; int b = base_s.h - s; // 最大24点を定義して、そのうち両端の2個を除いた点を使用する。 for (int i = 1; i < dist - 1; i++) { int x = (int)(i * dx / dist + i_pos1.x - i_edge); int y = (int)(i * dy / dist + i_pos1.y - i_edge); // limit coord.items[i - 1].x = x < 0 ? 0 : (x >= r ? r : x); coord.items[i - 1].y = y < 0 ? 0 : (y >= b ? b : y); } coord.length = dist - 2; // 点数は10点程度を得る。 return(traceConture(coord, 1, s, o_coord)); }
/** * クリッピング付きのライントレーサです。 * * @param i_pos1 * @param i_pos2 * @param i_edge * @param o_coord * @return * @throws NyARException */ public bool traceLineWithClip(NyARDoublePoint2d i_pos1, NyARDoublePoint2d i_pos2, int i_edge, VecLinearCoordinates o_coord) { NyARIntSize s = this._ref_base_raster.getSize(); bool is_p1_inside_area, is_p2_inside_area; NyARIntPoint2d[] pt = this.__pt; // 線分が範囲内にあるかを確認 is_p1_inside_area = s.isInnerPoint(i_pos1); is_p2_inside_area = s.isInnerPoint(i_pos2); // 個数で分岐 if (is_p1_inside_area && is_p2_inside_area) { // 2ならクリッピング必要なし。 if (!this.traceLine(i_pos1, i_pos2, i_edge, o_coord)) { return(false); } return(true); } // 1,0個の場合は、線分を再定義 if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2)) { return(false); } if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt)) { return(false); } if (is_p1_inside_area != is_p2_inside_area) { // 1ならクリッピング後に、外に出ていた点に近い輪郭交点を得る。 if (is_p1_inside_area) { // p2が範囲外 pt[(i_pos2.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos1); } else { // p1が範囲外 pt[(i_pos1.sqDist(pt[0]) < i_pos2.sqDist(pt[1])) ? 1 : 0].setValue(i_pos2); } } else { // 0ならクリッピングして得られた2点を使う。 if (!this.__temp_l.makeLinearWithNormalize(i_pos1, i_pos2)) { return(false); } if (!this.__temp_l.makeSegmentLine(s.w, s.h, pt)) { return(false); } } if (!this.traceLine(pt[0], pt[1], i_edge, o_coord)) { return(false); } return(true); }