geomerative 0.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/LICENSE +662 -0
- data/LICENSE.md +9 -0
- data/README.md +2 -0
- data/Rakefile +37 -0
- data/examples/README.md +7 -0
- data/examples/data/FreeSans.ttf +0 -0
- data/examples/data/ReplicaBold.ttf +0 -0
- data/examples/data/bot1.svg +160 -0
- data/examples/hello_svg_to_pdf.rb +26 -0
- data/examples/hello_world.rb +23 -0
- data/examples/physics_type.rb +77 -0
- data/examples/rotate_first_letter.rb +28 -0
- data/geomerative.gemspec +32 -0
- data/lib/geomerative.rb +12 -0
- data/lib/geomerative/version.rb +3 -0
- data/pom.xml +110 -0
- data/src/geomerative/FastRClip.java +2715 -0
- data/src/geomerative/RClip.java +2892 -0
- data/src/geomerative/RClosest.java +64 -0
- data/src/geomerative/RCommand.java +1941 -0
- data/src/geomerative/RContour.java +348 -0
- data/src/geomerative/RFont.java +583 -0
- data/src/geomerative/RG.java +753 -0
- data/src/geomerative/RGeomElem.java +1075 -0
- data/src/geomerative/RGroup.java +888 -0
- data/src/geomerative/RMatrix.java +401 -0
- data/src/geomerative/RMesh.java +420 -0
- data/src/geomerative/RPath.java +1095 -0
- data/src/geomerative/RPoint.java +419 -0
- data/src/geomerative/RPolygon.java +1110 -0
- data/src/geomerative/RRectangle.java +91 -0
- data/src/geomerative/RSVG.java +976 -0
- data/src/geomerative/RShape.java +2045 -0
- data/src/geomerative/RStrip.java +221 -0
- data/src/geomerative/RStyle.java +469 -0
- data/src/org/apache/batik/svggen/font/.SVGFont.java.swp +0 -0
- data/src/org/apache/batik/svggen/font/Font.java +188 -0
- data/src/org/apache/batik/svggen/font/Glyph.java +113 -0
- data/src/org/apache/batik/svggen/font/Messages.java.bak +72 -0
- data/src/org/apache/batik/svggen/font/Point.java +38 -0
- data/src/org/apache/batik/svggen/font/RandomAccessFileEmulator.java +15 -0
- data/src/org/apache/batik/svggen/font/table/ClassDef.java +42 -0
- data/src/org/apache/batik/svggen/font/table/ClassDefFormat1.java +55 -0
- data/src/org/apache/batik/svggen/font/table/ClassDefFormat2.java +49 -0
- data/src/org/apache/batik/svggen/font/table/CmapFormat.java +81 -0
- data/src/org/apache/batik/svggen/font/table/CmapFormat0.java +60 -0
- data/src/org/apache/batik/svggen/font/table/CmapFormat2.java +48 -0
- data/src/org/apache/batik/svggen/font/table/CmapFormat4.java +147 -0
- data/src/org/apache/batik/svggen/font/table/CmapFormat6.java +60 -0
- data/src/org/apache/batik/svggen/font/table/CmapIndexEntry.java +84 -0
- data/src/org/apache/batik/svggen/font/table/CmapTable.java +87 -0
- data/src/org/apache/batik/svggen/font/table/Coverage.java +50 -0
- data/src/org/apache/batik/svggen/font/table/CoverageFormat1.java +59 -0
- data/src/org/apache/batik/svggen/font/table/CoverageFormat2.java +56 -0
- data/src/org/apache/batik/svggen/font/table/CvtTable.java +48 -0
- data/src/org/apache/batik/svggen/font/table/Device.java +63 -0
- data/src/org/apache/batik/svggen/font/table/DirectoryEntry.java +73 -0
- data/src/org/apache/batik/svggen/font/table/Feature.java +56 -0
- data/src/org/apache/batik/svggen/font/table/FeatureList.java +70 -0
- data/src/org/apache/batik/svggen/font/table/FeatureRecord.java +52 -0
- data/src/org/apache/batik/svggen/font/table/FeatureTags.java +30 -0
- data/src/org/apache/batik/svggen/font/table/FpgmTable.java +38 -0
- data/src/org/apache/batik/svggen/font/table/GlyfCompositeComp.java +165 -0
- data/src/org/apache/batik/svggen/font/table/GlyfCompositeDescript.java +160 -0
- data/src/org/apache/batik/svggen/font/table/GlyfDescript.java +79 -0
- data/src/org/apache/batik/svggen/font/table/GlyfSimpleDescript.java +155 -0
- data/src/org/apache/batik/svggen/font/table/GlyfTable.java +111 -0
- data/src/org/apache/batik/svggen/font/table/GlyphDescription.java +39 -0
- data/src/org/apache/batik/svggen/font/table/GposTable.java +80 -0
- data/src/org/apache/batik/svggen/font/table/GsubTable.java +118 -0
- data/src/org/apache/batik/svggen/font/table/HeadTable.java +159 -0
- data/src/org/apache/batik/svggen/font/table/HheaTable.java +109 -0
- data/src/org/apache/batik/svggen/font/table/HmtxTable.java +99 -0
- data/src/org/apache/batik/svggen/font/table/KernSubtable.java +58 -0
- data/src/org/apache/batik/svggen/font/table/KernSubtableFormat0.java +65 -0
- data/src/org/apache/batik/svggen/font/table/KernSubtableFormat2.java +56 -0
- data/src/org/apache/batik/svggen/font/table/KernTable.java +64 -0
- data/src/org/apache/batik/svggen/font/table/KerningPair.java +53 -0
- data/src/org/apache/batik/svggen/font/table/LangSys.java +58 -0
- data/src/org/apache/batik/svggen/font/table/LangSysRecord.java +52 -0
- data/src/org/apache/batik/svggen/font/table/Ligature.java +57 -0
- data/src/org/apache/batik/svggen/font/table/LigatureSet.java +55 -0
- data/src/org/apache/batik/svggen/font/table/LigatureSubst.java +40 -0
- data/src/org/apache/batik/svggen/font/table/LigatureSubstFormat1.java +63 -0
- data/src/org/apache/batik/svggen/font/table/LocaTable.java +72 -0
- data/src/org/apache/batik/svggen/font/table/Lookup.java +77 -0
- data/src/org/apache/batik/svggen/font/table/LookupList.java +68 -0
- data/src/org/apache/batik/svggen/font/table/LookupSubtable.java +27 -0
- data/src/org/apache/batik/svggen/font/table/LookupSubtableFactory.java +31 -0
- data/src/org/apache/batik/svggen/font/table/MaxpTable.java +124 -0
- data/src/org/apache/batik/svggen/font/table/NameRecord.java +98 -0
- data/src/org/apache/batik/svggen/font/table/NameTable.java +67 -0
- data/src/org/apache/batik/svggen/font/table/Os2Table.java +232 -0
- data/src/org/apache/batik/svggen/font/table/Panose.java +108 -0
- data/src/org/apache/batik/svggen/font/table/PostTable.java +379 -0
- data/src/org/apache/batik/svggen/font/table/PrepTable.java +38 -0
- data/src/org/apache/batik/svggen/font/table/Program.java +49 -0
- data/src/org/apache/batik/svggen/font/table/RangeRecord.java +57 -0
- data/src/org/apache/batik/svggen/font/table/Script.java +72 -0
- data/src/org/apache/batik/svggen/font/table/ScriptList.java +78 -0
- data/src/org/apache/batik/svggen/font/table/ScriptRecord.java +52 -0
- data/src/org/apache/batik/svggen/font/table/ScriptTags.java +28 -0
- data/src/org/apache/batik/svggen/font/table/SingleSubst.java +47 -0
- data/src/org/apache/batik/svggen/font/table/SingleSubstFormat1.java +67 -0
- data/src/org/apache/batik/svggen/font/table/SingleSubstFormat2.java +67 -0
- data/src/org/apache/batik/svggen/font/table/Table.java +204 -0
- data/src/org/apache/batik/svggen/font/table/TableDirectory.java +94 -0
- data/src/org/apache/batik/svggen/font/table/TableFactory.java +121 -0
- metadata +206 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
|
|
3
|
+
|
|
4
|
+
This file is part of Geomerative.
|
|
5
|
+
|
|
6
|
+
Geomerative is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
Geomerative is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License
|
|
17
|
+
along with Geomerative. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
package geomerative;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* RPoint is a very simple interface for creating, holding and drawing 2D points.
|
|
24
|
+
* @eexample RPoint
|
|
25
|
+
* @usage Geometry
|
|
26
|
+
* @related x
|
|
27
|
+
* @related y
|
|
28
|
+
*/
|
|
29
|
+
public class RPoint
|
|
30
|
+
{
|
|
31
|
+
/**
|
|
32
|
+
* The x coordinate of the point.
|
|
33
|
+
* @eexample RPoint_x
|
|
34
|
+
* @usage Geometry
|
|
35
|
+
* @related y
|
|
36
|
+
*/
|
|
37
|
+
public float x;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The y coordinate of the point.
|
|
41
|
+
* @eexample RPoint_y
|
|
42
|
+
* @usage Geometry
|
|
43
|
+
* @related x
|
|
44
|
+
*/
|
|
45
|
+
public float y;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create a new point, given the coordinates.
|
|
49
|
+
* @eexample RPoint_constructor
|
|
50
|
+
* @usage Geometry
|
|
51
|
+
* @param x the x coordinate of the new point
|
|
52
|
+
* @param y the y coordinate of the new point
|
|
53
|
+
* @related x
|
|
54
|
+
* @related y
|
|
55
|
+
*/
|
|
56
|
+
public RPoint(float x,float y)
|
|
57
|
+
{
|
|
58
|
+
this.x = x;
|
|
59
|
+
this.y = y;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public RPoint(double x, double y)
|
|
63
|
+
{
|
|
64
|
+
this.x = (float)x;
|
|
65
|
+
this.y = (float)y;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create a new point at (0, 0).
|
|
70
|
+
* @eexample RPoint_constructor
|
|
71
|
+
* @usage Geometry
|
|
72
|
+
* @related x
|
|
73
|
+
* @related y
|
|
74
|
+
*/
|
|
75
|
+
public RPoint()
|
|
76
|
+
{
|
|
77
|
+
x = 0;
|
|
78
|
+
y = 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Copy a point.
|
|
83
|
+
* @eexample RPoint_constructor
|
|
84
|
+
* @usage Geometry
|
|
85
|
+
* @param p the point we wish to make a copy of
|
|
86
|
+
* @related x
|
|
87
|
+
* @related y
|
|
88
|
+
*/
|
|
89
|
+
public RPoint(RPoint p)
|
|
90
|
+
{
|
|
91
|
+
this.x = p.x;
|
|
92
|
+
this.y = p.y;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @invisible
|
|
97
|
+
*/
|
|
98
|
+
float getX()
|
|
99
|
+
{
|
|
100
|
+
return this.x;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @invisible
|
|
105
|
+
*/
|
|
106
|
+
float getY()
|
|
107
|
+
{
|
|
108
|
+
return this.y;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @invisible
|
|
114
|
+
*/
|
|
115
|
+
void setLocation(float nx, float ny)
|
|
116
|
+
{
|
|
117
|
+
this.x = nx;
|
|
118
|
+
this.y = ny;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Use this to apply a transformation to the point.
|
|
123
|
+
* @eexample RPoint_transform
|
|
124
|
+
* @usage Geometry
|
|
125
|
+
* @param m the transformation matrix to be applied
|
|
126
|
+
* @related translate ( )
|
|
127
|
+
* @related rotate ( )
|
|
128
|
+
* @related scale ( )
|
|
129
|
+
*/
|
|
130
|
+
public void transform(RMatrix m)
|
|
131
|
+
{
|
|
132
|
+
float tempx = m.m00*x + m.m01*y + m.m02;
|
|
133
|
+
float tempy = m.m10*x + m.m11*y + m.m12;
|
|
134
|
+
|
|
135
|
+
x = tempx;
|
|
136
|
+
y = tempy;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Apply a translation to the point.
|
|
141
|
+
* @eexample RPoint_translate
|
|
142
|
+
* @usage Geometry
|
|
143
|
+
* @param tx the coefficient of x translation
|
|
144
|
+
* @param ty the coefficient of y translation
|
|
145
|
+
* @related transform ( )
|
|
146
|
+
* @related rotate ( )
|
|
147
|
+
* @related scale ( )
|
|
148
|
+
*/
|
|
149
|
+
public void translate(float tx, float ty)
|
|
150
|
+
{
|
|
151
|
+
x += tx;
|
|
152
|
+
y += ty;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Apply a translation to the point.
|
|
157
|
+
* @eexample RPoint_translate
|
|
158
|
+
* @usage Geometry
|
|
159
|
+
* @param t the translation vector to be applied
|
|
160
|
+
* @related transform ( )
|
|
161
|
+
* @related rotate ( )
|
|
162
|
+
* @related scale ( )
|
|
163
|
+
*/
|
|
164
|
+
public void translate(RPoint t)
|
|
165
|
+
{
|
|
166
|
+
x += t.x;
|
|
167
|
+
y += t.y;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Apply a rotation to the point, given the angle and optionally the coordinates of the center of rotation.
|
|
172
|
+
* @eexample RPoint_rotate
|
|
173
|
+
* @usage Geometry
|
|
174
|
+
* @param angle the angle of rotation to be applied
|
|
175
|
+
* @param vx the x coordinate of the center of rotation
|
|
176
|
+
* @param vy the y coordinate of the center of rotation
|
|
177
|
+
* @related transform ( )
|
|
178
|
+
* @related translate ( )
|
|
179
|
+
* @related scale ( )
|
|
180
|
+
*/
|
|
181
|
+
public void rotate(float angle, float vx, float vy)
|
|
182
|
+
{
|
|
183
|
+
float c = (float)Math.cos(angle);
|
|
184
|
+
float s = (float)Math.sin(angle);
|
|
185
|
+
|
|
186
|
+
x -= vx;
|
|
187
|
+
y -= vy;
|
|
188
|
+
|
|
189
|
+
float tempx = x;
|
|
190
|
+
float tempy = y;
|
|
191
|
+
|
|
192
|
+
x = tempx*c - tempy*s;
|
|
193
|
+
y = tempx*s + tempy*c;
|
|
194
|
+
|
|
195
|
+
x += vx;
|
|
196
|
+
y += vy;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public void rotate(float angle)
|
|
200
|
+
{
|
|
201
|
+
float c = (float)Math.cos(angle);
|
|
202
|
+
float s = (float)Math.sin(angle);
|
|
203
|
+
|
|
204
|
+
float tempx = x;
|
|
205
|
+
float tempy = y;
|
|
206
|
+
|
|
207
|
+
x = tempx*c - tempy*s;
|
|
208
|
+
y = tempx*s + tempy*c;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Apply a rotation to the point, given the angle and optionally the point of the center of rotation.
|
|
213
|
+
* @eexample RPoint_rotate
|
|
214
|
+
* @usage Geometry
|
|
215
|
+
* @param angle the angle of rotation to be applied
|
|
216
|
+
* @param v the position vector of the center of rotation
|
|
217
|
+
* @related transform ( )
|
|
218
|
+
* @related translate ( )
|
|
219
|
+
* @related scale ( )
|
|
220
|
+
*/
|
|
221
|
+
public void rotate(float angle, RPoint v)
|
|
222
|
+
{
|
|
223
|
+
float c = (float)Math.cos(angle);
|
|
224
|
+
float s = (float)Math.sin(angle);
|
|
225
|
+
|
|
226
|
+
x -= v.x;
|
|
227
|
+
y -= v.y;
|
|
228
|
+
|
|
229
|
+
float tempx = x;
|
|
230
|
+
float tempy = y;
|
|
231
|
+
|
|
232
|
+
x = tempx*c - tempy*s;
|
|
233
|
+
y = tempx*s + tempy*c;
|
|
234
|
+
|
|
235
|
+
x += v.x;
|
|
236
|
+
y += v.y;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Apply a scaling to the point, given the scaling factors.
|
|
241
|
+
* @eexample RPoint_scale
|
|
242
|
+
* @usage Geometry
|
|
243
|
+
* @param sx the scaling coefficient over the x axis
|
|
244
|
+
* @param sy the scaling coefficient over the y axis
|
|
245
|
+
* @related transform ( )
|
|
246
|
+
* @related translate ( )
|
|
247
|
+
* @related rotate ( )
|
|
248
|
+
*/
|
|
249
|
+
public void scale (float sx, float sy)
|
|
250
|
+
{
|
|
251
|
+
x *= sx;
|
|
252
|
+
y *= sy;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Apply a scaling to the point, given a scaling factor.
|
|
257
|
+
* @eexample RPoint_scale
|
|
258
|
+
* @usage Geometry
|
|
259
|
+
* @param s the scaling coefficient for a uniform scaling
|
|
260
|
+
* @related transform ( )
|
|
261
|
+
* @related translate ( )
|
|
262
|
+
* @related rotate ( )
|
|
263
|
+
*/
|
|
264
|
+
public void scale (float s)
|
|
265
|
+
{
|
|
266
|
+
x *= s;
|
|
267
|
+
y *= s;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Apply a scaling to the point, given a scaling vector.
|
|
272
|
+
* @eexample RPoint_scale
|
|
273
|
+
* @usage Geometry
|
|
274
|
+
* @param s the scaling vector
|
|
275
|
+
* @related transform ( )
|
|
276
|
+
* @related translate ( )
|
|
277
|
+
* @related rotate ( )
|
|
278
|
+
*/
|
|
279
|
+
public void scale (RPoint s)
|
|
280
|
+
{
|
|
281
|
+
x *= s.x;
|
|
282
|
+
y *= s.y;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Use this to normalize the point. This means that after applying, it's norm will be equal to 1.
|
|
288
|
+
* @eexample RPoint_normalize
|
|
289
|
+
* @usage Geometry
|
|
290
|
+
* @related transform ( )
|
|
291
|
+
* @related translate ( )
|
|
292
|
+
* @related rotate ( )
|
|
293
|
+
* @related scale ( )
|
|
294
|
+
*/
|
|
295
|
+
public void normalize ()
|
|
296
|
+
{
|
|
297
|
+
float norma = norm();
|
|
298
|
+
if(norma!=0) scale(1/norma);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Use this to subtract a vector from this point.
|
|
303
|
+
* @eexample RPoint_sub
|
|
304
|
+
* @usage Geometry
|
|
305
|
+
* @param p the vector to substract
|
|
306
|
+
* @related add ( )
|
|
307
|
+
* @related mult ( )
|
|
308
|
+
* @related cross ( )
|
|
309
|
+
*/
|
|
310
|
+
public void sub (RPoint p)
|
|
311
|
+
{
|
|
312
|
+
x -= p.x;
|
|
313
|
+
y -= p.y;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Use this to add a vector to this point.
|
|
318
|
+
* @eexample RPoint_add
|
|
319
|
+
* @usage Geometry
|
|
320
|
+
* @param p the vector to add
|
|
321
|
+
* @related sub ( )
|
|
322
|
+
* @related mult ( )
|
|
323
|
+
* @related cross ( )
|
|
324
|
+
*/
|
|
325
|
+
public void add (RPoint p)
|
|
326
|
+
{
|
|
327
|
+
x += p.x;
|
|
328
|
+
y += p.y;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Use this to multiply a vector to this point. This returns a float corresponding to the scalar product of both vectors.
|
|
333
|
+
* @eexample RPoint_mult
|
|
334
|
+
* @usage Geometry
|
|
335
|
+
* @param p the vector to multiply
|
|
336
|
+
* @return float, the result of the scalar product
|
|
337
|
+
* @related add ( )
|
|
338
|
+
* @related sub ( )
|
|
339
|
+
* @related cross ( )
|
|
340
|
+
*/
|
|
341
|
+
public float mult (RPoint p)
|
|
342
|
+
{
|
|
343
|
+
return (x * p.x + y * p.y);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Use this to perform a cross product of the point with another point. This returns a RPoint corresponding to the cross product of both vectors.
|
|
348
|
+
* @eexample RPoint_cross
|
|
349
|
+
* @usage Geometry
|
|
350
|
+
* @param p the vector to perform the cross product with
|
|
351
|
+
* @return RPoint, the resulting vector of the cross product
|
|
352
|
+
* @related add ( )
|
|
353
|
+
* @related sub ( )
|
|
354
|
+
* @related mult ( )
|
|
355
|
+
*/
|
|
356
|
+
public RPoint cross (RPoint p)
|
|
357
|
+
{
|
|
358
|
+
return new RPoint(x * p.y - p.x * y, y * p.x - p.y * x);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Use this to obtain the norm of the point.
|
|
363
|
+
* @eexample RPoint_norm
|
|
364
|
+
* @usage Geometry
|
|
365
|
+
* @return float, the norm of the point
|
|
366
|
+
* @related angle ( )
|
|
367
|
+
*/
|
|
368
|
+
public float norm ()
|
|
369
|
+
{
|
|
370
|
+
return (float)Math.sqrt(mult(this));
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Use this to obtain the square norm of the point.
|
|
375
|
+
* @eexample RPoint_norm
|
|
376
|
+
* @usage Geometry
|
|
377
|
+
* @return float, the norm of the point
|
|
378
|
+
* @related angle ( )
|
|
379
|
+
*/
|
|
380
|
+
public float sqrnorm ()
|
|
381
|
+
{
|
|
382
|
+
return (float)mult(this);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Use this to obtain the angle between the vector and another vector
|
|
387
|
+
* @eexample RPoint_angle
|
|
388
|
+
* @usage Geometry
|
|
389
|
+
* @param p the vector relative to which we want to evaluate the angle
|
|
390
|
+
* @return float, the angle between the two vectors
|
|
391
|
+
* @related norm ( )
|
|
392
|
+
*/
|
|
393
|
+
public float angle (RPoint p)
|
|
394
|
+
{
|
|
395
|
+
float normp = p.norm();
|
|
396
|
+
float normthis = norm();
|
|
397
|
+
return (float)Math.acos(mult(p)/(normp*normthis));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Use this to obtain the distance between the vector and another vector
|
|
402
|
+
* @eexample RPoint_dist
|
|
403
|
+
* @usage Geometry
|
|
404
|
+
* @param p the vector relative to which we want to evaluate the distance
|
|
405
|
+
* @return float, the distance between the two vectors
|
|
406
|
+
* @related norm ( )
|
|
407
|
+
*/
|
|
408
|
+
public float dist (RPoint p)
|
|
409
|
+
{
|
|
410
|
+
float dx = (p.x-this.x);
|
|
411
|
+
float dy = (p.y-this.y);
|
|
412
|
+
return (float)Math.sqrt(dx*dx + dy*dy);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
public void print(){
|
|
417
|
+
System.out.print("("+x+","+y+")\n");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
@@ -0,0 +1,1110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2004-2008 Ricard Marxer <email@ricardmarxer.com>
|
|
3
|
+
*
|
|
4
|
+
This file is part of Geomerative.
|
|
5
|
+
*
|
|
6
|
+
* Geomerative is free software: you can redistribute it and/or modify it under
|
|
7
|
+
* the terms of the GNU General Public License as published by the Free Software
|
|
8
|
+
* Foundation, either version 3 of the License, or (at your option) any later
|
|
9
|
+
* version.
|
|
10
|
+
*
|
|
11
|
+
* Geomerative is distributed in the hope that it will be useful, but WITHOUT
|
|
12
|
+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
13
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
14
|
+
* details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU General Public License along with
|
|
17
|
+
* Geomerative. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
package geomerative;
|
|
20
|
+
|
|
21
|
+
import processing.core.*;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* RPolygon is a reduced interface for creating, holding and drawing complex
|
|
25
|
+
* polygons. Polygons are groups of one or more contours (RContour). This
|
|
26
|
+
* interface allows us to perform binary operations (difference, xor, union and
|
|
27
|
+
* intersection) on polygons.
|
|
28
|
+
*
|
|
29
|
+
* @eexample RPolygon
|
|
30
|
+
* @usage Geometry
|
|
31
|
+
* @related RContour
|
|
32
|
+
* @related createCircle ( )
|
|
33
|
+
* @related createRing ( )
|
|
34
|
+
* @related createStar ( )
|
|
35
|
+
* @related diff ( )
|
|
36
|
+
* @related xor ( )
|
|
37
|
+
* @related union ( )
|
|
38
|
+
* @related intersection ( )
|
|
39
|
+
* @extended
|
|
40
|
+
*/
|
|
41
|
+
public class RPolygon extends RGeomElem {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @invisible
|
|
45
|
+
*/
|
|
46
|
+
public int type = RGeomElem.POLYGON;
|
|
47
|
+
public static int defaultDetail = 50;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Array of RContour objects holding the contours of the polygon.
|
|
51
|
+
*
|
|
52
|
+
* @eexample contours
|
|
53
|
+
* @related RContour
|
|
54
|
+
* @related countContours ( )
|
|
55
|
+
* @related addContour ( )
|
|
56
|
+
*/
|
|
57
|
+
public RContour[] contours;
|
|
58
|
+
int currentContour = 0;
|
|
59
|
+
|
|
60
|
+
// ----------------------
|
|
61
|
+
// --- Public Methods ---
|
|
62
|
+
// ----------------------
|
|
63
|
+
/**
|
|
64
|
+
* Make a copy of the given polygon.
|
|
65
|
+
*
|
|
66
|
+
* @eexample createPolygon
|
|
67
|
+
* @param p the object of which to make a copy
|
|
68
|
+
*/
|
|
69
|
+
public RPolygon(RPolygon p) {
|
|
70
|
+
if (p == null) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (int i = 0; i < p.countContours(); i++) {
|
|
75
|
+
this.append(new RContour(p.contours[i]));
|
|
76
|
+
}
|
|
77
|
+
type = RGeomElem.POLYGON;
|
|
78
|
+
|
|
79
|
+
setStyle(p);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Create a new polygon given an array of points.
|
|
84
|
+
*
|
|
85
|
+
* @eexample createPolygon
|
|
86
|
+
* @param points the points for the new polygon.
|
|
87
|
+
*/
|
|
88
|
+
public RPolygon(RPoint[] points) {
|
|
89
|
+
this(new RContour(points));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create a new polygon given a contour.
|
|
94
|
+
*
|
|
95
|
+
* @param newcontour the contour for the new polygon.
|
|
96
|
+
*/
|
|
97
|
+
public RPolygon(RContour newcontour) {
|
|
98
|
+
this.append(newcontour);
|
|
99
|
+
type = RGeomElem.POLYGON;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Create an empty polygon.
|
|
104
|
+
*/
|
|
105
|
+
public RPolygon() {
|
|
106
|
+
contours = null;
|
|
107
|
+
type = RGeomElem.POLYGON;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Use this method to create a new circle polygon.
|
|
112
|
+
*
|
|
113
|
+
* @param x
|
|
114
|
+
* @param y
|
|
115
|
+
* @eexample createCircle
|
|
116
|
+
* @param radius the radius of the circle
|
|
117
|
+
* @param detail the number of vertices of the polygon
|
|
118
|
+
* @return RPolygon, the circular polygon newly created
|
|
119
|
+
*/
|
|
120
|
+
static public RPolygon createCircle(float x, float y, float radius, int detail) {
|
|
121
|
+
RPoint[] points = new RPoint[detail];
|
|
122
|
+
double radiansPerStep = 2 * Math.PI / detail;
|
|
123
|
+
for (int i = 0; i < detail; i++) {
|
|
124
|
+
points[i] = new RPoint(
|
|
125
|
+
radius * Math.cos(i * radiansPerStep) + x,
|
|
126
|
+
radius * Math.sin(i * radiansPerStep) + y
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
return new RPolygon(points);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static public RPolygon createCircle(float radius, int detail) {
|
|
133
|
+
return createCircle(0, 0, radius, detail);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static public RPolygon createCircle(float x, float y, float radius) {
|
|
137
|
+
return createCircle(x, y, radius, defaultDetail);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static public RPolygon createCircle(float radius) {
|
|
141
|
+
return createCircle(0, 0, radius, defaultDetail);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Use this method to create a new rectangle polygon.
|
|
146
|
+
*
|
|
147
|
+
* @eexample createRectangle
|
|
148
|
+
* @param x the upper-left corner x coordinate
|
|
149
|
+
* @param y the upper-left corner y coordinate
|
|
150
|
+
* @param w the width
|
|
151
|
+
* @param h the height
|
|
152
|
+
* @return RPolygon, the circular polygon newly created
|
|
153
|
+
*/
|
|
154
|
+
static public RPolygon createRectangle(float x, float y, float w, float h) {
|
|
155
|
+
RPolygon rectangle = new RPolygon();
|
|
156
|
+
rectangle.addPoint(x, y);
|
|
157
|
+
rectangle.addPoint(x + w, y);
|
|
158
|
+
rectangle.addPoint(x + w, y + h);
|
|
159
|
+
rectangle.addPoint(x, y + h);
|
|
160
|
+
rectangle.addPoint(x, y);
|
|
161
|
+
return rectangle;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static public RPolygon createRectangle(float w, float h) {
|
|
165
|
+
return createRectangle(0, 0, w, h);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Use this method to create a new starform polygon.
|
|
170
|
+
*
|
|
171
|
+
* @param x
|
|
172
|
+
* @param y
|
|
173
|
+
* @eexample createStar
|
|
174
|
+
* @param radiusBig the outter radius of the star polygon
|
|
175
|
+
* @param radiusSmall the inner radius of the star polygon
|
|
176
|
+
* @param spikes the amount of spikes on the star polygon
|
|
177
|
+
* @return RPolygon, the starform polygon newly created
|
|
178
|
+
*/
|
|
179
|
+
static public RPolygon createStar(float x, float y, float radiusBig, float radiusSmall, int spikes) {
|
|
180
|
+
int numPoints = spikes * 2;
|
|
181
|
+
RPoint[] points = new RPoint[numPoints];
|
|
182
|
+
double radiansPerStep = Math.PI / spikes;
|
|
183
|
+
for (int i = 0; i < numPoints; i += 2) {
|
|
184
|
+
points[i] = new RPoint(
|
|
185
|
+
radiusBig * Math.cos(i * radiansPerStep) + x,
|
|
186
|
+
radiusBig * Math.sin(i * radiansPerStep) + y
|
|
187
|
+
);
|
|
188
|
+
points[i + 1] = new RPoint(
|
|
189
|
+
radiusSmall * Math.cos(i * radiansPerStep) + x,
|
|
190
|
+
radiusSmall * Math.sin(i * radiansPerStep) + y
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return new RPolygon(points);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static public RPolygon createStar(float radiusBig, float radiusSmall, int spikes) {
|
|
197
|
+
return createStar(0, 0, radiusBig, radiusSmall, spikes);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Use this method to create a new ring polygon.
|
|
202
|
+
*
|
|
203
|
+
* @param x
|
|
204
|
+
* @param y
|
|
205
|
+
* @eexample createRing
|
|
206
|
+
* @param radiusBig the outter radius of the ring polygon
|
|
207
|
+
* @param radiusSmall the inner radius of the ring polygon
|
|
208
|
+
* @param detail the number of vertices on each contour of the ring
|
|
209
|
+
* @return RPolygon, the ring polygon newly created
|
|
210
|
+
*/
|
|
211
|
+
static public RPolygon createRing(float x, float y, float radiusBig, float radiusSmall, int detail) {
|
|
212
|
+
RPoint[] inner = new RPoint[detail];
|
|
213
|
+
RPoint[] outer = new RPoint[detail];
|
|
214
|
+
double radiansPerStep = 2 * Math.PI / detail;
|
|
215
|
+
for (int i = 0; i < detail; i++) {
|
|
216
|
+
inner[i] = new RPoint(
|
|
217
|
+
radiusSmall * Math.cos(i * radiansPerStep) + x,
|
|
218
|
+
radiusSmall * Math.sin(i * radiansPerStep) + y
|
|
219
|
+
);
|
|
220
|
+
outer[i] = new RPoint(
|
|
221
|
+
radiusBig * Math.cos(i * radiansPerStep) + x,
|
|
222
|
+
radiusBig * Math.sin(i * radiansPerStep) + y
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
RPolygon ring = new RPolygon();
|
|
226
|
+
ring.addContour(outer);
|
|
227
|
+
ring.addContour(inner);
|
|
228
|
+
return ring;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static public RPolygon createRing(float radiusBig, float radiusSmall, int detail) {
|
|
232
|
+
return createRing(0, 0, radiusBig, radiusSmall, detail);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
static public RPolygon createRing(float x, float y, float radiusBig, float radiusSmall) {
|
|
236
|
+
return createRing(x, y, radiusBig, radiusSmall, defaultDetail);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static public RPolygon createRing(float radiusBig, float radiusSmall) {
|
|
240
|
+
return createRing(0, 0, radiusBig, radiusSmall, defaultDetail);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Use this method to get the centroid of the element.
|
|
245
|
+
*
|
|
246
|
+
* @eexample RGroup_getCentroid
|
|
247
|
+
* @return RPo the centroid point of the element
|
|
248
|
+
* @related getBounds ( )
|
|
249
|
+
* @related getCenter ( )
|
|
250
|
+
*/
|
|
251
|
+
@Override
|
|
252
|
+
public RPoint getCentroid() {
|
|
253
|
+
RPoint bestCentroid = new RPoint();
|
|
254
|
+
float bestArea = Float.NEGATIVE_INFINITY;
|
|
255
|
+
if (contours != null) {
|
|
256
|
+
for (RContour contour : contours) {
|
|
257
|
+
float area = Math.abs(contour.getArea());
|
|
258
|
+
if (area > bestArea) {
|
|
259
|
+
bestArea = area;
|
|
260
|
+
bestCentroid = contour.getCentroid();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return bestCentroid;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Use this method to count the number of contours in the polygon.
|
|
270
|
+
*
|
|
271
|
+
* @eexample countContours
|
|
272
|
+
* @return int the number contours in the polygon
|
|
273
|
+
* @related addContour ( )
|
|
274
|
+
*/
|
|
275
|
+
public int countContours() {
|
|
276
|
+
if (this.contours == null) {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return this.contours.length;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Add a new contour to the polygon.
|
|
285
|
+
*
|
|
286
|
+
* @eexample addContour
|
|
287
|
+
* @param c the contour to be added
|
|
288
|
+
* @related addPoint ( )
|
|
289
|
+
*/
|
|
290
|
+
public void addContour(RContour c) {
|
|
291
|
+
this.append(c);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Add an empty contour to the polygon.
|
|
296
|
+
*
|
|
297
|
+
* @eexample addContour
|
|
298
|
+
* @related addPoint ( )
|
|
299
|
+
*/
|
|
300
|
+
public void addContour() {
|
|
301
|
+
this.append(new RContour());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Add a new contour to the polygon given an array of points.
|
|
306
|
+
*
|
|
307
|
+
* @eexample addContour
|
|
308
|
+
* @param points the points of the new contour to be added
|
|
309
|
+
* @related addPoint ( )
|
|
310
|
+
*/
|
|
311
|
+
public void addContour(RPoint[] points) {
|
|
312
|
+
this.append(new RContour(points));
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Use this method to set the current contour to which append points.
|
|
317
|
+
*
|
|
318
|
+
* @param indContour
|
|
319
|
+
* @eexample addContour
|
|
320
|
+
* @related addPoint ( )
|
|
321
|
+
*/
|
|
322
|
+
public void setContour(int indContour) {
|
|
323
|
+
this.currentContour = indContour;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Add a new point to the current contour.
|
|
328
|
+
*
|
|
329
|
+
* @eexample addPoint
|
|
330
|
+
* @param p the point to be added
|
|
331
|
+
* @related addContour ( )
|
|
332
|
+
* @related setCurrent ( )
|
|
333
|
+
*/
|
|
334
|
+
public void addPoint(RPoint p) {
|
|
335
|
+
if (contours == null) {
|
|
336
|
+
this.append(new RContour());
|
|
337
|
+
}
|
|
338
|
+
this.contours[currentContour].append(p);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Add a new point to the current contour.
|
|
343
|
+
*
|
|
344
|
+
* @eexample addPoint
|
|
345
|
+
* @param x the x coordinate of the point to be added
|
|
346
|
+
* @param y the y coordinate of the point to be added
|
|
347
|
+
* @related addContour ( )
|
|
348
|
+
* @related setCurrent ( )
|
|
349
|
+
*/
|
|
350
|
+
public void addPoint(float x, float y) {
|
|
351
|
+
if (contours == null) {
|
|
352
|
+
this.append(new RContour());
|
|
353
|
+
}
|
|
354
|
+
this.contours[currentContour].append(new RPoint(x, y));
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Add a new point to the selected contour.
|
|
359
|
+
*
|
|
360
|
+
* @eexample addPoint
|
|
361
|
+
* @param indContour the index of the contour to which the point will be
|
|
362
|
+
* added
|
|
363
|
+
* @param p the point to be added
|
|
364
|
+
* @related addContour ( )
|
|
365
|
+
* @related setCurrent ( )
|
|
366
|
+
*/
|
|
367
|
+
public void addPoint(int indContour, RPoint p) {
|
|
368
|
+
if (contours == null) {
|
|
369
|
+
this.append(new RContour());
|
|
370
|
+
}
|
|
371
|
+
this.contours[indContour].append(p);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Add a new point to the selected contour.
|
|
376
|
+
*
|
|
377
|
+
* @eexample addPoint
|
|
378
|
+
* @param indContour the index of the contour to which the point will be
|
|
379
|
+
* added
|
|
380
|
+
* @param x the x coordinate of the point to be added
|
|
381
|
+
* @param y the y coordinate of the point to be added
|
|
382
|
+
* @related addContour ( )
|
|
383
|
+
* @related setCurrent ( )
|
|
384
|
+
*/
|
|
385
|
+
public void addPoint(int indContour, float x, float y) {
|
|
386
|
+
if (contours == null) {
|
|
387
|
+
this.append(new RContour());
|
|
388
|
+
}
|
|
389
|
+
this.contours[indContour].append(new RPoint(x, y));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
public void addClose() {
|
|
393
|
+
if (contours == null) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
contours[contours.length - 1].addClose();
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Use this method to create a new mesh from a given polygon.
|
|
402
|
+
*
|
|
403
|
+
* @eexample toMesh
|
|
404
|
+
* @return RMesh, the mesh made of tristrips resulting of a tesselation of
|
|
405
|
+
* the polygon
|
|
406
|
+
* @related draw ( )
|
|
407
|
+
*/
|
|
408
|
+
@Override
|
|
409
|
+
public RMesh toMesh() {
|
|
410
|
+
if (contours == null) {
|
|
411
|
+
return new RMesh();
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
RMesh mesh = RClip.polygonToMesh(this);
|
|
415
|
+
if (mesh == null) {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
mesh.setStyle(this);
|
|
420
|
+
return mesh;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
@Override
|
|
424
|
+
public void print() {
|
|
425
|
+
System.out.println("polygon: ");
|
|
426
|
+
for (int i = 0; i < countContours(); i++) {
|
|
427
|
+
System.out.println("--- contour " + i + " ---");
|
|
428
|
+
contours[i].print();
|
|
429
|
+
System.out.println("---------------");
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Removes contours with less than 3 points. These are contours that are
|
|
435
|
+
* open. Since close polygons have points[0] == points[-1] and two more
|
|
436
|
+
* points to form a triangle at least. This is useful to avoid the clipping
|
|
437
|
+
* algorithm from breaking.
|
|
438
|
+
*
|
|
439
|
+
* @return
|
|
440
|
+
* @invisible
|
|
441
|
+
*/
|
|
442
|
+
protected RPolygon removeOpenContours() {
|
|
443
|
+
RPolygon clean = new RPolygon();
|
|
444
|
+
for (int i = 0; i < countContours(); i++) {
|
|
445
|
+
if (contours[i].countPoints() > 3) {
|
|
446
|
+
clean.addContour(contours[i]);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
clean.setStyle(this);
|
|
450
|
+
return clean;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* @return @invisible
|
|
455
|
+
*/
|
|
456
|
+
@Override
|
|
457
|
+
public RPolygon toPolygon() {
|
|
458
|
+
return new RPolygon(this);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* @return @invisible
|
|
463
|
+
*/
|
|
464
|
+
@Override
|
|
465
|
+
public RShape toShape() {
|
|
466
|
+
int numContours = countContours();
|
|
467
|
+
|
|
468
|
+
RShape result = new RShape();
|
|
469
|
+
for (int i = 0; i < numContours; i++) {
|
|
470
|
+
RPoint[] newpoints = this.contours[i].getHandles();
|
|
471
|
+
|
|
472
|
+
if (newpoints != null) {
|
|
473
|
+
result.addMoveTo(newpoints[0]);
|
|
474
|
+
|
|
475
|
+
for (int j = 1; j < newpoints.length; j++) {
|
|
476
|
+
result.addLineTo(newpoints[j]);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
if (contours[i].closed) {
|
|
480
|
+
result.addClose();
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
result.paths[i].setStyle(contours[i]);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
result.setStyle(this);
|
|
488
|
+
return result;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Use this to return the points of the polygon. It returns the points in
|
|
493
|
+
* the way of an array of RPoint.
|
|
494
|
+
*
|
|
495
|
+
* @eexample RPolygon_getHandles
|
|
496
|
+
* @return RPoint[], the points returned in an array.
|
|
497
|
+
*
|
|
498
|
+
*/
|
|
499
|
+
@Override
|
|
500
|
+
public RPoint[] getHandles() {
|
|
501
|
+
int numContours = countContours();
|
|
502
|
+
if (numContours == 0) {
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
RPoint[] result = null;
|
|
507
|
+
RPoint[] newresult = null;
|
|
508
|
+
for (int i = 0; i < numContours; i++) {
|
|
509
|
+
RPoint[] newPoints = contours[i].getHandles();
|
|
510
|
+
if (newPoints != null) {
|
|
511
|
+
if (result == null) {
|
|
512
|
+
result = new RPoint[newPoints.length];
|
|
513
|
+
System.arraycopy(newPoints, 0, result, 0, newPoints.length);
|
|
514
|
+
} else {
|
|
515
|
+
newresult = new RPoint[result.length + newPoints.length];
|
|
516
|
+
System.arraycopy(result, 0, newresult, 0, result.length);
|
|
517
|
+
System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
|
|
518
|
+
result = newresult;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Use this to return the points of the polygon. It returns the points in
|
|
527
|
+
* the way of an array of RPoint.
|
|
528
|
+
*
|
|
529
|
+
* @eexample RPolygon_getPoints
|
|
530
|
+
* @return RPoint[], the points returned in an array.
|
|
531
|
+
*
|
|
532
|
+
*/
|
|
533
|
+
@Override
|
|
534
|
+
public RPoint[] getPoints() {
|
|
535
|
+
int numContours = countContours();
|
|
536
|
+
if (numContours == 0) {
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
RPoint[] result = null;
|
|
541
|
+
RPoint[] newresult = null;
|
|
542
|
+
for (int i = 0; i < numContours; i++) {
|
|
543
|
+
RPoint[] newPoints = contours[i].getPoints();
|
|
544
|
+
if (newPoints != null) {
|
|
545
|
+
if (result == null) {
|
|
546
|
+
result = new RPoint[newPoints.length];
|
|
547
|
+
System.arraycopy(newPoints, 0, result, 0, newPoints.length);
|
|
548
|
+
} else {
|
|
549
|
+
newresult = new RPoint[result.length + newPoints.length];
|
|
550
|
+
System.arraycopy(result, 0, newresult, 0, result.length);
|
|
551
|
+
System.arraycopy(newPoints, 0, newresult, result.length, newPoints.length);
|
|
552
|
+
result = newresult;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return result;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Use this method to get the type of element this is.
|
|
561
|
+
*
|
|
562
|
+
* @eexample RPolygon_getType
|
|
563
|
+
* @return int, will allways return RGeomElem.POLYGON
|
|
564
|
+
*/
|
|
565
|
+
@Override
|
|
566
|
+
public int getType() {
|
|
567
|
+
return type;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Use this method to get the area covered by the polygon.
|
|
572
|
+
*
|
|
573
|
+
* @eexample getArea
|
|
574
|
+
* @return float, the area covered by the polygon
|
|
575
|
+
* @related draw ( )
|
|
576
|
+
*/
|
|
577
|
+
@Override
|
|
578
|
+
public float getArea() {
|
|
579
|
+
if (getNumPoints() < 3) {
|
|
580
|
+
return 0.0F;
|
|
581
|
+
}
|
|
582
|
+
float ax = getX(0);
|
|
583
|
+
float ay = getY(0);
|
|
584
|
+
float area = 0.0F;
|
|
585
|
+
for (int i = 1; i < (getNumPoints() - 1); i++) {
|
|
586
|
+
float bx = getX(i);
|
|
587
|
+
float by = getY(i);
|
|
588
|
+
float cx = getX(i + 1);
|
|
589
|
+
float cy = getY(i + 1);
|
|
590
|
+
float tarea = ((cx - bx) * (ay - by)) - ((ax - bx) * (cy - by));
|
|
591
|
+
area += tarea;
|
|
592
|
+
}
|
|
593
|
+
area = 0.5F * Math.abs(area);
|
|
594
|
+
return area;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Use this method to draw the polygon.
|
|
599
|
+
*
|
|
600
|
+
* @eexample drawPolygon
|
|
601
|
+
* @param g PGraphics, the graphics object on which to draw the polygon
|
|
602
|
+
* @related draw ( )
|
|
603
|
+
*/
|
|
604
|
+
@Override
|
|
605
|
+
public void draw(PGraphics g) {
|
|
606
|
+
int numContours = countContours();
|
|
607
|
+
if (numContours != 0) {
|
|
608
|
+
if (isIn(g)) {
|
|
609
|
+
if (!RG.ignoreStyles) {
|
|
610
|
+
saveContext(g);
|
|
611
|
+
setContext(g);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Check whether to draw the fill or not
|
|
615
|
+
if (g.fill) {
|
|
616
|
+
// Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
|
|
617
|
+
// NOTE: there's currently no way of drawing the outline of a mesh, since no information is kept about what vertices are at the edge
|
|
618
|
+
|
|
619
|
+
// Save the information about the current stroke color and turn off
|
|
620
|
+
boolean stroking = g.stroke;
|
|
621
|
+
g.noStroke();
|
|
622
|
+
|
|
623
|
+
// Save smoothing state and turn off
|
|
624
|
+
// boolean smoothing = g.smooth;
|
|
625
|
+
try {
|
|
626
|
+
|
|
627
|
+
g.noSmooth();
|
|
628
|
+
|
|
629
|
+
} catch (Exception e) {
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
RMesh tempMesh = this.toMesh();
|
|
633
|
+
tempMesh.draw(g);
|
|
634
|
+
|
|
635
|
+
// Restore the old stroke color
|
|
636
|
+
if (stroking) {
|
|
637
|
+
g.stroke(g.strokeColor);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Check whether to draw the stroke or not
|
|
643
|
+
if (g.stroke) {
|
|
644
|
+
for (int i = 0; i < numContours; i++) {
|
|
645
|
+
contours[i].draw(g);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (!RG.ignoreStyles) {
|
|
650
|
+
restoreContext(g);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
*
|
|
658
|
+
* @param g
|
|
659
|
+
*/
|
|
660
|
+
@Override
|
|
661
|
+
public void draw(PApplet g) {
|
|
662
|
+
int numContours = countContours();
|
|
663
|
+
if (numContours != 0) {
|
|
664
|
+
if (isIn(g)) {
|
|
665
|
+
if (!RG.ignoreStyles) {
|
|
666
|
+
saveContext(g);
|
|
667
|
+
setContext(g);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// Check whether to draw the fill or not
|
|
671
|
+
if (g.g.fill) {
|
|
672
|
+
// Since we are drawing the different tristrips we must turn off the stroke or make it the same color as the fill
|
|
673
|
+
// NOTE: there's currently no way of drawing the outline of a mesh, since no information is kept about what vertices are at the edge
|
|
674
|
+
|
|
675
|
+
// Save the information about the current stroke color and turn off
|
|
676
|
+
boolean stroking = g.g.stroke;
|
|
677
|
+
g.noStroke();
|
|
678
|
+
|
|
679
|
+
RMesh tempMesh = this.toMesh();
|
|
680
|
+
if (tempMesh != null) {
|
|
681
|
+
tempMesh.draw(g);
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Restore the old stroke color
|
|
685
|
+
if (stroking) {
|
|
686
|
+
g.stroke(g.g.strokeColor);
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Check whether to draws the stroke or not
|
|
692
|
+
if (g.g.stroke) {
|
|
693
|
+
for (int i = 0; i < numContours; i++) {
|
|
694
|
+
contours[i].draw(g);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
if (!RG.ignoreStyles) {
|
|
699
|
+
restoreContext(g);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Use this method to get the intersection of this polygon with the polygon
|
|
707
|
+
* passed in as a parameter.
|
|
708
|
+
*
|
|
709
|
+
* @eexample intersection
|
|
710
|
+
* @param p RPolygon, the polygon with which to perform the intersection
|
|
711
|
+
* @return RPolygon, the intersection of the two polygons
|
|
712
|
+
* @related union ( )
|
|
713
|
+
* @related xor ( )
|
|
714
|
+
* @related diff ( )
|
|
715
|
+
*/
|
|
716
|
+
public RPolygon intersection(RPolygon p) {
|
|
717
|
+
RPolygon res = RClip.intersection(p, this);
|
|
718
|
+
res.setStyle(this.getStyle());
|
|
719
|
+
return res;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Use this method to get the union of this polygon with the polygon passed
|
|
724
|
+
* in as a parameter.
|
|
725
|
+
*
|
|
726
|
+
* @eexample union
|
|
727
|
+
* @param p RPolygon, the polygon with which to perform the union
|
|
728
|
+
* @return RPolygon, the union of the two polygons
|
|
729
|
+
* @related intersection ( )
|
|
730
|
+
* @related xor ( )
|
|
731
|
+
* @related diff ( )
|
|
732
|
+
*/
|
|
733
|
+
public RPolygon union(RPolygon p) {
|
|
734
|
+
RPolygon res = RClip.union(p, this);
|
|
735
|
+
res.setStyle(this.getStyle());
|
|
736
|
+
return res;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
/**
|
|
740
|
+
* Use this method to get the xor of this polygon with the polygon passed in
|
|
741
|
+
* as a parameter.
|
|
742
|
+
*
|
|
743
|
+
* @eexample xor
|
|
744
|
+
* @param p RPolygon, the polygon with which to perform the xor
|
|
745
|
+
* @return RPolygon, the xor of the two polygons
|
|
746
|
+
* @related union ( )
|
|
747
|
+
* @related intersection ( )
|
|
748
|
+
* @related diff ( )
|
|
749
|
+
*/
|
|
750
|
+
public RPolygon xor(RPolygon p) {
|
|
751
|
+
RPolygon res = RClip.xor(p, this);
|
|
752
|
+
res.setStyle(this.getStyle());
|
|
753
|
+
return res;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Use this method to get the difference between this polygon and the
|
|
758
|
+
* polygon passed in as a parameter.
|
|
759
|
+
*
|
|
760
|
+
* @eexample diff
|
|
761
|
+
* @param p RPolygon, the polygon with which to perform the difference
|
|
762
|
+
* @return RPolygon, the difference of the two polygons
|
|
763
|
+
* @related union ( )
|
|
764
|
+
* @related xor ( )
|
|
765
|
+
* @related intersection ( )
|
|
766
|
+
*/
|
|
767
|
+
public RPolygon diff(RPolygon p) {
|
|
768
|
+
RPolygon res = RClip.diff(this, p);
|
|
769
|
+
res.setStyle(this.getStyle());
|
|
770
|
+
return res;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* Use this method to get a rebuilt version of a given polygon by removing
|
|
775
|
+
* extra points and solving intersecting contours or holes.
|
|
776
|
+
*
|
|
777
|
+
* @eexample RPolygon_update
|
|
778
|
+
* @return RPolygon, the updated polygon
|
|
779
|
+
* @related diff ( )
|
|
780
|
+
* @related union ( )
|
|
781
|
+
* @related xor ( )
|
|
782
|
+
* @related intersection ( )
|
|
783
|
+
*/
|
|
784
|
+
public RPolygon update() {
|
|
785
|
+
return RClip.update(this);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
@Override
|
|
789
|
+
public RPoint getPoint(float t) {
|
|
790
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
*
|
|
796
|
+
* @param t
|
|
797
|
+
* @return
|
|
798
|
+
*/
|
|
799
|
+
@Override
|
|
800
|
+
public RPoint getTangent(float t) {
|
|
801
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
*
|
|
807
|
+
* @return
|
|
808
|
+
*/
|
|
809
|
+
@Override
|
|
810
|
+
public RPoint[] getTangents() {
|
|
811
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
812
|
+
return null;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
*
|
|
817
|
+
* @return
|
|
818
|
+
*/
|
|
819
|
+
@Override
|
|
820
|
+
public RPoint[][] getPointsInPaths() {
|
|
821
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
822
|
+
return null;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
@Override
|
|
826
|
+
public RPoint[][] getHandlesInPaths() {
|
|
827
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
828
|
+
return null;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
@Override
|
|
832
|
+
public RPoint[][] getTangentsInPaths() {
|
|
833
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
@Override
|
|
838
|
+
public boolean contains(RPoint p) {
|
|
839
|
+
PApplet.println("Feature not yet implemented for this class.");
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/**
|
|
844
|
+
* Use this method to transform the polygon.
|
|
845
|
+
*
|
|
846
|
+
* @eexample RPolygon_transform
|
|
847
|
+
* @param m RMatrix, the matrix of the affine transformation to apply to the
|
|
848
|
+
* polygon
|
|
849
|
+
*/
|
|
850
|
+
/*
|
|
851
|
+
public void transform(RMatrix m){
|
|
852
|
+
int numContours = countContours();
|
|
853
|
+
if(numContours!=0){
|
|
854
|
+
for(int i=0;i<numContours;i++){
|
|
855
|
+
contours[i].transform(m);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
*/
|
|
860
|
+
// ----------------------
|
|
861
|
+
// --- Private Methods ---
|
|
862
|
+
// ----------------------
|
|
863
|
+
/**
|
|
864
|
+
* Remove all of the points. Creates an empty polygon.
|
|
865
|
+
*/
|
|
866
|
+
protected void clear() {
|
|
867
|
+
this.contours = null;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
/**
|
|
871
|
+
* Add a point to the first inner polygon.
|
|
872
|
+
*
|
|
873
|
+
* @param x
|
|
874
|
+
* @param y
|
|
875
|
+
*/
|
|
876
|
+
protected void add(float x, float y) {
|
|
877
|
+
if (contours == null) {
|
|
878
|
+
this.append(new RContour());
|
|
879
|
+
}
|
|
880
|
+
this.contours[0].append(new RPoint(x, y));
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Add a point to the first inner polygon.
|
|
885
|
+
*
|
|
886
|
+
* @param p
|
|
887
|
+
*/
|
|
888
|
+
protected void add(RPoint p) {
|
|
889
|
+
if (contours == null) {
|
|
890
|
+
this.append(new RContour());
|
|
891
|
+
}
|
|
892
|
+
this.contours[0].append(p);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Add an inner polygon to this polygon - assumes that adding polygon does
|
|
897
|
+
* not have any inner polygons.
|
|
898
|
+
*
|
|
899
|
+
* @param p
|
|
900
|
+
*/
|
|
901
|
+
protected void add(RPolygon p) {
|
|
902
|
+
/*if (this.contours.length > 0 && this.isHole){
|
|
903
|
+
throw new IllegalStateException("Cannot add polys to something designated as a hole.");
|
|
904
|
+
}*/
|
|
905
|
+
RContour c = new RContour();
|
|
906
|
+
for (int i = 0; i < p.getNumPoints(); i++) {
|
|
907
|
+
c.addPoint(p.getX(i), p.getY(i));
|
|
908
|
+
}
|
|
909
|
+
this.append(c);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Add an inner polygon to this polygon - assumes that adding polygon does
|
|
914
|
+
* not have any inner polygons.
|
|
915
|
+
*
|
|
916
|
+
* @param c
|
|
917
|
+
*/
|
|
918
|
+
protected void add(RContour c) {
|
|
919
|
+
/*if (this.contours.length > 0 && this.isHole){
|
|
920
|
+
throw new IllegalStateException("Cannot add polys to something designated as a hole.");
|
|
921
|
+
}*/
|
|
922
|
+
this.append(c);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* Return true if the polygon is empty
|
|
927
|
+
*
|
|
928
|
+
* @return
|
|
929
|
+
*/
|
|
930
|
+
protected boolean isEmpty() {
|
|
931
|
+
return (this.contours == null);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* Returns the bounding box of the polygon.
|
|
936
|
+
*
|
|
937
|
+
* @return
|
|
938
|
+
*/
|
|
939
|
+
protected RRectangle getBBox() {
|
|
940
|
+
if (this.contours == null) {
|
|
941
|
+
return new RRectangle();
|
|
942
|
+
} else if (this.contours.length == 1) {
|
|
943
|
+
|
|
944
|
+
float xmin = Float.MAX_VALUE;
|
|
945
|
+
float ymin = Float.MAX_VALUE;
|
|
946
|
+
float xmax = -Float.MAX_VALUE;
|
|
947
|
+
float ymax = -Float.MAX_VALUE;
|
|
948
|
+
|
|
949
|
+
if (this.contours[0].points == null) {
|
|
950
|
+
return new RRectangle();
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
for (RPoint point : this.contours[0].points) {
|
|
954
|
+
float x = point.getX();
|
|
955
|
+
float y = point.getY();
|
|
956
|
+
if (x < xmin) {
|
|
957
|
+
xmin = x;
|
|
958
|
+
}
|
|
959
|
+
if (x > xmax) {
|
|
960
|
+
xmax = x;
|
|
961
|
+
}
|
|
962
|
+
if (y < ymin) {
|
|
963
|
+
ymin = y;
|
|
964
|
+
}
|
|
965
|
+
if (y > ymax) {
|
|
966
|
+
ymax = y;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
return new RRectangle(xmin, ymin, (xmax - xmin), (ymax - ymin));
|
|
971
|
+
} else {
|
|
972
|
+
throw new UnsupportedOperationException("getBounds not supported on complex poly.");
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/**
|
|
977
|
+
* Returns the polygon at this index.
|
|
978
|
+
*
|
|
979
|
+
* @param polyIndex
|
|
980
|
+
* @return
|
|
981
|
+
*/
|
|
982
|
+
protected RPolygon getInnerPoly(int polyIndex) {
|
|
983
|
+
return new RPolygon(this.contours[polyIndex]);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Returns the number of inner polygons - inner polygons are assumed to
|
|
988
|
+
* return one here.
|
|
989
|
+
*
|
|
990
|
+
* @return
|
|
991
|
+
*/
|
|
992
|
+
protected int getNumInnerPoly() {
|
|
993
|
+
if (this.contours == null) {
|
|
994
|
+
return 0;
|
|
995
|
+
}
|
|
996
|
+
return this.contours.length;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Return the number points of the first inner polygon
|
|
1001
|
+
*
|
|
1002
|
+
* @return
|
|
1003
|
+
*/
|
|
1004
|
+
protected int getNumPoints() {
|
|
1005
|
+
if (this.contours == null) {
|
|
1006
|
+
return 0;
|
|
1007
|
+
}
|
|
1008
|
+
if (this.contours[0].points == null) {
|
|
1009
|
+
return 0;
|
|
1010
|
+
}
|
|
1011
|
+
return this.contours[0].points.length;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Return the X value of the point at the index in the first inner polygon
|
|
1016
|
+
*
|
|
1017
|
+
* @param index
|
|
1018
|
+
* @return
|
|
1019
|
+
*/
|
|
1020
|
+
protected float getX(int index) {
|
|
1021
|
+
if (this.contours == null) {
|
|
1022
|
+
return 0;
|
|
1023
|
+
}
|
|
1024
|
+
return this.contours[0].points[index].x;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Return the Y value of the point at the index in the first inner polygon
|
|
1029
|
+
*
|
|
1030
|
+
* @param index
|
|
1031
|
+
* @return
|
|
1032
|
+
*/
|
|
1033
|
+
protected float getY(int index) {
|
|
1034
|
+
if (this.contours == null) {
|
|
1035
|
+
return 0;
|
|
1036
|
+
}
|
|
1037
|
+
return this.contours[0].points[index].y;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Return true if this polygon is a hole. Holes are assumed to be inner
|
|
1042
|
+
* polygons of a more complex polygon.
|
|
1043
|
+
*
|
|
1044
|
+
* @return
|
|
1045
|
+
* @throws IllegalStateException if called on a complex polygon.
|
|
1046
|
+
*/
|
|
1047
|
+
public boolean isHole() {
|
|
1048
|
+
if (this.contours == null || this.contours.length > 1) {
|
|
1049
|
+
throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
|
|
1050
|
+
}
|
|
1051
|
+
return this.contours[0].isHole;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Set whether or not this polygon is a hole. Cannot be called on a complex
|
|
1056
|
+
* polygon.
|
|
1057
|
+
*
|
|
1058
|
+
* @param isHole
|
|
1059
|
+
* @throws IllegalStateException if called on a complex polygon.
|
|
1060
|
+
*/
|
|
1061
|
+
protected void setIsHole(boolean isHole) {
|
|
1062
|
+
if (this.contours == null || this.contours.length > 1) {
|
|
1063
|
+
throw new IllegalStateException("Cannot call on a poly made up of more than one poly.");
|
|
1064
|
+
}
|
|
1065
|
+
this.contours[0].isHole = isHole;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
/**
|
|
1069
|
+
* Return true if the given inner polygon is contributing to the set
|
|
1070
|
+
* operation. This method should NOT be used outside the Clip algorithm.
|
|
1071
|
+
*
|
|
1072
|
+
* @param polyIndex
|
|
1073
|
+
* @return
|
|
1074
|
+
*/
|
|
1075
|
+
protected boolean isContributing(int polyIndex) {
|
|
1076
|
+
return this.contours[polyIndex].isContributing;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Set whether or not this inner polygon is constributing to the set
|
|
1081
|
+
* operation. This method should NOT be used outside the Clip algorithm.
|
|
1082
|
+
*
|
|
1083
|
+
* @param polyIndex
|
|
1084
|
+
* @param contributes
|
|
1085
|
+
*/
|
|
1086
|
+
protected void setContributing(int polyIndex, boolean contributes) {
|
|
1087
|
+
/*
|
|
1088
|
+
if( this.contours.length != 1 )
|
|
1089
|
+
{
|
|
1090
|
+
throw new IllegalStateException( "Only applies to polys of size 1" );
|
|
1091
|
+
}
|
|
1092
|
+
*/
|
|
1093
|
+
this.contours[polyIndex].isContributing = contributes;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
private void append(RContour nextcontour) {
|
|
1097
|
+
RContour[] newcontours;
|
|
1098
|
+
if (contours == null) {
|
|
1099
|
+
newcontours = new RContour[1];
|
|
1100
|
+
newcontours[0] = nextcontour;
|
|
1101
|
+
currentContour = 0;
|
|
1102
|
+
} else {
|
|
1103
|
+
newcontours = new RContour[this.contours.length + 1];
|
|
1104
|
+
System.arraycopy(this.contours, 0, newcontours, 0, this.contours.length);
|
|
1105
|
+
newcontours[this.contours.length] = nextcontour;
|
|
1106
|
+
currentContour++;
|
|
1107
|
+
}
|
|
1108
|
+
this.contours = newcontours;
|
|
1109
|
+
}
|
|
1110
|
+
}
|