1 package org.opentrafficsim.core.geometry;
2
3 import java.awt.geom.Line2D;
4 import java.awt.geom.Path2D;
5 import java.awt.geom.PathIterator;
6 import java.awt.geom.Point2D;
7 import java.util.ArrayList;
8 import java.util.List;
9 import java.util.SortedMap;
10 import java.util.TreeMap;
11
12 import org.opentrafficsim.core.network.NetworkException;
13
14
15
16
17
18
19
20
21
22
23
24 public final class OTSBufferingAV
25 {
26
27 private OTSBufferingAV()
28 {
29 }
30
31
32
33
34
35
36 public static void main(final String[] args) throws NetworkException, OTSGeometryException
37 {
38 OTSLine3D line0 =
39 new OTSLine3D(new OTSPoint3D(10, 10, 0), new OTSPoint3D(10, 8, 0), new OTSPoint3D(0, 6, 0), new OTSPoint3D(10,
40 4, 0), new OTSPoint3D(10, 0, 0));
41 OTSLine3D line1 =
42 new OTSLine3D(new OTSPoint3D(10, 10, 0), new OTSPoint3D(9.999, 8, 0), new OTSPoint3D(9.996, 7.99, 0),
43 new OTSPoint3D(9.999, 7.98, 0), new OTSPoint3D(10.03, 7.95, 0), new OTSPoint3D(10.01, 7.94, 0),
44 new OTSPoint3D(10.0, 7.94, 0), new OTSPoint3D(10, 6, 0), new OTSPoint3D(10, 2, 0));
45 OTSLine3D line2 =
46 new OTSLine3D(new OTSPoint3D(10, 10, 0), new OTSPoint3D(9.999, 8, 0), new OTSPoint3D(9.996, 7.99, 0),
47 new OTSPoint3D(9.999, 7.98, 0), new OTSPoint3D(10.03, 7.95, 0), new OTSPoint3D(10.01, 7.94, 0),
48 new OTSPoint3D(10.0, 7.94, 0), new OTSPoint3D(10, 6, 0), new OTSPoint3D(9.999, 6, 0), new OTSPoint3D(
49 9.996, 5.99, 0), new OTSPoint3D(9.999, 5.98, 0), new OTSPoint3D(10.03, 5.95, 0),
50 new OTSPoint3D(10.01, 5.94, 0), new OTSPoint3D(10.0, 5.94, 0), new OTSPoint3D(10, 2, 0));
51 OTSLine3D line3 =
52 new OTSLine3D(new OTSPoint3D(-115.3680561332295, -548.0151713307242, 0.0), new OTSPoint3D(-121.1405898342023,
53 -546.9967679699366, 0.0), new OTSPoint3D(-133.3954402170488, -545.1596234831587, 0.0), new OTSPoint3D(
54 -133.49497466097273, -545.1499853728319, 0.0), new OTSPoint3D(-133.59452107477017, -545.1404716880575,
55 0.0), new OTSPoint3D(-133.69407930289987, -545.1310824437005, 0.0), new OTSPoint3D(-133.7936491898021,
56 -545.1218176544314, 0.0), new OTSPoint3D(-133.89323057989893, -545.1126773347269, 0.0), new OTSPoint3D(
57 -133.99282331759446, -545.1036614988684, 0.0), new OTSPoint3D(-134.09242724727505, -545.0947701609432,
58 0.0), new OTSPoint3D(-134.19204221330963, -545.086003334844, 0.0), new OTSPoint3D(-134.29166806004977,
59 -545.077361034269, 0.0), new OTSPoint3D(-134.39130463183014, -545.0688432727218, 0.0), new OTSPoint3D(
60 -134.4909517729686, -545.0604500635113, 0.0), new OTSPoint3D(-134.59060932776654, -545.0521814197522,
61 0.0), new OTSPoint3D(-134.690277140509, -545.0440373543638, 0.0), new OTSPoint3D(-134.78995505546513,
62 -545.0360178800717, 0.0), new OTSPoint3D(-134.88964291688814, -545.0281230094058, 0.0), new OTSPoint3D(
63 -134.98934056901578, -545.0203527547022, 0.0), new OTSPoint3D(-135.08904785607044, -545.0127071281019,
64 0.0), new OTSPoint3D(-135.18876462225958, -545.005186141551, 0.0), new OTSPoint3D(-135.28849071177578,
65 -544.9977898068012, 0.0), new OTSPoint3D(-135.38822596879697, -544.9905181354092, 0.0), new OTSPoint3D(
66 -135.4879702374869, -544.9833711387371, 0.0), new OTSPoint3D(-135.58772336199513, -544.9763488279517,
67 0.0), new OTSPoint3D(-135.68748518645745, -544.9694512140259, 0.0), new OTSPoint3D(-135.78725555499602,
68 -544.9626783077368, 0.0), new OTSPoint3D(-135.88703431171965, -544.9560301196673, 0.0), new OTSPoint3D(
69 -135.98682130072405, -544.9495066602052, 0.0), new OTSPoint3D(-136.08661636609207, -544.9431079395432,
70 0.0), new OTSPoint3D(-136.18641935189396, -544.9368339676794, 0.0), new OTSPoint3D(-136.28623010218757,
71 -544.9306847544171, 0.0), new OTSPoint3D(-136.38604846101862, -544.9246603093641, 0.0), new OTSPoint3D(
72 -136.48587427242094, -544.9187606419338, 0.0), new OTSPoint3D(-136.58570738041672, -544.9129857613443,
73 0.0), new OTSPoint3D(-136.68554762901675, -544.907335676619, 0.0), new OTSPoint3D(-136.78539486222067,
74 -544.9018103965861, 0.0), new OTSPoint3D(-136.88524892401722, -544.8964099298789, 0.0), new OTSPoint3D(
75 -136.98510965838437, -544.8911342849353, 0.0), new OTSPoint3D(-137.08497690928982, -544.8859834699989,
76 0.0), new OTSPoint3D(-137.18485052069096, -544.8809574931176, 0.0), new OTSPoint3D(-137.28473033653535,
77 -544.8760563621447, 0.0), new OTSPoint3D(-137.38461620076075, -544.8712800847381, 0.0), new OTSPoint3D(
78 -137.48450795729553, -544.8666286683607, 0.0), new OTSPoint3D(-137.58440545005882, -544.8621021202804,
79 0.0), new OTSPoint3D(-137.68430852296086, -544.8577004475699, 0.0), new OTSPoint3D(-137.78421701990308,
80 -544.8534236571068, 0.0), new OTSPoint3D(-137.8841307847785, -544.8492717555735, 0.0), new OTSPoint3D(
81 -137.98404966147183, -544.8452447494575, 0.0), new OTSPoint3D(-138.08397349385993, -544.841342645051,
82 0.0), new OTSPoint3D(-138.18390212581176, -544.837565448451, 0.0), new OTSPoint3D(-138.28383540118887,
83 -544.8339131655592, 0.0), new OTSPoint3D(-138.38377316384558, -544.8303858020826, 0.0), new OTSPoint3D(
84 -138.4837152576291, -544.8269833635323, 0.0), new OTSPoint3D(-138.58366152637993, -544.8237058552252,
85 0.0), new OTSPoint3D(-138.68361181393206, -544.8205532822818, 0.0), new OTSPoint3D(-138.78356596411322,
86 -544.8175256496284, 0.0), new OTSPoint3D(-138.883523820745, -544.8146229619954, 0.0), new OTSPoint3D(
87 -138.98348522764337, -544.8118452239183, 0.0), new OTSPoint3D(-139.08345002861856, -544.8091924397376,
88 0.0), new OTSPoint3D(-139.18341806747563, -544.806664613598, 0.0), new OTSPoint3D(-139.28338918801452,
89 -544.8042617494492, 0.0), new OTSPoint3D(-139.38336323403036, -544.8019838510459, 0.0), new OTSPoint3D(
90 -139.48334004931382, -544.7998309219471, 0.0), new OTSPoint3D(-139.58331947765103, -544.7978029655169,
91 0.0), new OTSPoint3D(-139.6833013628242, -544.7958999849238, 0.0), new OTSPoint3D(-139.78328554861167,
92 -544.7941219831416, 0.0), new OTSPoint3D(-139.88327187878815, -544.7924689629479, 0.0), new OTSPoint3D(
93 -139.98326019712502, -544.7909409269257, 0.0), new OTSPoint3D(-140.08325034739056, -544.7895378774629,
94 0.0), new OTSPoint3D(-140.18324217335015, -544.7882598167514, 0.0), new OTSPoint3D(-140.28323551876667,
95 -544.7871067467883, 0.0), new OTSPoint3D(-140.38323022740042, -544.7860786693752, 0.0), new OTSPoint3D(
96 -140.48322614300977, -544.7851755861186, 0.0), new OTSPoint3D(-140.58322310935108, -544.7843974984295,
97 0.0), new OTSPoint3D(-140.68322097017915, -544.7837444075236, 0.0), new OTSPoint3D(-140.7832195692473,
98 -544.7832163144215, 0.0), new OTSPoint3D(-140.88321875030778, -544.7828132199481, 0.0), new OTSPoint3D(
99 -140.98321835711187, -544.7825351247336, 0.0), new OTSPoint3D(-141.0832182334102, -544.7823820292122,
100 0.0), new OTSPoint3D(-141.18321822295303, -544.7823539336232, 0.0), new OTSPoint3D(-141.28321816949028,
101 -544.7824508380106, 0.0), new OTSPoint3D(-141.38321791677217, -544.7826727422229, 0.0), new OTSPoint3D(
102 -141.48321730854906, -544.7830196459133, 0.0), new OTSPoint3D(-141.58321618857192, -544.7834915485399,
103 0.0), new OTSPoint3D(-141.68321440059256, -544.7840884493653, 0.0), new OTSPoint3D(-141.7832117883638,
104 -544.7848103474569, 0.0), new OTSPoint3D(-141.88320819563967, -544.7856572416866, 0.0), new OTSPoint3D(
105 -141.98320346617584, -544.7866291307313, 0.0), new OTSPoint3D(-142.08319744372974, -544.7877260130723,
106 0.0), new OTSPoint3D(-142.1831899720608, -544.7889478869957, 0.0), new OTSPoint3D(-142.28318089493067,
107 -544.7902947505925, 0.0), new OTSPoint3D(-142.3831700561036, -544.7917666017579, 0.0), new OTSPoint3D(
108 -142.48315729934654, -544.7933634381925, 0.0), new OTSPoint3D(-142.58314246842943, -544.7950852574011,
109 0.0), new OTSPoint3D(-142.68312540712546, -544.7969320566932, 0.0), new OTSPoint3D(-142.78310595921133,
110 -544.7989038331833, 0.0), new OTSPoint3D(-142.8830839684674, -544.8010005837906, 0.0), new OTSPoint3D(
111 -142.9830592786781, -544.8032223052389, 0.0), new OTSPoint3D(-143.08303173363203, -544.8055689940566,
112 0.0), new OTSPoint3D(-143.1830011771222, -544.8080406465771, 0.0), new OTSPoint3D(-143.28296745294642,
113 -544.8106372589384, 0.0), new OTSPoint3D(-143.3829304049074, -544.8133588270834, 0.0), new OTSPoint3D(
114 -143.48288987681303, -544.8162053467596, 0.0), new OTSPoint3D(-143.58284571247668, -544.8191768135193,
115 0.0), new OTSPoint3D(-143.68279775571733, -544.8222732227196, 0.0), new OTSPoint3D(-143.78274585036,
116 -544.8254945695223, 0.0), new OTSPoint3D(-143.88268984023574, -544.8288408488941, 0.0), new OTSPoint3D(
117 -143.98262956918217, -544.8323120556064, 0.0), new OTSPoint3D(-144.0825648810434, -544.8359081842356,
118 0.0), new OTSPoint3D(-144.18249561967056, -544.8396292291625, 0.0), new OTSPoint3D(-144.2824216289219,
119 -544.8434751845731, 0.0), new OTSPoint3D(-144.38234275266305, -544.847446044458, 0.0), new OTSPoint3D(
120 -144.48225883476726, -544.8515418026129, 0.0), new OTSPoint3D(-144.58216971911568, -544.8557624526381,
121 0.0), new OTSPoint3D(-144.68207524959763, -544.8601079879389, 0.0), new OTSPoint3D(-144.7819752701106,
122 -544.8645784017253, 0.0), new OTSPoint3D(-144.88186962456095, -544.8691736870123, 0.0), new OTSPoint3D(
123 -144.98175815686372, -544.8738938366197, 0.0), new OTSPoint3D(-145.0816407109431, -544.8787388431724,
124 0.0), new OTSPoint3D(-145.18151713073263, -544.8837086991001, 0.0), new OTSPoint3D(-145.2813872601755,
125 -544.8888033966373, 0.0), new OTSPoint3D(-145.3812509432245, -544.8940229278235, 0.0), new OTSPoint3D(
126 -145.48110802384275, -544.8993672845032, 0.0), new OTSPoint3D(-145.58095834600357, -544.9048364583259,
127 0.0), new OTSPoint3D(-145.68080175369082, -544.9104304407462, 0.0), new OTSPoint3D(-145.7806380908992,
128 -544.9161492230231, 0.0), new OTSPoint3D(-145.8804672016345, -544.9219927962213, 0.0), new OTSPoint3D(
129 -145.98028892991368, -544.9279611512101, 0.0), new OTSPoint3D(-146.0801031197654, -544.934054278664,
130 0.0), new OTSPoint3D(-146.17990961522992, -544.9402721690625, 0.0), new OTSPoint3D(-146.2797082603597,
131 -544.9466148126901, 0.0), new OTSPoint3D(-146.37949889921927, -544.9530821996364, 0.0), new OTSPoint3D(
132 -146.47928137588588, -544.9596743197961, 0.0), new OTSPoint3D(-146.57905553444937, -544.9663911628691,
133 0.0), new OTSPoint3D(-146.67882121901263, -544.9732327183604, 0.0), new OTSPoint3D(-146.77857827369186,
134 -544.9801989755798, 0.0), new OTSPoint3D(-146.87832654261663, -544.9872899236427, 0.0), new OTSPoint3D(
135 -146.97806586993033, -544.9945055514696, 0.0), new OTSPoint3D(-147.0777960997902, -545.001845847786,
136 0.0), new OTSPoint3D(-147.17751707636785, -545.0093108011225, 0.0), new OTSPoint3D(-147.27722864384927,
137 -545.0169003998153, 0.0), new OTSPoint3D(-147.37693064643514, -545.0246146320056, 0.0), new OTSPoint3D(
138 -147.47662292834113, -545.0324534856402, 0.0), new OTSPoint3D(-147.57630533379802, -545.0404169484702,
139 0.0), new OTSPoint3D(-147.67597770705208, -545.0485050080534, 0.0), new OTSPoint3D(-147.7756398923653,
140 -545.0567176517519, 0.0), new OTSPoint3D(-147.87529173401546, -545.0650548667334, 0.0), new OTSPoint3D(
141 -147.97493307629662, -545.0735166399711, 0.0), new OTSPoint3D(-148.07456376351922, -545.0821029582435,
142 0.0), new OTSPoint3D(-148.1741836400103, -545.0908138081345, 0.0), new OTSPoint3D(-148.27379255011385,
143 -545.0996491760332, 0.0), new OTSPoint3D(-148.37339033819092, -545.1086090481344, 0.0), new OTSPoint3D(
144 -148.47297684862002, -545.1176934104385, 0.0), new OTSPoint3D(-148.57255192579726, -545.1269022487511,
145 0.0), new OTSPoint3D(-148.67211541413658, -545.1362355486832, 0.0), new OTSPoint3D(-148.77166715807007,
146 -545.1456932956519, 0.0), new OTSPoint3D(-148.87120700204815, -545.1552754748791, 0.0), new OTSPoint3D(
147 -148.9707347905398, -545.1649820713927, 0.0), new OTSPoint3D(-149.0702503680329, -545.1748130700264,
148 0.0), new OTSPoint3D(-149.16975357903436, -545.1847684554191, 0.0), new OTSPoint3D(-149.2692442680705,
149 -545.1948482120155, 0.0), new OTSPoint3D(-149.368722279687, -545.205052324066, 0.0), new OTSPoint3D(
150 -149.46818745844962, -545.2153807756266, 0.0), new OTSPoint3D(-149.567639648944, -545.2258335505592,
151 0.0), new OTSPoint3D(-149.6670786957761, -545.2364106325315, 0.0), new OTSPoint3D(-149.76650444357242,
152 -545.2471120050163, 0.0), new OTSPoint3D(-149.86591673698024, -545.2579376512932, 0.0), new OTSPoint3D(
153 -149.96531542066793, -545.268887554447, 0.0), new OTSPoint3D(-150.06470033932501, -545.2799616973684,
154 0.0), new OTSPoint3D(-150.1640713376626, -545.2911600627541, 0.0), new OTSPoint3D(-150.26342826041352,
155 -545.3024826331067, 0.0), new OTSPoint3D(-150.3627709523326, -545.3139293907345, 0.0), new OTSPoint3D(
156 -150.46209925819687, -545.3255003177524, 0.0), new OTSPoint3D(-150.56141302280594, -545.3371953960801,
157 0.0), new OTSPoint3D(-150.66071209098203, -545.3490146074447, 0.0), new OTSPoint3D(-150.7599963075704,
158 -545.3609579333784, 0.0), new OTSPoint3D(-150.85926551743938, -545.3730253552196, 0.0), new OTSPoint3D(
159 -150.95851956548103, -545.3852168541134, 0.0), new OTSPoint3D(-151.05775829661076, -545.3975324110104,
160 0.0), new OTSPoint3D(-151.15698155576814, -545.4099720066673, 0.0), new OTSPoint3D(-151.25618918791685,
161 -545.4225356216475, 0.0), new OTSPoint3D(-151.35538103804492, -545.4352232363202, 0.0), new OTSPoint3D(
162 -151.4545569511652, -545.448034830861, 0.0),
163 new OTSPoint3D(-151.55371677231528, -545.460970385252, 0.0), new OTSPoint3D(-151.652860346558,
164 -545.4740298792813, 0.0), new OTSPoint3D(-151.75198751898154, -545.4872132925433, 0.0),
165 new OTSPoint3D(-151.85109813469967, -545.5005206044389, 0.0), new OTSPoint3D(-151.95019203885212,
166 -545.5139517941758, 0.0), new OTSPoint3D(-152.04926907660465, -545.5275068407674, 0.0),
167 new OTSPoint3D(-152.14832909314944, -545.5411857230341, 0.0), new OTSPoint3D(-152.24737193370524,
168 -545.5549884196025, 0.0), new OTSPoint3D(-152.3463974435176, -545.5689149089062, 0.0),
169 new OTSPoint3D(-152.4454054678592, -545.5829651691847, 0.0), new OTSPoint3D(-152.54439585203,
170 -545.5971391784847, 0.0), new OTSPoint3D(-152.64336844135755, -545.6114369146592, 0.0),
171 new OTSPoint3D(-152.74232308119724, -545.625858355368, 0.0), new OTSPoint3D(-152.84125961693243,
172 -545.6404034780777, 0.0), new OTSPoint3D(-152.9401778939748, -545.6550722600615, 0.0),
173 new OTSPoint3D(-153.03907775776457, -545.6698646783994, 0.0), new OTSPoint3D(-153.13795905377074,
174 -545.6847807099783, 0.0), new OTSPoint3D(-153.23682162749128, -545.6998203314919, 0.0),
175 new OTSPoint3D(-153.33566532445343, -545.7149835194407, 0.0), new OTSPoint3D(-153.434489990214,
176 -545.7302702501322, 0.0), new OTSPoint3D(-153.53329547035938, -545.7456804996812, 0.0),
177 new OTSPoint3D(-153.63208161050608, -545.7612142440088, 0.0), new OTSPoint3D(-153.73084825630076,
178 -545.7768714588436, 0.0), new OTSPoint3D(-153.82959525342056, -545.7926521197215, 0.0),
179 new OTSPoint3D(-153.92832244757332, -545.808556201985, 0.0), new OTSPoint3D(-154.02702968449785,
180 -545.8245836807839, 0.0), new OTSPoint3D(-154.12571680996405, -545.8407345310753, 0.0),
181 new OTSPoint3D(-154.22438366977332, -545.8570087276237, 0.0), new OTSPoint3D(-154.32303010975875,
182 -545.8734062450004, 0.0), new OTSPoint3D(-154.42165597578528, -545.8899270575845, 0.0),
183 new OTSPoint3D(-154.52026111375, -545.9065711395622, 0.0), new OTSPoint3D(-154.6188453695824,
184 -545.9233384649269, 0.0), new OTSPoint3D(-154.71740858924463, -545.94022900748, 0.0),
185 new OTSPoint3D(-154.81595061873168, -545.9572427408298, 0.0), new OTSPoint3D(-154.91447130407158,
186 -545.9743796383924, 0.0), new OTSPoint3D(-155.01297049132586, -545.9916396733913, 0.0),
187 new OTSPoint3D(-155.11144802658953, -546.0090228188579, 0.0), new OTSPoint3D(-155.20990375599146,
188 -546.026529047631, 0.0), new OTSPoint3D(-155.3083375256946, -546.044158332357, 0.0),
189 new OTSPoint3D(-155.4067491818962, -546.0619106454902, 0.0), new OTSPoint3D(-155.50513857082805,
190 -546.0797859592926, 0.0), new OTSPoint3D(-155.60350553875676, -546.0977842458342, 0.0),
191 new OTSPoint3D(-155.701849931984, -546.1159054769923, 0.0), new OTSPoint3D(-155.8001715968466,
192 -546.1341496244529, 0.0), new OTSPoint3D(-155.89847037971708, -546.1525166597092, 0.0),
193 new OTSPoint3D(-155.99674612700352, -546.171006554063, 0.0), new OTSPoint3D(-156.0949986851501,
194 -546.1896192786236, 0.0), new OTSPoint3D(-156.19322790063725, -546.2083548043087, 0.0),
195 new OTSPoint3D(-156.29143361998186, -546.227213101844, 0.0), new OTSPoint3D(-156.38961568973744,
196 -546.2461941417636, 0.0), new OTSPoint3D(-156.4877739564946, -546.2652978944094, 0.0),
197 new OTSPoint3D(-156.585908266881, -546.2845243299319, 0.0), new OTSPoint3D(-156.68401846756186,
198 -546.3038734182899, 0.0), new OTSPoint3D(-156.78210440523998, -546.3233451292501, 0.0),
199 new OTSPoint3D(-156.88016592665613, -546.3429394323884, 0.0), new OTSPoint3D(-156.97820287858914,
200 -546.3626562970885, 0.0), new OTSPoint3D(-157.07621510785637, -546.3824956925428, 0.0),
201 new OTSPoint3D(-157.17420246131368, -546.4024575877521, 0.0), new OTSPoint3D(-157.27216478585586,
202 -546.4225419515262, 0.0), new OTSPoint3D(-157.37010192841683, -546.4427487524832, 0.0),
203 new OTSPoint3D(-157.46801373596978, -546.46307795905, 0.0), new OTSPoint3D(-157.56590005552755,
204 -546.4835295394621, 0.0), new OTSPoint3D(-157.66376073414278, -546.504103461764, 0.0),
205 new OTSPoint3D(-157.76159561890822, -546.524799693809, 0.0), new OTSPoint3D(-157.8594045569568,
206 -546.5456182032591, 0.0), new OTSPoint3D(-157.95718739546214, -546.5665589575855, 0.0),
207 new OTSPoint3D(-158.05494398163856, -546.5876219240682, 0.0), new OTSPoint3D(-158.15267416274142,
208 -546.6088070697964, 0.0), new OTSPoint3D(-158.2503777860673, -546.6301143616682, 0.0),
209 new OTSPoint3D(-158.34805469895434, -546.6515437663911, 0.0), new OTSPoint3D(-158.44570474878236,
210 -546.6730952504817, 0.0), new OTSPoint3D(-158.54332778297322, -546.6947687802656, 0.0),
211 new OTSPoint3D(-158.6409236489909, -546.716564321878, 0.0), new OTSPoint3D(-158.7384921943419,
212 -546.7384818412634, 0.0), new OTSPoint3D(-158.83603326657538, -546.7605213041757, 0.0),
213 new OTSPoint3D(-158.93354671328345, -546.7826826761781, 0.0), new OTSPoint3D(-159.03103238210136,
214 -546.8049659226436, 0.0), new OTSPoint3D(-159.1284901207078, -546.8273710087547, 0.0),
215 new OTSPoint3D(-159.225919776825, -546.8498978995033, 0.0), new OTSPoint3D(-159.32332119821922,
216 -546.8725465596913, 0.0), new OTSPoint3D(-159.4206942327007, -546.8953169539299, 0.0),
217 new OTSPoint3D(-159.51803872812414, -546.9182090466406, 0.0), new OTSPoint3D(-159.61535453238878,
218 -546.9412228020545, 0.0), new OTSPoint3D(-159.71264149343864, -546.9643581842125, 0.0),
219 new OTSPoint3D(-159.80989945926294, -546.9876151569657, 0.0), new OTSPoint3D(-159.90712827789608,
220 -547.010993683975, 0.0), new OTSPoint3D(-160.00432779741806, -547.0344937287114, 0.0),
221 new OTSPoint3D(-160.10149786595466, -547.0581152544562, 0.0), new OTSPoint3D(-160.19863833167767,
222 -547.0818582243007, 0.0), new OTSPoint3D(-160.2957490428051, -547.1057226011466, 0.0),
223 new OTSPoint3D(-160.39282984760155, -547.1297083477057, 0.0), new OTSPoint3D(-160.4898805943782,
224 -547.1538154265004, 0.0), new OTSPoint3D(-160.58690113149333, -547.1780437998632, 0.0),
225 new OTSPoint3D(-160.68389130735238, -547.2023934299375, 0.0), new OTSPoint3D(-160.78085097040818,
226 -547.2268642786769, 0.0), new OTSPoint3D(-160.87777996916128, -547.2514563078457, 0.0),
227 new OTSPoint3D(-160.97467815216018, -547.2761694790188, 0.0), new OTSPoint3D(-161.07154536800144,
228 -547.3010037535821, 0.0), new OTSPoint3D(-161.1683814653301, -547.3259590927318, 0.0),
229 new OTSPoint3D(-161.26518629283973, -547.3510354574753, 0.0), new OTSPoint3D(-161.36195969927286,
230 -547.3762328086307, 0.0), new OTSPoint3D(-161.45870153342102, -547.4015511068272, 0.0),
231 new OTSPoint3D(-161.55541164412512, -547.426990312505, 0.0), new OTSPoint3D(-161.65208988027564,
232 -547.4525503859154, 0.0), new OTSPoint3D(-161.74873609081288, -547.4782312871207, 0.0),
233 new OTSPoint3D(-161.8453501247271, -547.5040329759945, 0.0), new OTSPoint3D(-161.94193183105892,
234 -547.5299554122216, 0.0), new OTSPoint3D(-162.0384810588995, -547.5559985552984, 0.0),
235 new OTSPoint3D(-162.13499765739058, -547.5821623645322, 0.0), new OTSPoint3D(-162.23148147572508,
236 -547.6084467990423, 0.0), new OTSPoint3D(-162.327932363147, -547.6348518177593, 0.0),
237 new OTSPoint3D(-162.4243501689519, -547.6613773794252, 0.0), new OTSPoint3D(-162.52073474248692,
238 -547.6880234425938, 0.0), new OTSPoint3D(-162.61708593315126, -547.7147899656309, 0.0),
239 new OTSPoint3D(-162.71340359039613, -547.7416769067133, 0.0), new OTSPoint3D(-162.80968756372525,
240 -547.7686842238307, 0.0), new OTSPoint3D(-162.9059377026949, -547.795811874784, 0.0),
241 new OTSPoint3D(-163.0021538569143, -547.8230598171862, 0.0), new OTSPoint3D(-163.0983358760457,
242 -547.8504280084622, 0.0), new OTSPoint3D(-163.1944836098047, -547.8779164058496, 0.0),
243 new OTSPoint3D(-163.29059690796055, -547.9055249663976, 0.0), new OTSPoint3D(-163.38667562033615,
244 -547.9332536469677, 0.0), new OTSPoint3D(-163.4827195968086, -547.961102404234, 0.0),
245 new OTSPoint3D(-163.5787286873092, -547.9890711946829, 0.0), new OTSPoint3D(-163.67470274182375,
246 -548.0171599746129, 0.0), new OTSPoint3D(-163.7706416103928, -548.0453687001356, 0.0),
247 new OTSPoint3D(-163.8665451431119, -548.0736973271746, 0.0), new OTSPoint3D(-163.96241319013177,
248 -548.1021458114666, 0.0), new OTSPoint3D(-164.05824560165868, -548.1307141085607, 0.0),
249 new OTSPoint3D(-164.15404222795442, -548.1594021738192, 0.0), new OTSPoint3D(-164.24980291933684,
250 -548.1882099624167, 0.0), new OTSPoint3D(-164.34552752617986, -548.2171374293412, 0.0),
251 new OTSPoint3D(-164.4412158989138, -548.2461845293935, 0.0), new OTSPoint3D(-164.53686788802563,
252 -548.2753512171876, 0.0), new OTSPoint3D(-164.63248334405907, -548.3046374471504, 0.0),
253 new OTSPoint3D(-164.72806211761502, -548.3340431735223, 0.0), new OTSPoint3D(-164.82360405935168,
254 -548.3635683503568, 0.0), new OTSPoint3D(-164.91910901998477, -548.3932129315208, 0.0),
255 new OTSPoint3D(-165.01457685028782, -548.4229768706948, 0.0), new OTSPoint3D(-165.11000740109236,
256 -548.4528601213724, 0.0), new OTSPoint3D(-165.20540052328818, -548.4828626368612, 0.0),
257 new OTSPoint3D(-165.30075606782353, -548.5129843702822, 0.0), new OTSPoint3D(-165.3960738857054,
258 -548.5432252745702, 0.0), new OTSPoint3D(-165.49135382799972, -548.5735853024739, 0.0),
259 new OTSPoint3D(-165.58659574583157, -548.6040644065556, 0.0), new OTSPoint3D(-165.68179949038554,
260 -548.6346625391919, 0.0), new OTSPoint3D(-165.77696491290575, -548.665379652573, 0.0),
261 new OTSPoint3D(-165.87209186469624, -548.6962156987037, 0.0), new OTSPoint3D(-165.9671801971212,
262 -548.7271706294023, 0.0), new OTSPoint3D(-166.06222976160512, -548.7582443963021, 0.0),
263 new OTSPoint3D(-166.15724040963306, -548.7894369508501, 0.0), new OTSPoint3D(-166.2522119927509,
264 -548.8207482443081, 0.0), new OTSPoint3D(-166.34714436256556, -548.852178227752, 0.0),
265 new OTSPoint3D(-166.44203737074525, -548.8837268520728, 0.0), new OTSPoint3D(-166.5368908690197,
266 -548.9153940679754, 0.0), new OTSPoint3D(-166.63170470918024, -548.94717982598, 0.0),
267 new OTSPoint3D(-166.72647874308035, -548.9790840764214, 0.0), new OTSPoint3D(-166.82121282263557,
268 -549.011106769449, 0.0), new OTSPoint3D(-166.91590679982392, -549.0432478550275, 0.0),
269 new OTSPoint3D(-167.01056052668613, -549.0755072829365, 0.0), new OTSPoint3D(-167.10517385532575,
270 -549.1078850027706, 0.0), new OTSPoint3D(-167.19974663790944, -549.1403809639396, 0.0),
271 new OTSPoint3D(-167.29427872666727, -549.1729951156685, 0.0), new OTSPoint3D(-167.3887699738929,
272 -549.2057274069979, 0.0), new OTSPoint3D(-167.4832202319437, -549.2385777867835, 0.0),
273 new OTSPoint3D(-167.57762935324124, -549.2715462036964, 0.0), new OTSPoint3D(-167.67199719027124,
274 -549.3046326062237, 0.0), new OTSPoint3D(-167.766323595584, -549.3378369426678, 0.0),
275 new OTSPoint3D(-167.86060842179452, -549.3711591611469, 0.0), new OTSPoint3D(-167.95485152158278,
276 -549.4045992095952, 0.0), new OTSPoint3D(-168.04905274769393, -549.4381570357625, 0.0),
277 new OTSPoint3D(-168.1432119529386, -549.4718325872147, 0.0), new OTSPoint3D(-168.23732899019308,
278 -549.5056258113337, 0.0), new OTSPoint3D(-168.33140371239944, -549.5395366553179, 0.0),
279 new OTSPoint3D(-168.42543597256602, -549.5735650661812, 0.0), new OTSPoint3D(-168.5194256237674,
280 -549.6077109907545, 0.0), new OTSPoint3D(-168.61337251914478, -549.6419743756846, 0.0),
281 new OTSPoint3D(-168.70727651190614, -549.6763551674352, 0.0), new OTSPoint3D(-168.8011374553265,
282 -549.7108533122862, 0.0), new OTSPoint3D(-168.8949552027482, -549.7454687563342, 0.0),
283 new OTSPoint3D(-168.988729607581, -549.7802014454926, 0.0), new OTSPoint3D(-169.08246052330242,
284 -549.8150513254916, 0.0), new OTSPoint3D(-169.1761478034579, -549.8500183418782, 0.0),
285 new OTSPoint3D(-169.2697913016611, -549.8851024400167, 0.0), new OTSPoint3D(-169.36339087159408,
286 -549.9203035650879, 0.0), new OTSPoint3D(-169.45694636700753, -549.9556216620903, 0.0),
287 new OTSPoint3D(-169.55045764172098, -549.9910566758391, 0.0), new OTSPoint3D(-169.64392454962314,
288 -550.0266085509672, 0.0), new OTSPoint3D(-169.73734694467194, -550.062277231925, 0.0),
289 new OTSPoint3D(-169.8307246808949, -550.09806266298, 0.0), new OTSPoint3D(-169.92405761238936,
290 -550.1339647882176, 0.0), new OTSPoint3D(-170.0173455933226, -550.1699835515406, 0.0),
291 new OTSPoint3D(-170.1105884779322, -550.2061188966698, 0.0), new OTSPoint3D(-170.20378612052616,
292 -550.2423707671435, 0.0), new OTSPoint3D(-170.29693837548317, -550.2787391063184, 0.0),
293 new OTSPoint3D(-170.39004509725288, -550.315223857369, 0.0), new OTSPoint3D(-170.48310614035597,
294 -550.3518249632878, 0.0), new OTSPoint3D(-170.57612135938473, -550.3885423668855, 0.0),
295 new OTSPoint3D(-170.66909060900278, -550.4253760107913, 0.0), new OTSPoint3D(-170.76201374394572,
296 -550.4623258374525, 0.0), new OTSPoint3D(-170.85489061902118, -550.4993917891351, 0.0),
297 new OTSPoint3D(-170.94772108910905, -550.5365738079236, 0.0), new OTSPoint3D(-171.04050500916173,
298 -550.573871835721, 0.0), new OTSPoint3D(-171.13324223420437, -550.6112858142492, 0.0),
299 new OTSPoint3D(-171.2259326193351, -550.6488156850488, 0.0), new OTSPoint3D(-171.3185760197252,
300 -550.6864613894795, 0.0), new OTSPoint3D(-171.4111722906194, -550.7242228687198, 0.0),
301 new OTSPoint3D(-171.50372128733594, -550.7621000637674, 0.0), new OTSPoint3D(-171.59622286526712,
302 -550.8000929154392, 0.0), new OTSPoint3D(-171.68867687987927, -550.8382013643715, 0.0),
303 new OTSPoint3D(-171.78108318671295, -550.8764253510196, 0.0), new OTSPoint3D(-171.8734416413833,
304 -550.9147648156588, 0.0), new OTSPoint3D(-171.96575209958038, -550.9532196983835, 0.0),
305 new OTSPoint3D(-172.058014417069, -550.991789939108, 0.0), new OTSPoint3D(-183.2636723755513,
306 -556.3855708716345, 0.0), new OTSPoint3D(-183.7248063744403, -556.6224974422428, 0.0),
307 new OTSPoint3D(-184.4647247962342, -557.0026609839204, 0.0), new OTSPoint3D(-186.64575105571316,
308 -558.2116382472677, 0.0));
309 OTSLine3D buf1 = offsetLine(line3, 1.625);
310 System.out.println(buf1.toExcel());
311
312
313
314
315
316
317
318
319
320
321
322
323
324 }
325
326
327
328
329
330 private static void printExcel(final OTSLine3D line)
331 {
332 for (OTSPoint3D p : line.getPoints())
333 {
334 System.out.println(p.x + "\t" + p.y);
335 }
336 System.out.println();
337 }
338
339
340 private static final int LINES2PI = 128;
341
342
343
344
345
346
347
348
349 public static OTSLine3D offsetLine(final OTSLine3D line, final double offset) throws OTSGeometryException
350 {
351
352 if (offset < 0.00001)
353 {
354 return line;
355 }
356
357 List<Point2D.Double> orig = new ArrayList<>();
358 List<Line2D.Double> lines = new ArrayList<>();
359 List<Path2D.Double> rects = new ArrayList<>();
360 List<Path2D.Double> circs = new ArrayList<>();
361 double sign = (offset < 0) ? -1.0 : 1.0;
362 double pi2 = Math.PI / 2.0;
363
364
365 Point2D.Double startPoint = null;
366 Point2D.Double endPoint = null;
367
368
369 for (int i = 0; i < line.size() - 1; i++)
370 {
371 Point2D.Double p1 = new Point2D.Double(line.get(i).x, line.get(i).y);
372 Point2D.Double p2 = new Point2D.Double(line.get(i + 1).x, line.get(i + 1).y);
373 double p1x = p1.x;
374 double p1y = p1.y;
375 double p2x = p2.x;
376 double p2y = p2.y;
377 double angle = Math.atan2(p2y - p1y, p2x - p1x);
378 double osina = sign * offset * Math.sin(angle + sign * pi2);
379 double ocosa = sign * offset * Math.cos(angle + sign * pi2);
380 Point2D.Double o1 = new Point2D.Double(p1x + ocosa, p1y + osina);
381 Point2D.Double o2 = new Point2D.Double(p2x + ocosa, p2y + osina);
382 lines.add(new Line2D.Double(o1, o2));
383 rects.add(makeRectangle(p1, p2, o2, o1));
384
385
386 if (i == 0)
387 {
388 startPoint = o1;
389 }
390 if (i == line.size() - 2)
391 {
392 endPoint = o2;
393 }
394 }
395
396 for (int i = 0; i < line.size(); i++)
397 {
398 orig.add(new Point2D.Double(line.get(i).x, line.get(i).y));
399 }
400
401
402 for (int i = 0; i < orig.size() - 2; i++)
403 {
404 Point2D.Double p1 = orig.get(i);
405 Point2D.Double p2 = orig.get(i + 1);
406 Point2D.Double p3 = orig.get(i + 2);
407
408
409 double angle1 = norm(Math.atan2(p2.y - p1.y, p2.x - p1.x));
410 double angle2 = norm(Math.atan2(p3.y - p2.y, p3.x - p2.x));
411 if (angle1 != angle2 && norm(sign * (angle2 - angle1)) > Math.PI)
412 {
413
414 int numPoints = (int) Math.ceil(LINES2PI * norm(Math.abs(angle2 - angle1)) / (2.0 * Math.PI)) + 1;
415 Point2D.Double[] arc = new Point2D.Double[numPoints + 1];
416 arc[0] = new Point2D.Double(lines.get(i).x2, lines.get(i).y2);
417 arc[arc.length - 1] = new Point2D.Double(lines.get(i + 1).x1, lines.get(i + 1).y1);
418 for (int j = 1; j < numPoints; j++)
419 {
420 double angle = angle1 + sign * pi2 + (angle2 - angle1) * (1.0 * j / numPoints);
421 arc[j] = new Point2D.Double(p2.x + sign * offset * Math.cos(angle), p2.y + sign * offset * Math.sin(angle));
422 }
423
424 for (int j = 0; j < arc.length - 1; j++)
425 {
426 lines.add(new Line2D.Double(arc[j], arc[j + 1]));
427 }
428
429 Path2D.Double circ = new Path2D.Double();
430 circ.moveTo(p2.x, p2.y);
431 for (int j = 0; j <= numPoints; j++)
432 {
433 double angle = angle1 + sign * pi2 + (angle2 - angle1) * (1.0 * j / numPoints);
434 circ.lineTo(p2.x + sign * offset * Math.cos(angle), p2.y + sign * offset * Math.sin(angle));
435 }
436 circ.closePath();
437 circs.add(circ);
438 }
439 }
440
441
442 Point2D.Double po1 = orig.get(0);
443 Point2D.Double po2 = orig.get(1);
444 double angle1 = norm(Math.atan2(po2.y - po1.y, po2.x - po1.x) + ((sign > 0) ? Math.PI : 0));
445 Point2D.Double p1 =
446 new Point2D.Double(po1.x + offset * Math.cos(angle1 - pi2), po1.y + offset * Math.sin(angle1 - pi2));
447 Point2D.Double p2 =
448 new Point2D.Double(po1.x + offset * Math.cos(angle1 + pi2), po1.y + offset * Math.sin(angle1 + pi2));
449 Point2D.Double p3 = new Point2D.Double(p2.x + offset * Math.cos(angle1), p2.y + offset * Math.sin(angle1));
450 Point2D.Double p4 = new Point2D.Double(p1.x + offset * Math.cos(angle1), p1.y + offset * Math.sin(angle1));
451 rects.add(makeRectangle(p1, p2, p3, p4));
452
453 po1 = orig.get(orig.size() - 1);
454 po2 = orig.get(orig.size() - 2);
455 double angle2 = norm(Math.atan2(po2.y - po1.y, po2.x - po1.x) + ((sign > 0) ? Math.PI : 0));
456 p1 = new Point2D.Double(po1.x + offset * Math.cos(angle2 - pi2), po1.y + offset * Math.sin(angle2 - pi2));
457 p2 = new Point2D.Double(po1.x + offset * Math.cos(angle2 + pi2), po1.y + offset * Math.sin(angle2 + pi2));
458 p3 = new Point2D.Double(p2.x + offset * Math.cos(angle2), p2.y + offset * Math.sin(angle2));
459 p4 = new Point2D.Double(p1.x + offset * Math.cos(angle2), p1.y + offset * Math.sin(angle2));
460 rects.add(makeRectangle(p1, p2, p3, p4));
461
462
463 List<Line2D.Double> lines2 = new ArrayList<>(lines);
464 while (!lines2.isEmpty())
465 {
466 boolean crossed = false;
467 Line2D.Double line1 = lines2.get(0);
468 for (int i = 1; i < lines2.size() && !crossed; i++)
469 {
470 Line2D.Double line2 = lines2.get(i);
471 List<Line2D.Double> splitLines = splitAtIntersection(line1, line2);
472 if (splitLines != null)
473 {
474 if (splitLines.size() != 0)
475 {
476 lines2.addAll(splitLines);
477 lines.remove(line1);
478 lines.addAll(splitLines);
479 }
480 lines.remove(line2);
481 lines2.remove(line2);
482 crossed = true;
483 }
484 }
485 lines2.remove(0);
486 }
487
488
489 List<Line2D.Double> remove = new ArrayList<>();
490 for (int i = 0; i < orig.size() - 1; i++)
491 {
492 Line2D.Double o = new Line2D.Double(orig.get(i), orig.get(i + 1));
493 for (Line2D.Double l : lines)
494 {
495 if (o.intersectsLine(l) || o.getP1().distance(l.getP1()) < 0.1 * sign * offset
496 || o.getP1().distance(l.getP2()) < 0.1 * sign * offset
497 || o.getP2().distance(l.getP1()) < 0.1 * sign * offset
498 || o.getP2().distance(l.getP2()) < 0.1 * sign * offset)
499 {
500 remove.add(l);
501 }
502 }
503 }
504 lines.removeAll(remove);
505
506
507
508
509 for (Path2D.Double rect : rects)
510 {
511 List<Line2D.Double> contour = getContour(rect);
512 remove = new ArrayList<>();
513 for (Line2D.Double l : lines)
514 {
515 if (inside(rect, l, contour))
516 {
517 remove.add(l);
518
519 }
520 }
521 lines.removeAll(remove);
522 }
523
524
525 for (Path2D.Double circle : circs)
526 {
527 List<Line2D.Double> contour = getContour(circle);
528 remove = new ArrayList<>();
529 for (Line2D.Double l : lines)
530 {
531 if (inside(circle, l, contour))
532 {
533 remove.add(l);
534 }
535 }
536 lines.removeAll(remove);
537 }
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 List<Point2D> offsetLine = new ArrayList<>();
553 Line2D.Double l0 = lines.remove(0);
554 offsetLine.add(l0.getP1());
555 offsetLine.add(l0.getP2());
556 while (!lines.isEmpty())
557 {
558 boolean found = false;
559 Point2D ps = offsetLine.get(0);
560 Point2D pe = offsetLine.get(offsetLine.size() - 1);
561 for (int i = 0; i < lines.size() && !found; i++)
562 {
563 Line2D.Double l = lines.get(i);
564 if (l.getP1().equals(ps))
565 {
566 offsetLine.add(0, l.getP2());
567 lines.remove(i);
568 found = true;
569 }
570 if (l.getP2().equals(ps))
571 {
572 offsetLine.add(0, l.getP1());
573 lines.remove(i);
574 found = true;
575 }
576 if (l.getP1().equals(pe))
577 {
578 offsetLine.add(l.getP2());
579 lines.remove(i);
580 found = true;
581 }
582 if (l.getP2().equals(pe))
583 {
584 offsetLine.add(l.getP1());
585 lines.remove(i);
586 found = true;
587 }
588 }
589 if (!found)
590 {
591 System.err.println("#offsetLine: Problem connecting one or more points");
592
593 lines.clear();
594 offsetLine.clear();
595 offsetLine.add(startPoint);
596 offsetLine.add(endPoint);
597 }
598 }
599
600
601 double ss = startPoint.distance(offsetLine.get(0));
602 double ee = endPoint.distance(offsetLine.get(offsetLine.size() - 1));
603 double es = endPoint.distance(offsetLine.get(0));
604 double se = startPoint.distance(offsetLine.get(offsetLine.size() - 1));
605
606
607 if (ss == 0.0 && ee == 0.0)
608 {
609 return makeOTSLine3D(offsetLine);
610 }
611 if (es == 0.0 && se == 0.0)
612 {
613 return makeOTSLine3D(offsetLine).reverse();
614 }
615
616
617 if (ss > 0.0 && se > 0.0)
618 {
619
620 if (ss < se)
621 {
622 offsetLine.add(0, startPoint);
623 }
624 else
625 {
626 offsetLine.add(startPoint);
627 }
628 }
629 if (ee > 0.0 && es > 0.0)
630 {
631
632 if (ee < es)
633 {
634 offsetLine.add(endPoint);
635 }
636 else
637 {
638 offsetLine.add(0, endPoint);
639 }
640 }
641
642
643 if (startPoint.distance(offsetLine.get(0)) == 0.0 && endPoint.distance(offsetLine.get(offsetLine.size() - 1)) == 0.0)
644 {
645 return makeOTSLine3D(offsetLine);
646 }
647 else
648 {
649 return makeOTSLine3D(offsetLine).reverse();
650 }
651 }
652
653
654
655
656
657
658 private static String toJava(final OTSLine3D line)
659 {
660 StringBuffer s = new StringBuffer();
661 s.append(" OTSLine3D line = new OTSLine3D(");
662 boolean first = false;
663 for (OTSPoint3D p : line.getPoints())
664 {
665 if (!first)
666 {
667 first = true;
668 s.append("\n ");
669 }
670 else
671 {
672 s.append("\n , ");
673 }
674 s.append("new OTSPoint3D(" + p.x + ", " + p.y + ", " + p.z + ")");
675 }
676 s.append(" );");
677 return s.toString();
678 }
679
680
681
682
683
684
685
686 private static OTSLine3D makeOTSLine3D(final List<Point2D> points) throws OTSGeometryException
687 {
688 List<OTSPoint3D> otsPoints = new ArrayList<>();
689 for (Point2D point : points)
690 {
691 otsPoints.add(new OTSPoint3D(point.getX(), point.getY(), 0.0));
692 }
693 return new OTSLine3D(otsPoints);
694 }
695
696
697
698
699
700
701
702
703
704 private static Path2D.Double makeRectangle(final Point2D.Double p1, final Point2D.Double p2, final Point2D.Double p3,
705 final Point2D.Double p4)
706 {
707 Path2D.Double rect = new Path2D.Double();
708 rect.moveTo(p1.x, p1.y);
709 rect.lineTo(p2.x, p2.y);
710 rect.lineTo(p3.x, p3.y);
711 rect.lineTo(p4.x, p4.y);
712 rect.closePath();
713 return rect;
714 }
715
716
717
718
719
720
721 private static double norm(final double angle)
722 {
723 double result = angle;
724 while (result < 0)
725 {
726 result += 2.0 * Math.PI;
727 }
728 while (result > 2.0 * Math.PI)
729 {
730 result -= 2.0 * Math.PI;
731 }
732 return result;
733 }
734
735
736
737
738
739
740
741
742 private static boolean inside(final Path2D.Double shape, final Line2D.Double line, final List<Line2D.Double> contour)
743 {
744 if (shape.contains(line.getP1()))
745 {
746 if (!onContour(contour, line.getP1()))
747 {
748 return true;
749 }
750 }
751 if (shape.contains(line.getP2()))
752 {
753 if (!onContour(contour, line.getP2()))
754 {
755 return true;
756 }
757 }
758 return false;
759 }
760
761
762
763
764
765
766
767 private static boolean onContour(final List<Line2D.Double> contour, final Point2D point)
768 {
769 for (Line2D.Double l : contour)
770 {
771 if (l.ptLineDist(point) < 1E-6)
772 {
773 return true;
774 }
775 }
776 return false;
777 }
778
779
780
781
782
783
784 private static List<Line2D.Double> getContour(final Path2D.Double shape)
785 {
786 List<Line2D.Double> contour = new ArrayList<>();
787 PathIterator pi = shape.getPathIterator(null);
788 Point2D.Double lastPoint = null;
789 Point2D.Double firstPoint = null;
790 while (!pi.isDone())
791 {
792 double[] p = new double[6];
793 int segtype = pi.currentSegment(p);
794 if (segtype == PathIterator.SEG_MOVETO)
795 {
796 lastPoint = new Point2D.Double(p[0], p[1]);
797 firstPoint = lastPoint;
798 }
799 if (segtype == PathIterator.SEG_LINETO && lastPoint != null)
800 {
801 Point2D.Double newPoint = new Point2D.Double(p[0], p[1]);
802 contour.add(new Line2D.Double(lastPoint, newPoint));
803 lastPoint = newPoint;
804 }
805 if (segtype == PathIterator.SEG_CLOSE && firstPoint != null)
806 {
807 contour.add(new Line2D.Double(lastPoint, firstPoint));
808 }
809 pi.next();
810 }
811 return contour;
812 }
813
814
815
816
817
818
819
820 private static List<Line2D.Double> splitAtIntersection(final Line2D.Double line1, final Line2D.Double line2)
821 {
822 if (!line1.intersectsLine(line2))
823 {
824 return null;
825 }
826 double p1x = line1.getX1(), p1y = line1.getY1(), d1x = line1.getX2() - p1x, d1y = line1.getY2() - p1y;
827 double p2x = line2.getX1(), p2y = line2.getY1(), d2x = line2.getX2() - p2x, d2y = line2.getY2() - p2y;
828
829 double det = d2x * d1y - d2y * d1x;
830 if (det == 0)
831 {
832
833
834
835
836
837
838 Point2D p1s = line1.getP1(), p1e = line1.getP2(), p2s = line2.getP1(), p2e = line2.getP2();
839 List<Line2D.Double> lines = new ArrayList<>();
840 if ((p1s.equals(p2s) && p1e.equals(p2e)) || (p1s.equals(p2e) && p1e.equals(p2s)))
841 {
842 return lines;
843 }
844 if (p1s.equals(p2s) && line1.ptLineDist(p2e) > 0 && line2.ptLineDist(p1e) > 0)
845 {
846 return null;
847 }
848 if (p1e.equals(p2e) && line1.ptLineDist(p2s) > 0 && line2.ptLineDist(p1s) > 0)
849 {
850 return null;
851 }
852 if (p1s.equals(p2e) && line1.ptLineDist(p2s) > 0 && line2.ptLineDist(p1e) > 0)
853 {
854 return null;
855 }
856 if (p1e.equals(p2s) && line1.ptLineDist(p2e) > 0 && line2.ptLineDist(p1s) > 0)
857 {
858 return null;
859 }
860
861 SortedMap<Double, Point2D> pointMap = new TreeMap<>();
862 pointMap.put(0.0, p1s);
863 pointMap.put(p1s.distance(p1e), p1e);
864 pointMap.put(p1s.distance(p2s), p2s);
865 pointMap.put(p1s.distance(p2e), p2e);
866 List<Point2D> ptList = new ArrayList<>(pointMap.values());
867 for (int i = 0; i < ptList.size() - 1; i++)
868 {
869 lines.add(new Line2D.Double(ptList.get(i), ptList.get(i + 1)));
870 }
871 return lines;
872 }
873 else
874 {
875 double z = (d2x * (p2y - p1y) + d2y * (p1x - p2x)) / det;
876 if (Math.abs(z) < 10.0 * Math.ulp(1.0) || Math.abs(z - 1.0) < 10.0 * Math.ulp(1.0))
877 {
878 return null;
879 }
880 Point2D.Double cross = new Point2D.Double(p1x + z * d1x, p1y + z * d1y);
881 List<Line2D.Double> lines = new ArrayList<>();
882 if (cross.distance(line1.getP1()) > 0)
883 {
884 lines.add(new Line2D.Double(line1.getP1(), cross));
885 }
886 if (cross.distance(line1.getP2()) > 0)
887 {
888 lines.add(new Line2D.Double(cross, line1.getP2()));
889 }
890 if (cross.distance(line2.getP1()) > 0)
891 {
892 lines.add(new Line2D.Double(line2.getP1(), cross));
893 }
894 if (cross.distance(line2.getP2()) > 0)
895 {
896 lines.add(new Line2D.Double(cross, line2.getP2()));
897 }
898 return lines;
899 }
900 }
901
902
903
904
905
906 private static void print(final Path2D.Double shape)
907 {
908 PathIterator pi = shape.getPathIterator(null);
909 Point2D.Double pf = null;
910 while (!pi.isDone())
911 {
912 double[] p = new double[6];
913 int segtype = pi.currentSegment(p);
914 if (segtype == PathIterator.SEG_MOVETO || segtype == PathIterator.SEG_LINETO)
915 {
916 System.out.println(p[0] + "\t" + p[1]);
917 if (pf == null)
918 {
919 pf = new Point2D.Double(p[0], p[1]);
920 }
921 }
922 pi.next();
923 }
924 System.out.println(pf.x + "\t" + pf.y);
925 System.out.println();
926 }
927
928
929
930
931
932 private static void print(final List<Line2D.Double> lines)
933 {
934 if (lines.size() == 0)
935 {
936 System.out.println("<<none>>");
937 return;
938 }
939 for (Line2D.Double line : lines)
940 {
941 System.out.println(line.x1 + "\t" + line.y1);
942 System.out.println(line.x2 + "\t" + line.y2);
943 System.out.println();
944 }
945 }
946
947
948
949
950
951
952 private static String p(final Line2D.Double l)
953 {
954 return "[(" + l.x1 + "," + l.y1 + ")->(" + l.x2 + "," + l.y2 + ")]";
955 }
956
957
958
959
960
961
962 private static String p(final List<Line2D.Double> c)
963 {
964 String s = "contour [";
965 for (Line2D.Double l : c)
966 {
967 s += p(l) + " ";
968 }
969 s += "]";
970 return s;
971 }
972
973 }