/**
         * クリッピング付きのライントレーサです。
         *
         * @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;
        }
Esempio n. 2
0
 /**
  * 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);
        }