OSDN Git Service

git-svn-id: http://svn.sourceforge.jp/svnroot/nyartoolkit/NyARToolkit/trunk@802 7cac0...
[nyartoolkit-and/nyartoolkit-and.git] / lib / src.rpf / jp / nyatla / nyartoolkit / rpf / utils / VecLinearCoordinatesOperator.java
1 package jp.nyatla.nyartoolkit.rpf.utils;\r
2 \r
3 import jp.nyatla.nyartoolkit.core.types.NyARDoublePoint2d;\r
4 import jp.nyatla.nyartoolkit.core.types.NyARLinear;\r
5 import jp.nyatla.nyartoolkit.core.utils.NyARMath;\r
6 \r
7 /**\r
8  * このクラスは、{@link VecLinearCoordinates}を編集する機能を提供します。\r
9  * 将来、{@link VecLinearCoordinates}へ統合するかもしれません。\r
10  */\r
11 public class VecLinearCoordinatesOperator\r
12 {\r
13         /**\r
14          * margeResembleCoordsで使う距離敷居値の値です。\r
15          * 許容する((距離^2)*2)を指定します。\r
16          */\r
17         private final static int _SQ_DIFF_DOT_TH=((10*10) * 2);\r
18         /**\r
19          * margeResembleCoordsで使う角度敷居値の値です。\r
20          * Cos(n)の値です。\r
21          */\r
22         private final static double _SQ_ANG_TH=NyARMath.COS_DEG_10;\r
23 \r
24         //ワーク\r
25         private NyARLinear _l1 = new NyARLinear();\r
26         private NyARLinear _l2 = new NyARLinear();\r
27         private NyARDoublePoint2d _p = new NyARDoublePoint2d();\r
28         \r
29         /**\r
30          * この関数は、リストにある似たベクトルを集めます。\r
31          * 似たベクトルの判定基準は、2線の定義点における直線の法線上での距離の二乗和です。\r
32          * スケール値は単純加算され、ベクトルと位置は加重平均して加算します。\r
33          * 集めたベクトルは、配列の前方に集められ、i_vectorの長さは処理後に減少します。\r
34          * @param i_vector\r
35          * 編集するオブジェクトを指定します。\r
36          */\r
37         public void margeResembleCoords(VecLinearCoordinates i_vector)\r
38         {\r
39                 VecLinearCoordinates.VecLinearCoordinatePoint[] items=i_vector.items;\r
40                 NyARLinear l1 = this._l1;\r
41                 NyARLinear l2 = this._l2;\r
42                 NyARDoublePoint2d p = this._p;\r
43 \r
44 \r
45                 for (int i = i_vector.length - 1; i >= 0; i--) {\r
46                         VecLinearCoordinates.VecLinearCoordinatePoint target1 = items[i];\r
47                         if(target1.scalar==0){\r
48                                 continue;\r
49                         }\r
50                         double rdx=target1.dx;\r
51                         double rdy=target1.dy;\r
52                         double rx=target1.x;\r
53                         double ry=target1.y;\r
54                         l1.setVector(target1);\r
55                         double s_tmp=target1.scalar;\r
56                         target1.dx*=s_tmp;\r
57                         target1.dy*=s_tmp;\r
58                         target1.x*=s_tmp;\r
59                         target1.y*=s_tmp;\r
60                         for (int i2 = i - 1; i2 >= 0; i2--) {\r
61                                 VecLinearCoordinates.VecLinearCoordinatePoint target2 = items[i2];\r
62                                 if(target2.scalar==0){\r
63                                         continue;\r
64                                 }\r
65                                 if (target2.getVecCos(rdx,rdy) >=_SQ_ANG_TH) {\r
66                                         // それぞれの代表点から法線を引いて、相手の直線との交点を計算する。\r
67                                         l2.setVector(target2);\r
68                                         l1.normalLineCrossPos(rx, ry,l2, p);\r
69                                         double wx, wy;\r
70                                         double l = 0;\r
71                                         // 交点間の距離の合計を計算。lに2*dist^2を得る。\r
72                                         wx = (p.x - rx);\r
73                                         wy = (p.y - ry);\r
74                                         l += wx * wx + wy * wy;\r
75                                         l2.normalLineCrossPos(target2.x, target2.y,l2, p);\r
76                                         wx = (p.x - target2.x);\r
77                                         wy = (p.y - target2.y);\r
78                                         l += wx * wx + wy * wy;\r
79                                         // 距離が一定値以下なら、マージ\r
80                                         if (l > _SQ_DIFF_DOT_TH) {\r
81                                                 continue;\r
82                                         }\r
83                                         // 似たようなベクトル発見したら、後方のアイテムに値を統合。\r
84                                         s_tmp= target2.scalar;\r
85                                         target1.x+= target2.x*s_tmp;\r
86                                         target1.y+= target2.y*s_tmp;\r
87                                         target1.dx += target2.dx*s_tmp;\r
88                                         target1.dy += target2.dy*s_tmp;\r
89                                         target1.scalar += s_tmp;\r
90                                         //要らない子を無効化しておく。\r
91                                         target2.scalar=0;\r
92                                 }\r
93                         }\r
94                 }\r
95                 //前方詰め\r
96                 i_vector.removeZeroDistItem();\r
97                 //加重平均解除なう(x,y位置のみ)\r
98                 for(int i=0;i<i_vector.length;i++)\r
99                 {\r
100                         VecLinearCoordinates.VecLinearCoordinatePoint ptr=items[i];\r
101                         double d=1/ptr.scalar;\r
102                         ptr.x*=d;\r
103                         ptr.y*=d;\r
104                         ptr.dx*=d;\r
105                         ptr.dy*=d;\r
106                 }\r
107         }\r
108 }\r