/**
	     * クリッピング付きのライントレーサです。
	     * 
	     * @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;
	    }
	    /**
	     * 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);
	    }
Exemple #4
0
        public void extractVisibleFeatures(
            NyARNftFsetFile i_fset, NyARSurfaceTransMatrixSet i_ctrans,
            NyARSurfaceFeatures candidate, NyARSurfaceFeatures candidate2)
        {
            //get work objects
            NyARDoublePoint2d ide2d    = this.__ide2d;
            NyARDoublePoint2d obs2d    = this.__obs2d;
            NyARDoublePoint2d rideal2d = this.__rideal2d;

            //		trans1.setCoefficient(i_cparam.getPerspectiveProjectionMatrix(), trans1);
            candidate.clear();
            candidate2.clear();

            int xsize = this._ref_size.w;
            int ysize = this._ref_size.h;
            INyARCameraDistortionFactor df = this._ref_dist_factor;


            for (int j = 0; j < i_fset.list.Length; j++)
            {
                NyARNftFsetFile.NyAR2FeaturePoints fpoint_ptr = i_fset.list[j];
                for (int k = 0; k < fpoint_ptr.coord.Length; k++)
                {
                    NyARNftFsetFile.NyAR2FeatureCoord coord_ptr = fpoint_ptr.coord[k];

                    //理想画面点を計算
                    i_ctrans.calculate2dPos(coord_ptr.mx, coord_ptr.my, ide2d);
                    df.ideal2Observ(ide2d.x, ide2d.y, obs2d);

                    //観察座標に変換後、画面内にあるか確認
                    if (obs2d.x < 0 || obs2d.x >= xsize)
                    {
                        continue;
                    }
                    if (obs2d.y < 0 || obs2d.y >= ysize)
                    {
                        continue;
                    }
                    //逆変換可能か確認
                    df.observ2Ideal(obs2d, rideal2d);
                    if (ide2d.sqDist(rideal2d) > 1.0)
                    {
                        continue;
                    }


                    //原点からのベクトルを計算
                    //Z軸が+だとつかえないので判定?
                    if (i_ctrans.calculateVd(coord_ptr.mx, coord_ptr.my) > -0.1)
                    {
                        continue;
                    }
                    //				double vd0 = trans1.m00 * coord_ptr.mx+ trans1.m01 * coord_ptr.my+ trans1.m03;
                    //				double vd1 = trans1.m10 * coord_ptr.mx+ trans1.m11 * coord_ptr.my+ trans1.m13;
                    //				double vd2 = trans1.m20 * coord_ptr.mx+ trans1.m21 * coord_ptr.my+ trans1.m23;
                    //				if( (vd0*trans1.m02 + vd1*trans1.m12 + vd2*trans1.m22)/Math.sqrt( vd0*vd0 + vd1*vd1 + vd2*vd2 ) > -0.1 ){
                    //					continue;
                    //				}


                    //撮影箇所のdpiを計算(x,y方向で計算して、大・小の順番で格納?)
                    double dpi = i_ctrans.ar2GetMinResolution(coord_ptr);

                    //dpiによってコレクトする候補を分離
                    if (dpi <= fpoint_ptr.maxdpi && dpi >= fpoint_ptr.mindpi)
                    {
                        NyARSurfaceFeatureItem item = candidate.prePush();
                        if (item == null)
                        {
                            return;
                        }
                        item.ref_feature = coord_ptr;
                        item.scale       = fpoint_ptr.scale;
                        item.x           = obs2d.x;
                        item.y           = obs2d.y;
                    }
                    else if (dpi <= fpoint_ptr.maxdpi * 2 && dpi >= fpoint_ptr.mindpi / 2)
                    {
                        NyARSurfaceFeatureItem item = candidate2.prePush();
                        if (item == null)
                        {
                            return;
                        }
                        item.ref_feature = coord_ptr;
                        item.scale       = fpoint_ptr.scale;
                        item.x           = obs2d.x;
                        item.y           = obs2d.y;
                    }
                }
            }
            return;
        }