View Javadoc

1   package org.catacomb.graph.gui;
2   
3   import org.catacomb.be.Position;
4   
5   
6   
7   public abstract class Geom {
8   
9   
10  
11      public final static boolean pointIsInside(double[] xb, double[] yb, int x, int y) {
12          return pointIsInside(xb, yb, (double)x, (double)y);
13      }
14  
15  
16      public final static boolean pointIsInside(double[] xb, double[] yb, double x, double y) {
17          int n = xb.length;
18          int iwn = 0;
19          for (int i = 0; i < n; i++) {
20              int idir = 0;
21              int p = (i + 1) % n;
22              if (yb[i] <= y && yb[p] > y) {
23                  idir = 1;
24              }
25  
26              if (yb[i] > y && yb[p] <= y) {
27                  idir = -1;
28              }
29  
30              if (idir != 0) {
31                  double f = (y - yb[i]) / (yb[p] - yb[i]);
32                  double xc = f * xb[p] + (1. - f) * xb[i];
33                  int isid = (xc > x ? 1 : -1);
34                  iwn += isid * idir;
35              }
36  
37          }
38          return (iwn != 0);
39      }
40  
41  
42  
43      public static double[][] makeLineBoundary(double[] xpts, double[] ypts) {
44          int np = xpts.length;
45          double[][] ret = new double[2][4 + 3 * (np - 2)];
46          double[] xret = ret[0];
47          double[] yret = ret[1];
48  
49          int nr = xret.length - 1;
50  
51  
52  
53          int ic = 0;
54          int iac = 0;
55  
56          double f = 0.15;
57  
58          for (int i = 0; i < np; i++) {
59              int ifa = i - 1;
60              if (ifa < 0) {
61                  ifa = 0;
62              }
63              int ifb = i + 1;
64              if (ifb >= np - 1) {
65                  ifb = np - 1;
66              }
67  
68              double dxa = xpts[ifa] - xpts[ifa + 1];
69              double dya = ypts[ifa] - ypts[ifa + 1];
70              double dxb = xpts[ifb] - xpts[ifb - 1];
71              double dyb = ypts[ifb] - ypts[ifb - 1];
72  
73              double la = Math.sqrt(dxa * dxa + dya * dya) + 1.e-8;
74              double lb = Math.sqrt(dxb * dxb + dyb * dyb) + 2.e-8; // ADHOC
75  
76              double vxa = dxa / la;
77              double vya = dya / la;
78              double vxb = dxb / lb;
79              double vyb = dyb / lb;
80  
81              double cosTheta = vxa * vxb + vya * vyb;
82              double sinHalfTheta = Math.sqrt((1. - cosTheta) / 2.);
83  
84              double vecp = vxa * vyb - vxb * vya;
85  
86              double vxo = vya - vyb;
87              double vyo = -vxa + vxb;
88              double lo = Math.sqrt(vxo * vxo + vyo * vyo);
89              vxo /= lo;
90              vyo /= lo;
91  
92              double fe = 1 / (sinHalfTheta);
93  
94              fe *= f;
95  
96              double xc = xpts[i];
97              double yc = ypts[i];
98  
99              if (i == 0 || i == np - 1) {
100                 xret[ic] = xc +  fe * vxo;
101                 yret[ic] = yc + fe * vyo;
102                 ic += 1;
103 
104                 xret[nr - iac] = xc - fe * vxo;
105                 yret[nr - iac]  = yc - fe * vyo;
106                 iac += 1;
107 
108             } else if (vecp < 0) {
109                 xret[ic] = xc + fe * vxo;
110                 yret[ic] = yc + fe * vyo;
111                 ic += 1;
112 
113                 xret[nr - iac] =xc - f * vya;
114                 yret[nr - iac] = yc + f * vxa;
115                 iac += 1;
116 
117                 xret[nr - iac] = xc + f * vyb;
118                 yret[nr - iac] = yc - f * vxb;
119                 iac += 1;
120 
121             } else {
122                 xret[ic] = xc + f * vya;
123                 yret[ic] = yc - f * vxa;
124                 ic += 1;
125 
126                 xret[ic] = xc - f * vyb;
127                 yret[ic] = yc + f * vxb;
128                 ic += 1;
129 
130                 xret[nr - iac] = xc - fe * vxo;
131                 yret[nr - iac] = yc - fe * vyo;
132                 iac += 1;
133 
134             }
135 
136         }
137 
138         return ret;
139     }
140 
141 
142     public static Position centerOfGravity(double[] xpts, double[] ypts) {
143         int np = xpts.length;
144         double xc = 0.;
145         double yc = 0;
146         for (int i = 0; i < np; i++) {
147             xc += xpts[i];
148             yc += ypts[i];
149         }
150         xc /= np;
151         yc /= np;
152         return new Position(xc, yc);
153     }
154 
155 
156     public static double distanceBetween(Position a, Position b) {
157         double dx = b.getX() - a.getX();
158         double dy = b.getY() - a.getY();
159         double ret = Math.sqrt(dx*dx + dy*dy);
160         return ret;
161     }
162 
163 
164 
165     // TODO - smarter (eg pickable region code)
166     public static double[][] innerPolygon(double[] x, double[] y) {
167         int n = x.length;
168         double[][] ret = new double[2][n];
169         double cx = 0.;
170         double cy = 0.;
171         for (int i = 0; i < n; i++) {
172             cx += x[i];
173             cy += y[i];
174         }
175         cx /= n;
176         cy /= n;
177         for (int i = 0; i < n; i++) {
178             ret[0][i] = cx + 0.9 * (x[i] - cx);
179             ret[1][i] = cy + 0.9 * (y[i] - cy);
180         }
181         return ret;
182     }
183 
184 
185 }