1 package com.github.celldynamics.quimp.plugin.ecmm;
2
3 import java.util.ArrayList;
4
5 import com.github.celldynamics.quimp.Outline;
6 import com.github.celldynamics.quimp.Vert;
7 import com.github.celldynamics.quimp.geom.ExtendedVector2d;
8
9 import ij.IJ;
10 import ij.process.FloatPolygon;
11
12
13
14
15
16
17
18 class Sector {
19
20 private int id;
21 private Vert startO1;
22 private Vert startO2;
23 public Outline migCharges;
24 public Outline tarCharges;
25 FloatPolygon chargesPoly;
26 FloatPolygon innerPoly;
27 FloatPolygon outerPoly;
28 public double lengthO1;
29 public double lengthO2;
30 public int vertSo1;
31 public int vertSo2;
32 public boolean forwardMap;
33
34
35
36 public boolean expansion;
37
38
39
40 public double outerNormal;
41
42
43
44
45
46
47 public Sector(int i) {
48 id = i;
49 }
50
51
52
53
54 public void print() {
55 IJ.log("Sector " + id + "\nMig charges: ");
56 migCharges.print();
57 IJ.log("");
58
59 IJ.log("tar charges: ");
60 tarCharges.print();
61 }
62
63
64
65
66 public void construct() {
67
68 calcLengths();
69
70 double sectorTriArea = ExtendedVector2d.triangleArea(startO1.getPoint(),
71 startO1.getNext().getPoint(), startO2.getNext().getPoint());
72
73 if ((lengthO1 > lengthO2) || ECMp.forceForwardMapping) {
74 forwardMap = true;
75 migCharges = formCharges(startO1);
76 tarCharges = formCharges(startO2);
77 if (sectorTriArea > 0) {
78 expansion = true;
79 outerNormal = -1.;
80 } else {
81 expansion = false;
82 outerNormal = 1.;
83 }
84 } else {
85 forwardMap = false;
86 migCharges = formCharges(startO2);
87 tarCharges = formCharges(startO1);
88 if (sectorTriArea > 0) {
89 expansion = true;
90 outerNormal = 1.;
91
92 } else {
93 expansion = false;
94 outerNormal = -1.;
95 }
96 }
97
98 Vert v = migCharges.getHead();
99 ExtendedVector2d normal;
100 do {
101 normal = new ExtendedVector2d(v.getNormal().getX(), v.getNormal().getY());
102 normal.multiply(outerNormal * ECMp.w);
103 v.getPoint().addVec(normal);
104 v = v.getNext();
105 } while (!v.isHead());
106
107 if (ECMp.chargeDensity != -1) {
108 migCharges.setResolution(ECMp.chargeDensity);
109 tarCharges.setResolution(ECMp.chargeDensity);
110 }
111
112
113 chargesPolygon();
114
115 }
116
117
118
119
120
121
122
123 public void constructWhole(double area1, double area2) {
124 Outline innerCharges;
125 Outline outerCharges;
126
127 calcLengths();
128
129 if (((lengthO1 > lengthO2) || ECMp.forceForwardMapping || ECMp.ANA)
130 && !ECMp.forceBackwardMapping) {
131 forwardMap = true;
132 migCharges = formCharges(startO1);
133 tarCharges = formCharges(startO2);
134 if (area1 > area2) {
135 expansion = false;
136 outerNormal = 1.;
137 innerCharges = tarCharges;
138 outerCharges = migCharges;
139 } else {
140 expansion = true;
141 outerNormal = -1.;
142 innerCharges = migCharges;
143 outerCharges = tarCharges;
144 }
145 } else {
146 forwardMap = false;
147 migCharges = formCharges(startO2);
148 tarCharges = formCharges(startO1);
149 if (area1 > area2) {
150 expansion = true;
151 outerNormal = -1.;
152 innerCharges = migCharges;
153 outerCharges = tarCharges;
154 } else {
155 expansion = false;
156 outerNormal = 1.;
157 innerCharges = tarCharges;
158 outerCharges = migCharges;
159 }
160 }
161
162 Vert v = migCharges.getHead();
163 ExtendedVector2d normal;
164 do {
165 normal = new ExtendedVector2d(v.getNormal().getX(), v.getNormal().getY());
166 normal.multiply(outerNormal * ECMp.w);
167 v.getPoint().addVec(normal);
168 v = v.getNext();
169 } while (!v.isHead());
170
171 if (ECMp.chargeDensity != -1) {
172 migCharges.setResolution(ECMp.chargeDensity);
173 tarCharges.setResolution(ECMp.chargeDensity);
174 }
175
176 outerPoly = ioPolygons(outerCharges);
177 innerPoly = ioPolygons(innerCharges);
178
179 }
180
181 public void setStarts(Vertt" href="../../../../../../com/github/celldynamics/quimp/Vert.html#Vert">Vert a, Vert b) {
182 startO1 = a;
183 startO2 = b;
184 }
185
186 private void calcLengths() {
187 lengthO1 = 0.;
188 vertSo1 = 0;
189 Vert v = startO1;
190 do {
191 lengthO1 += ExtendedVector2d.lengthP2P(v.getPoint(), v.getNext().getPoint());
192 vertSo1++;
193 v = v.getNext();
194 } while (!v.isIntPoint());
195
196 lengthO2 = 0.;
197 vertSo2 = 0;
198 v = startO2;
199 do {
200 lengthO2 += ExtendedVector2d.lengthP2P(v.getPoint(), v.getNext().getPoint());
201 vertSo2++;
202 v = v.getNext();
203 } while (!v.isIntPoint());
204
205
206
207
208 }
209
210 private Outline formCharges(Vert s) {
211
212 Vertamics/quimp/Vert.html#Vert">Vert newV = new Vert(s.getX(), s.getY(), 1);
213 newV.setNormal(s.getNormal().getX(), s.getNormal().getY());
214 newV.setIntPoint(true, -1);
215 Outlineamics/quimp/Outline.html#Outline">Outline o = new Outline(newV);
216
217 s = s.getNext();
218 do {
219 newV = o.insertVert(newV);
220 newV.setX(s.getX());
221 newV.setY(s.getY());
222 newV.setNormal(s.getNormal().getX(), s.getNormal().getY());
223
224 if (s.isIntPoint()) {
225 newV.setIntPoint(true, -1);
226 }
227
228 s = s.getNext();
229 } while (!s.getPrev().isIntPoint());
230
231 return o;
232 }
233
234 public Vert getMigStart() {
235 if (forwardMap) {
236 return startO1;
237 } else {
238 return startO2;
239 }
240 }
241
242 public Vert getTarStart() {
243 if (forwardMap) {
244 return startO2;
245 } else {
246 return startO1;
247 }
248 }
249
250 public Vert/../../../../../com/github/celldynamics/quimp/Vert.html#Vert">Vert addTempCharge(Vert tv) {
251
252
253
254
255 Vert v = migCharges.getHead();
256 double dis = 99999.;
257 double cdis;
258 Vert closest = v;
259 do {
260 cdis = ExtendedVector2d.distPointToSegment(tv.getPoint(), v.getPoint(),
261 v.getNext().getPoint());
262 if (cdis < dis) {
263 closest = v;
264 dis = cdis;
265 }
266 v = v.getNext();
267 } while (!v.isHead());
268
269 Vert newVert = migCharges.insertVert(closest);
270 newVert.setTrackNum(-35);
271 newVert.setX(tv.getX());
272 newVert.setY(tv.getY());
273 ExtendedVector2dom/ExtendedVector2d.html#ExtendedVector2d">ExtendedVector2d normal = new ExtendedVector2d(tv.getNormal().getX(), tv.getNormal().getY());
274 normal.multiply(outerNormal * ECMp.w);
275 newVert.getPoint().addVec(normal);
276 newVert.updateNormale(true);
277 return newVert;
278 }
279
280 public void removeTempCharge(Vert v) {
281 migCharges.removeVert(v);
282 }
283
284 private void chargesPolygon() {
285 ArrayList<ExtendedVector2d> points = new ArrayList<ExtendedVector2d>();
286
287 Vert v = migCharges.getHead();
288 do {
289
290 points.add(v.getPoint());
291 if (v.isIntPoint() && !v.isHead()) {
292 break;
293 }
294 v = v.getNext();
295 } while (!v.isHead());
296
297
298 v = tarCharges.getHead();
299 do {
300 v = v.getNext();
301 } while (!v.isIntPoint());
302
303
304 do {
305 points.add(v.getPoint());
306 v = v.getPrev();
307 } while (!v.getNext().isHead());
308
309
310 float[] x = new float[points.size()];
311 float[] y = new float[points.size()];
312
313 ExtendedVector2d p;
314 for (int i = 0; i < points.size(); i++) {
315 p = (ExtendedVector2d) points.get(i);
316 x[i] = (float) p.getX();
317 y[i] = (float) p.getY();
318 }
319
320 chargesPoly = new FloatPolygon(x, y, x.length);
321 }
322
323 private FloatPolygon ioPolygons(Outline charges) {
324 float[] x = new float[charges.getNumPoints()];
325 float[] y = new float[charges.getNumPoints()];
326
327 int i = 0;
328 Vert v = charges.getHead();
329 do {
330 x[i] = (float) v.getX();
331 y[i] = (float) v.getY();
332 i++;
333 v = v.getNext();
334 } while (!v.isHead());
335
336 return new FloatPolygon(x, y, x.length);
337 }
338
339 public boolean insideCharges(ExtendedVector2d p) {
340 if (ECMp.numINTS > 1) {
341 return chargesPoly.contains(p.getX(), p.getY());
342 } else {
343 if (outerPoly.contains(p.getX(), p.getY())) {
344 if (innerPoly.contains(p.getX(), p.getY())) {
345 return false;
346 } else {
347 return true;
348 }
349 } else {
350 return false;
351 }
352 }
353
354 }
355
356 public void switchMigDirection() {
357 Outline tempO = tarCharges;
358 tarCharges = migCharges;
359 migCharges = tempO;
360 forwardMap = !forwardMap;
361 }
362 }