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;
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
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 }