Passed
Push — master ( 0f24f3...f1f647 )
by Seth
03:04
created

docs.GenerateFigures.figurePathScale()   A

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
dl 0
loc 5
rs 10
1
package docs;
2
3
import org.gannacademy.cdf.graphics.Drawable;
4
import org.gannacademy.cdf.graphics.Image;
5
import org.gannacademy.cdf.graphics.Text;
6
import org.gannacademy.cdf.graphics.geom.Rectangle;
7
import org.gannacademy.cdf.graphics.geom.*;
8
import org.gannacademy.cdf.graphics.ui.AppWindow;
9
10
import java.awt.*;
11
import java.awt.geom.Rectangle2D;
12
import java.io.File;
13
import java.util.HashMap;
14
import java.util.Map;
15
16
import static org.gannacademy.cdf.graphics.Drawable.NO_STROKE;
17
import static org.gannacademy.cdf.graphics.ui.DrawingPanel.DEFAULT_HEIGHT;
18
import static org.gannacademy.cdf.graphics.ui.DrawingPanel.DEFAULT_WIDTH;
19
20
public class GenerateFigures extends AppWindow {
21
  private static final String BASE_PATH = "src/main/java/org/gannacademy/cdf/graphics";
22
  private static final double
23
          DIAGRAM_WIDTH = 200,
24
          DIAGRAM_HEIGHT = DIAGRAM_WIDTH / 1.618,
25
          POINT_DIAMETER = 4,
26
          ROUND_RECTANGLE_ARC_DIAMETER = 40,
27
          ARC_START_ANGLE = 70,
28
          ARC_EXTENT_ANGLE = 220,
29
          ARROW_SIDE = 10,
30
          ARC_START_SCALE = 2.0 / 3.0,
31
          ARC_EXTENT_SCALE = 2.0 / 3.0;
32
33
  private static final int
34
          BEZIER_CURVE_INTERPOLATIONS = 9;
35
36
  private static final Color
37
          DIAGRAM = Color.BLACK,
38
          BACKGROUND = Color.WHITE,
39
          POINT_FILL = Color.WHITE,
40
          HIGHLIGHT_1 = new Color(77, 122, 151),
41
          HIGHLIGHT_2 = new Color(248, 152, 29),
42
          HIGHLIGHT_3 = new Color(230, 100, 80),
43
          HIGHLIGHT_4 = new Color(80, 210, 80);
44
  private static final Font LABEL = new Font("Arial", Font.PLAIN, 12);
45
  private static final BasicStroke DASHED = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 1, new float[]{3, 3}, 0);
46
47
  private Rectangle2D bounds = new Rectangle2D.Double(0, 0, DIAGRAM_WIDTH, DIAGRAM_HEIGHT);
48
  private HashMap<String, Drawable> components;
49
50
  private static void emptyDir(File dir) {
51
    File[] contents = dir.listFiles();
52
    if (contents != null) {
53
      for (File file : contents) {
54
        if (file.isDirectory()) {
55
          emptyDir(file);
56
        }
57
        file.delete();
0 ignored issues
show
introduced by
Use "java.nio.Files#delete" here for better messages on error conditions.
Loading history...
introduced by
Do something with the "boolean" value returned by "delete".
Loading history...
58
      }
59
    }
60
  }
61
62
  private static void resetDir(String dir) {
63
    if (!new File(dir).mkdirs()) {
64
      emptyDir(new File(dir));
65
      System.out.println("Emptied " + dir);
66
    }
67
  }
68
69
  public static void main(String[] args) {
70
    new GenerateFigures();
71
  }
72
73
  private void saveFigure(String subpackage, String name) {
74
    double width = 0, height = 0;
75
    for (Map.Entry<String, Drawable> entry : components.entrySet()) {
76
      Drawable component = entry.getValue();
77
      if (component instanceof Text) {
78
        Text t = (Text) component;
79
        if (t.getX() + t.getWidth() > width) {
80
          width = t.getX() + t.getWidth();
81
        }
82
        if (t.getY() + t.getMaxDescent() > height) {
83
          height = t.getY() + t.getMaxDescent();
84
        }
85
      } else {
86
        if (component.getX() + component.getWidth() > width) {
87
          width = component.getX() + component.getWidth();
88
        }
89
        if (component.getY() + component.getHeight() > height) {
90
          height = component.getY() + component.getHeight();
91
        }
92
      }
93
    }
94
    saveFigure(subpackage, name, width + 1, height + 1);
95
  }
96
97
  private void saveFigure(String subpackage, String name, double width, double height) {
98
    getDrawingPanel().setBackground(BACKGROUND);
99
    getDrawingPanel().setSize((int) width, (int) height);
100
    getDrawingPanel().saveAs(BASE_PATH + (subpackage.length() > 0 ? "/" : "") + subpackage + "/doc-files/" + name + ".png", "PNG");
101
    System.out.println("Generated " + (int) width + "×" + (int) height + " PNG " + BASE_PATH + (subpackage.length() > 0 ? "/" : "") + subpackage + "/doc-files/" + name + ".png");
102
  }
103
104
  private Path arrow(double x, double y, double angle) {
105
    angle = Math.toRadians(angle);
106
    double
107
            x1 = x + Math.cos(angle + Math.PI * 8.0 / 9.0) * ARROW_SIDE,
108
            y1 = y + Math.sin(angle + Math.PI * 8.0 / 9.0) * ARROW_SIDE,
109
            x2 = x + Math.cos(angle + Math.PI * 10.0 / 9.0) * ARROW_SIDE,
110
            y2 = y + Math.sin(angle + Math.PI * 10.0 / 9.0) * ARROW_SIDE;
111
    Path arrow = new Path(getDrawingPanel());
112
    arrow.moveTo(x, y);
113
    arrow.lineTo(x1, y1);
114
    arrow.lineTo(x2, y2);
115
    arrow.lineTo(x, y);
116
    return arrow;
117
  }
118
119
  private void figureDrawingApp() {
120
    getDrawingPanel().clear();
121
    components.clear();
122
123
    Rectangle r = new Rectangle(200, 75, 200, 200, getDrawingPanel());
124
    r.setFillColor(Color.BLUE);
125
    Ellipse e = new Ellipse(250, 125, 200, 200, getDrawingPanel());
126
    e.setFillColor(new Color(255, 100, 100, 200));
127
128
    components.put("r", r);
129
    components.put("e", e);
130
    saveFigure("", "DrawingApp", DEFAULT_WIDTH, DEFAULT_HEIGHT);
131
  }
132
133
  private void figureWindowCoordinates() {
134
    resetComponents();
135
    components.remove("rightEdge").removeFromDrawingPanel();
136
    components.remove("bottomEdge").removeFromDrawingPanel();
137
138
    Line
139
            xAxis = (Line) components.get("topEdge"),
140
            yAxis = (Line) components.get("leftEdge");
141
142
    Text
143
            originLabel = (Text) components.get("originLabel"),
144
            xAxisLabel = (Text) components.get("widthLabel"),
145
            yAxisLabel1 = (Text) components.get("heightLabel1"),
146
            yAxisLabel2 = (Text) components.get("heightLabel2"),
147
            yAxisLabel3 = (Text) components.get("heightLabel3"),
148
            ptLabel = new Text("(" + (int) (bounds.getWidth() * 2 / 3) + ", " + (int) (bounds.getHeight() * 2 / 3) + ")", 0, 0, getDrawingPanel());
149
    components.put("ptLabel", ptLabel);
150
151
    Path
152
            xAxisArrow = arrow(bounds.getX() + bounds.getWidth(), bounds.getY(), 0),
153
            yAxisArrow = arrow(bounds.getX(), bounds.getY() + bounds.getHeight(), 90);
154
    components.put("xAxisArrow", xAxisArrow);
155
    components.put("yAxisArrow", yAxisArrow);
156
157
    Ellipse pt = new Ellipse(
158
            bounds.getX() + bounds.getWidth() * 2 / 3 - POINT_DIAMETER / 2,
159
            bounds.getY() + bounds.getHeight() * 2 / 3 - POINT_DIAMETER / 2,
160
            POINT_DIAMETER,
161
            POINT_DIAMETER,
162
            getDrawingPanel()
163
    );
164
    components.put("pt", pt);
165
166
    originLabel.setText("(0, 0)");
167
168
    pt.setFillColor(DIAGRAM);
169
    pt.setStrokeColor(DIAGRAM);
170
171
    ptLabel.setFont(LABEL);
172
    ptLabel.setStrokeColor(pt.getFillColor());
173
    ptLabel.setLocation(pt.getX() - ptLabel.getWidth() / 2, pt.getY() - POINT_DIAMETER / 2 - ptLabel.getMaxDescent());
174
175
    xAxisLabel.setText("Positive X-axis →");
176
    xAxisLabel.setLocation(
177
            bounds.getX() + bounds.getWidth() / 2 - xAxisLabel.getWidth() / 2,
178
            bounds.getY() + xAxisLabel.getHeight()
179
    );
180
181
    yAxisLabel1.setText(" Positive");
182
    yAxisLabel2.setText(" Y-axis");
183
    yAxisLabel3.setText(" ↓");
184
185
    yAxisLabel2.setLocation(
186
            bounds.getX(),
187
            bounds.getY() + bounds.getHeight() / 2 - yAxisLabel2.getMaxAscent() / 2
188
    );
189
    yAxisLabel1.setLocation(yAxisLabel2.getX(), yAxisLabel2.getY() - yAxisLabel2.getHeight());
190
    yAxisLabel3.setLocation(yAxisLabel2.getX(), yAxisLabel2.getY() + yAxisLabel3.getHeight());
191
192
    xAxis.setLine(bounds.getX(), bounds.getY(), bounds.getX() + bounds.getWidth(), bounds.getY());
193
    xAxisArrow.setStroke(NO_STROKE);
194
    xAxisArrow.setFillColor(xAxis.getStrokeColor());
195
196
    yAxis.setLine(bounds.getX(), bounds.getY(), bounds.getX(), bounds.getY() + bounds.getHeight());
197
    yAxisArrow.setStroke(NO_STROKE);
198
    yAxisArrow.setFillColor(yAxis.getStrokeColor());
199
    saveFigure("", "window-coordinates");
200
  }
201
202
  private void figureStrokeFill() {
203
    getDrawingPanel().clear();
204
    components.clear();
205
206
    RoundRectangle roundRectangle = new RoundRectangle(
207
            0, 0, DIAGRAM_WIDTH, DIAGRAM_HEIGHT,
208
            DIAGRAM_HEIGHT / 3, DIAGRAM_HEIGHT / 3,
209
            getDrawingPanel()
210
    );
211
    components.put("roundRectangle", roundRectangle);
212
213
    Text
214
            strokeLabel = new Text("Stroke", 0, 0, getDrawingPanel()),
215
            fillLabel = new Text("Fill", 0, 0, getDrawingPanel());
216
    components.put("strokeLabel", strokeLabel);
217
    components.put("fillLabel", fillLabel);
218
219
    strokeLabel.setFont(new Font(LABEL.getFontName(), Font.BOLD, LABEL.getSize()));
220
    strokeLabel.setStrokeColor(Color.WHITE);
221
222
    fillLabel.setFont(strokeLabel.getFont());
223
224
    roundRectangle.setLocation(strokeLabel.getHeight() / 2, strokeLabel.getHeight() / 2);
225
    roundRectangle.setStroke(new BasicStroke((float) strokeLabel.getHeight(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
226
    roundRectangle.setStrokeColor(HIGHLIGHT_1);
227
    roundRectangle.setFillColor(HIGHLIGHT_2);
228
229
    strokeLabel.setLocation(
230
            roundRectangle.getX() + roundRectangle.getWidth() / 2 - strokeLabel.getWidth() / 2,
231
            roundRectangle.getY() - strokeLabel.getHeight() / 2 + strokeLabel.getMaxAscent()
232
    );
233
    strokeLabel.setStrokeColor(roundRectangle.getStrokeColor().brighter());
234
235
    fillLabel.setLocation(
236
            roundRectangle.getX() + roundRectangle.getWidth() / 2 - fillLabel.getWidth() / 2,
237
            roundRectangle.getY() + roundRectangle.getHeight() / 2 - fillLabel.getMaxAscent() / 2
238
    );
239
    fillLabel.setStrokeColor(roundRectangle.getFillColor().darker());
240
241
    saveFigure(
242
            "", "stroke-fill",
243
            roundRectangle.getWidth() + strokeLabel.getHeight(),
244
            roundRectangle.getHeight() + strokeLabel.getHeight()
245
    );
246
  }
247
248
  private void figureRectangle() {
249
    resetComponents();
250
    components.put("rectangle", new Rectangle(bounds.getX(), bounds.getY(), DIAGRAM_WIDTH, DIAGRAM_HEIGHT, getDrawingPanel()));
251
    saveFigure("geom", "Rectangle");
252
  }
253
254
  private void figureEllipse() {
255
    resetComponents();
256
    components.put("ellipse", new Ellipse(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(), getDrawingPanel()));
257
    saveFigure("geom", "Ellipse");
258
  }
259
260
  private void figureRoundRectangle() {
261
    resetComponents();
262
263
    Ellipse arc = new Ellipse(
264
            bounds.getX() + bounds.getWidth() - ROUND_RECTANGLE_ARC_DIAMETER,
265
            bounds.getY() + bounds.getHeight() - ROUND_RECTANGLE_ARC_DIAMETER,
266
            ROUND_RECTANGLE_ARC_DIAMETER,
267
            ROUND_RECTANGLE_ARC_DIAMETER,
268
            getDrawingPanel()
269
    );
270
    components.put("arc", arc);
271
272
    Line
273
            rightEdge = (Line) components.get("rightEdge"),
274
            bottomEdge = (Line) components.get("bottomEdge"),
275
            arcLeftEdge = new Line(
276
                    arc.getX(),
277
                    arc.getY() + arc.getHeight() / 2,
278
                    arc.getX(),
279
                    rightEdge.getY2() + components.get("widthLabel").getHeight(),
280
                    getDrawingPanel()
281
            ),
282
            arcRightEdge = new Line(
283
                    arc.getX() + arc.getWidth(),
284
                    arc.getY() + arc.getHeight() / 2,
285
                    arc.getX() + arc.getWidth(),
286
                    arcLeftEdge.getY2(),
287
                    getDrawingPanel()
288
            ),
289
            arcTopEdge = new Line(
290
                    arc.getX() + arc.getWidth() / 2,
291
                    arc.getY(),
292
                    bottomEdge.getX2() + components.get("originLabel").getHeight(),
293
                    arc.getY(),
294
                    getDrawingPanel()
295
            ),
296
            arcBottomEdge = new Line(
297
                    arc.getX() + arc.getWidth() / 2,
298
                    bottomEdge.getY1(),
299
                    arcTopEdge.getX2(),
300
                    bottomEdge.getY2(),
301
                    getDrawingPanel()
302
            );
303
    components.put("arcLeftEdge", arcLeftEdge);
304
    components.put("arcRightEdge", arcRightEdge);
305
    components.put("arcTopEdge", arcTopEdge);
306
    components.put("arcBottomEdge", arcBottomEdge);
307
308
    Text
309
            arcWidthLabel1 = new Text("↔", 0, 0, getDrawingPanel()),
310
            arcWidthLabel2 = new Text("Arc", 0, 0, getDrawingPanel()),
311
            arcWidthLabel3 = new Text("Width", 0, 0, getDrawingPanel()),
312
            arcHeightLabel = new Text("↕ Arc Height", 0, 0, getDrawingPanel());
313
    components.put("arcWidthLabel1", arcWidthLabel1);
314
    components.put("arcWidthLabel2", arcWidthLabel2);
315
    components.put("arcWidthLabel3", arcWidthLabel3);
316
    components.put("arcHeightLabel", arcHeightLabel);
317
318
    arc.setStroke(GenerateFigures.DASHED);
319
    arc.setStrokeColor(HIGHLIGHT_2);
320
321
    arcLeftEdge.setStroke(DASHED);
322
    arcLeftEdge.setStrokeColor(arc.getStrokeColor());
323
324
    arcRightEdge.setStroke(DASHED);
325
    arcRightEdge.setStrokeColor(arc.getStrokeColor());
326
327
    arcTopEdge.setStroke(DASHED);
328
    arcTopEdge.setStrokeColor(arc.getStrokeColor());
329
330
    arcBottomEdge.setStroke(GenerateFigures.DASHED);
331
    arcBottomEdge.setStrokeColor(arc.getStrokeColor());
332
333
    rightEdge.setDrawingPanel(getDrawingPanel()); // cheat to pop this component forward z-wise
334
    bottomEdge.setDrawingPanel(getDrawingPanel()); // cheat to pop this component forward z-wise
335
336
    arcWidthLabel1.setFont(LABEL);
337
    arcWidthLabel1.setStrokeColor(arc.getStrokeColor());
338
    arcWidthLabel1.setLocation(arc.getX() + arc.getWidth() / 2 - arcWidthLabel1.getWidth() / 2, ((Line) components.get("leftEdge")).getY2());
339
340
    arcWidthLabel2.setFont(LABEL);
341
    arcWidthLabel2.setStrokeColor(arc.getStrokeColor());
342
    arcWidthLabel2.setLocation(arc.getX() + arc.getWidth() / 2 - arcWidthLabel2.getWidth() / 2, arcWidthLabel1.getY() + arcWidthLabel2.getHeight());
343
344
    arcWidthLabel3.setFont(LABEL);
345
    arcWidthLabel3.setStrokeColor(arc.getStrokeColor());
346
    arcWidthLabel3.setLocation(arc.getX() + arc.getWidth() / 2 - arcWidthLabel3.getWidth() / 2, arcWidthLabel2.getY() + arcWidthLabel3.getHeight());
347
348
    arcHeightLabel.setFont(LABEL);
349
    arcHeightLabel.setStrokeColor(arc.getStrokeColor());
350
    arcHeightLabel.setLocation(
351
            components.get("heightLabel3").getX() + components.get("originLabel").getHeight(),
352
            bounds.getY() + bounds.getHeight() - arc.getHeight() / 2 + arcHeightLabel.getMaxAscent() / 2);
353
354
    components.put("roundRectangle", new RoundRectangle(
355
            bounds.getX(),
356
            bounds.getY(),
357
            bounds.getWidth(),
358
            bounds.getHeight(),
359
            ROUND_RECTANGLE_ARC_DIAMETER,
360
            ROUND_RECTANGLE_ARC_DIAMETER,
361
            getDrawingPanel()
362
    ));
363
    saveFigure("geom", "RoundRectangle");
364
  }
365
366
  private void figureArc() {
367
    resetComponents();
368
369
    Arc
370
            startAngle = new Arc(
371
            bounds.getX() + (bounds.getWidth() * (1 - ARC_START_SCALE)) / 2,
372
            bounds.getY() + (bounds.getHeight() * (1 - ARC_START_SCALE)) / 2,
373
            bounds.getWidth() * ARC_START_SCALE,
374
            bounds.getHeight() * ARC_START_SCALE,
375
            0,
376
            ARC_START_ANGLE,
377
            getDrawingPanel()
378
    ),
379
            extentAngle = new Arc(
380
                    bounds.getX() + (bounds.getWidth() * (1 - ARC_EXTENT_SCALE)) / 2,
381
                    bounds.getY() + (bounds.getHeight() * (1 - ARC_EXTENT_SCALE)) / 2,
382
                    bounds.getWidth() * ARC_EXTENT_SCALE,
383
                    bounds.getHeight() * ARC_EXTENT_SCALE,
384
                    ARC_START_ANGLE,
385
                    ARC_EXTENT_ANGLE,
386
                    getDrawingPanel()
387
            );
388
    components.put("startAngle", startAngle);
389
    components.put("extentAngle", extentAngle);
390
391
    Path
392
            startArrow = arrow(
393
            bounds.getX() + bounds.getWidth() / 2 + Math.cos(Math.toRadians(ARC_START_ANGLE)) * bounds.getWidth() * ARC_START_SCALE / 2,
394
            bounds.getY() + bounds.getHeight() / 2 - Math.sin(Math.toRadians(ARC_START_ANGLE)) * bounds.getHeight() * ARC_START_SCALE / 2,
395
            270 - ARC_START_ANGLE
396
    ),
397
            extentArrow = arrow(
398
                    bounds.getX() + bounds.getWidth() / 2 + Math.cos(Math.toRadians(ARC_START_ANGLE + ARC_EXTENT_ANGLE)) * bounds.getWidth() * ARC_EXTENT_SCALE / 2,
399
                    bounds.getY() + bounds.getHeight() / 2 - Math.sin(Math.toRadians(ARC_START_ANGLE + ARC_EXTENT_ANGLE)) * bounds.getHeight() * ARC_EXTENT_SCALE / 2,
400
                    270 - (ARC_START_ANGLE + ARC_EXTENT_ANGLE)
401
            );
402
    components.put("startArrow", startArrow);
403
    components.put("extentArrow", extentArrow);
404
405
    Text
406
            startLabel = new Text("Start", 0, 0, getDrawingPanel()),
407
            extentLabel = new Text("Extent", 0, 0, getDrawingPanel());
408
    components.put("startLabel", startLabel);
409
    components.put("extentLabel", extentLabel);
410
411
    startAngle.setStroke(DASHED);
412
    startAngle.setStrokeColor(HIGHLIGHT_4);
413
414
    startArrow.setFillColor(startAngle.getStrokeColor());
415
    startArrow.setStroke(Drawable.NO_STROKE);
416
417
    extentAngle.setStroke(DASHED);
418
    extentAngle.setStrokeColor(HIGHLIGHT_3);
419
420
    extentArrow.setFillColor(extentAngle.getStrokeColor());
421
    extentArrow.setStroke(Drawable.NO_STROKE);
422
423
    startLabel.setFont(LABEL);
424
    startLabel.setStrokeColor(startAngle.getStrokeColor());
425
    startLabel.setLocation(startArrow.getX() + ARROW_SIDE, startArrow.getY());
426
427
    extentLabel.setFont(LABEL);
428
    extentLabel.setStrokeColor(extentAngle.getStrokeColor());
429
    extentLabel.setLocation(extentArrow.getX() - ARROW_SIDE - extentLabel.getWidth(), extentArrow.getY() + extentLabel.getHeight());
430
431
    components.put("arc", new Arc(
432
            bounds.getX(),
433
            bounds.getY(),
434
            bounds.getWidth(),
435
            bounds.getHeight(),
436
            ARC_START_ANGLE,
437
            ARC_EXTENT_ANGLE,
438
            getDrawingPanel()
439
    ));
440
    saveFigure("geom", "Arc");
441
  }
442
443
  private void figureLine() {
444
    resetComponents(false);
445
    components.remove("ctrlPt1Label").removeFromDrawingPanel();
446
    components.remove("ctrlHandle1").removeFromDrawingPanel();
447
    components.remove("ctrlPt1").removeFromDrawingPanel();
448
    components.remove("ctrlPt2Label").removeFromDrawingPanel();
449
    components.remove("ctrlHandle2").removeFromDrawingPanel();
450
    components.remove("ctrlPt2").removeFromDrawingPanel();
451
452
    components.put("line", new Line(
453
            bounds.getX(),
454
            bounds.getY(),
455
            bounds.getX() + bounds.getWidth(),
456
            bounds.getY() + bounds.getHeight(),
457
            getDrawingPanel()
458
    ));
459
    saveFigure("geom", "Line");
460
  }
461
462
  private void figureQuadCurve() {
463
    resetComponents(false);
464
    components.remove("ctrlPt2").removeFromDrawingPanel();
465
    components.remove("ctrlPt2Label").removeFromDrawingPanel();
466
467
    Line
468
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
469
            ctrlHandle2 = (Line) components.get("ctrlHandle2");
470
471
    Text ctrlPt1Label = (Text) components.get("ctrlPt1Label");
472
473
    ctrlHandle2.setLine(bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight(), ctrlHandle1.getX2(), ctrlHandle1.getY2());
474
475
    ctrlPt1Label.setText("Control Point");
476
    ctrlPt1Label.setLocation(ctrlHandle1.getX2() - ctrlPt1Label.getWidth() / 2, ctrlPt1Label.getY());
477
478
    components.put("quadCurve", new QuadCurve(
479
            bounds.getX(),
480
            bounds.getY(),
481
            ctrlHandle1.getX2(),
482
            ctrlHandle1.getY2(),
483
            bounds.getX() + bounds.getWidth(),
484
            bounds.getY() + bounds.getHeight(),
485
            getDrawingPanel()
486
    ));
487
    saveFigure("geom", "QuadCurve");
488
  }
489
490
  private void figureCubicCurve() {
491
    resetComponents(false);
492
493
    Line
494
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
495
            ctrlHandle2 = (Line) components.get("ctrlHandle2");
496
497
    components.put("cubicCurve", new CubicCurve(
498
            bounds.getX(),
499
            bounds.getY(),
500
            ctrlHandle1.getX2(),
501
            ctrlHandle1.getY2(),
502
            ctrlHandle2.getX2(),
503
            ctrlHandle2.getY2(),
504
            bounds.getX() + bounds.getWidth(),
505
            bounds.getY() + bounds.getHeight(),
506
            getDrawingPanel()
507
    ));
508
    saveFigure("geom", "CubicCurve");
509
  }
510
511
  private void figureImage() {
512
    getDrawingPanel().clear();
513
    components.clear();
514
515
    Text originLabel = new Text("(x, y)", 1, 0, getDrawingPanel());
516
    components.put("originLabel", originLabel);
517
518
    Ellipse origin = new Ellipse(0, 0, POINT_DIAMETER, POINT_DIAMETER, getDrawingPanel());
519
    components.put("origin", origin);
520
521
    Image image = new Image("/java-logo.png", 0, 0, getDrawingPanel());
522
    components.put("image", image);
523
524
    originLabel.setFont(LABEL);
525
    originLabel.setStrokeColor(DIAGRAM);
526
    originLabel.setLocation(originLabel.getX(), originLabel.getHeight() - originLabel.getMaxDescent() + 1);
527
528
    origin.setFillColor(DIAGRAM);
529
    origin.setLocation(
530
            originLabel.getX() + originLabel.getWidth() / 2 - POINT_DIAMETER / 2,
531
            originLabel.getY() + originLabel.getMaxDescent()
532
    );
533
534
    image.setStroke(DASHED);
535
    image.setStrokeColor(HIGHLIGHT_1);
536
    image.setLocation(origin.getX() + POINT_DIAMETER / 2, origin.getY() + POINT_DIAMETER / 2);
537
    image.setWidth(bounds.getHeight() / image.getHeight() * image.getWidth());
538
    image.setHeight(bounds.getHeight());
539
540
    saveFigure("", "Image");
541
  }
542
543
  private void figureText() {
544
    resetComponents();
545
546
    Line
547
            baseline = new Line(0, 0, 0, 0, getDrawingPanel()),
548
            maxAscent = (Line) components.get("topEdge"),
549
            maxDescent = (Line) components.get("bottomEdge"),
550
            leftEdge = (Line) components.get("leftEdge"),
551
            rightEdge = (Line) components.get("rightEdge");
552
    components.put("baseline", baseline);
553
554
    Text
555
            originLabel = (Text) components.get("originLabel"),
556
            text = new Text("String", 1, 0, getDrawingPanel()),
557
            baselineLabel = new Text("Baseline", 0, 0, getDrawingPanel()),
558
            maxAscentLabel = new Text("Max Ascent", 0, 0, getDrawingPanel()),
559
            maxDescentLabel = new Text("Max Descent", 0, 0, getDrawingPanel()),
560
            heightLabel1 = (Text) components.get("heightLabel1"),
561
            heightLabel2 = (Text) components.get("heightLabel2"),
562
            heightLabel3 = (Text) components.get("heightLabel3"),
563
            widthLabel = (Text) components.get("widthLabel");
564
    components.put("text", text);
565
    components.put("baselineLabel", baselineLabel);
566
    components.put("maxAscentLabel", maxAscentLabel);
567
    components.put("maxDescentLabel", maxDescentLabel);
568
569
    Ellipse origin = (Ellipse) components.get("origin");
570
571
    originLabel.setStrokeColor(HIGHLIGHT_2);
572
573
    text.setFont(new Font("Times New Roman", Font.ITALIC, (int) (DIAGRAM_HEIGHT * 0.85)));
574
    text.setLocation(originLabel.getX() + originLabel.getWidth() / 2, text.getMaxAscent() + 1);
575
    bounds.setFrame(text.getX(), text.getY() - text.getMaxAscent(), text.getWidth(), text.getHeight());
576
577
    widthLabel.setLocation(bounds.getX() + bounds.getWidth() / 2 - widthLabel.getWidth() / 2, bounds.getY() + bounds.getHeight() + widthLabel.getHeight());
578
579
    leftEdge.setLine(bounds.getX(), bounds.getY(), bounds.getX(), widthLabel.getY());
580
    rightEdge.setLine(bounds.getX() + bounds.getWidth(), bounds.getY(), bounds.getX() + bounds.getWidth(), widthLabel.getY());
581
582
    heightLabel2.setLocation(bounds.getX() + bounds.getWidth() + heightLabel2.getHeight(), bounds.getY() + bounds.getHeight() / 2 + heightLabel2.getMaxAscent() / 2);
583
    heightLabel1.setLocation(heightLabel2.getX() + heightLabel2.getWidth() / 2 - heightLabel1.getWidth() / 2, heightLabel2.getY() - heightLabel2.getHeight());
584
    heightLabel3.setLocation(heightLabel2.getX() + heightLabel2.getWidth() / 2 - heightLabel3.getWidth() / 2, heightLabel2.getY() + heightLabel3.getHeight());
585
586
    text.setLocation(originLabel.getX() + originLabel.getWidth() / 2, text.getMaxAscent() + 1);
587
    originLabel.setLocation(originLabel.getX(), text.getY() + originLabel.getHeight() - originLabel.getMaxDescent() + POINT_DIAMETER / 2);
588
589
    origin.setFillColor(originLabel.getStrokeColor());
590
    origin.setStrokeColor(originLabel.getStrokeColor());
591
    origin.setLocation(text.getX() - POINT_DIAMETER / 2, text.getY() - POINT_DIAMETER / 2);
592
593
    maxAscent.setLine(bounds.getX(), bounds.getY(), heightLabel2.getX() + heightLabel2.getWidth() / 2, bounds.getY());
594
    maxDescent.setLine(bounds.getX(), bounds.getY() + bounds.getHeight(), maxAscent.getX2(), bounds.getY() + bounds.getHeight());
595
596
    maxAscentLabel.setFont(LABEL);
597
    maxAscentLabel.setStrokeColor(maxAscent.getStrokeColor());
598
    maxAscentLabel.setLocation(maxAscent.getX2(), maxAscent.getY2() + maxAscentLabel.getMaxAscent());
599
600
    maxDescentLabel.setFont(LABEL);
601
    maxDescentLabel.setStrokeColor(maxDescent.getStrokeColor());
602
    maxDescentLabel.setLocation(maxDescent.getX2(), maxDescent.getY2());
603
604
    baseline.setStrokeColor(originLabel.getStrokeColor());
605
    baseline.setStroke(DASHED);
606
    baseline.setLine(text.getX(), text.getY(), maxAscent.getX2(), text.getY());
607
608
    baselineLabel.setFont(LABEL);
609
    baselineLabel.setStrokeColor(baseline.getStrokeColor());
610
    baselineLabel.setLocation(baseline.getX2(), baseline.getY2());
611
612
    saveFigure("", "Text");
613
  }
614
615
  private void figurePath() {
616
    resetComponents(false);
617
618
    Line
619
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
620
            ctrlHandle2 = (Line) components.get("ctrlHandle2"),
621
            ctrlHandle3 = new Line(0, 0, 0, 0, getDrawingPanel()),
622
            ctrlHandle4 = new Line(0, 0, 0, 0, getDrawingPanel());
623
    components.put("ctrlHandle3", ctrlHandle3);
624
    components.put("ctrlHandle4", ctrlHandle4);
625
626
    Ellipse
627
            pt1 = (Ellipse) components.get("pt1"),
628
            pt2 = (Ellipse) components.get("pt2"),
629
            pt3 = new Ellipse(0, 0, POINT_DIAMETER, POINT_DIAMETER, getDrawingPanel()),
630
            pt4 = new Ellipse(0, 0, POINT_DIAMETER, POINT_DIAMETER, getDrawingPanel()),
631
            ctrlPt1 = (Ellipse) components.get("ctrlPt1"),
632
            ctrlPt2 = (Ellipse) components.get("ctrlPt2"),
633
            ctrlPt3 = new Ellipse(0, 0, POINT_DIAMETER, POINT_DIAMETER, getDrawingPanel());
634
    components.put("pt3", pt3);
635
    components.put("pt4", pt4);
636
    components.put("ctrlPt3", ctrlPt3);
637
638
    Text
639
            pt1Label = (Text) components.get("pt1Label"),
0 ignored issues
show
Unused Code introduced by
Consider removing the unused local variable pt1Label.
Loading history...
Unused Code Code Smell introduced by
Remove this useless assignment to local variable "pt1Label".
Loading history...
640
            pt2Label = (Text) components.get("pt2Label"),
641
            pt3Label = new Text("Point 3", 0, 0, getDrawingPanel()),
642
            pt4Label = new Text("Point 4", 0, 0, getDrawingPanel()),
643
            lineToLabel = (Text) components.get("ctrlPt1Label"),
644
            curveToLabel = (Text) components.get("ctrlPt2Label"),
645
            quadToLabel = new Text("Quad", 0, 0, getDrawingPanel());
646
    components.put("pt3Label", pt3Label);
647
    components.put("pt4Label", pt4Label);
648
    components.put("quadToLabel", quadToLabel);
649
650
    Path path = new Path(getDrawingPanel());
651
    components.put("path", path);
652
653
    lineToLabel.setText("Line");
654
    curveToLabel.setText("Curve");
655
    quadToLabel.setStrokeColor(lineToLabel.getStrokeColor());
656
    quadToLabel.setFont(LABEL);
657
658
    ctrlHandle3.setStroke(DASHED);
659
    ctrlHandle3.setStrokeColor(ctrlHandle1.getStrokeColor());
660
661
    ctrlHandle4.setStroke(DASHED);
662
    ctrlHandle4.setStrokeColor(ctrlHandle1.getStrokeColor());
663
664
    ctrlPt3.setStrokeColor(ctrlPt1.getStrokeColor());
665
    ctrlPt3.setStroke(ctrlPt1.getStroke());
666
    ctrlPt3.setFillColor(ctrlPt1.getFillColor());
667
668
    pt3.setStrokeColor(pt1.getStrokeColor());
669
    pt3.setFillColor(pt1.getFillColor());
670
    pt3.setStroke(pt1.getStroke());
671
672
    pt4.setStrokeColor(pt1.getStrokeColor());
673
    pt4.setFillColor(pt1.getFillColor());
674
    pt4.setStroke(pt1.getStroke());
675
676
    pt3Label.setStrokeColor(pt3.getFillColor());
677
    pt3Label.setFont(LABEL);
678
679
    pt4Label.setStrokeColor(pt4.getFillColor());
680
    pt4Label.setFont(LABEL);
681
682
    ctrlHandle1.setLine(
683
            bounds.getX() + bounds.getWidth() * 0.1, bounds.getY() + bounds.getHeight(),
684
            bounds.getX() + bounds.getWidth() * 0.4, bounds.getY() + bounds.getHeight()
685
    );
686
    ctrlHandle2.setLine(
687
            bounds.getX() + bounds.getWidth() * 0.5, bounds.getY() + bounds.getHeight() * 0.5,
688
            bounds.getX() + bounds.getWidth() * 0.5, bounds.getY() + bounds.getHeight() * 0.9
689
    );
690
    ctrlHandle3.setLine(
691
            ctrlHandle2.getX1(), ctrlHandle2.getY1(),
692
            ctrlHandle2.getX1(), bounds.getY()
693
    );
694
    ctrlHandle4.setLine(
695
            bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight() * 0.5,
696
            ctrlHandle3.getX2(), ctrlHandle3.getY2()
697
    );
698
699
    ctrlPt1.setLocation(ctrlHandle1.getX2() - POINT_DIAMETER / 2, ctrlHandle1.getY2() - POINT_DIAMETER / 2);
700
    ctrlPt2.setLocation(ctrlHandle2.getX2() - POINT_DIAMETER / 2, ctrlHandle2.getY2() - POINT_DIAMETER / 2);
701
    ctrlPt3.setLocation(ctrlHandle3.getX2() - POINT_DIAMETER / 2, ctrlHandle3.getY2() - POINT_DIAMETER / 2);
702
703
    pt2.setLocation(ctrlHandle1.getX1() - POINT_DIAMETER / 2, ctrlHandle1.getY1() - POINT_DIAMETER / 2);
704
    pt3.setLocation(ctrlHandle3.getX1() - POINT_DIAMETER / 2, ctrlHandle3.getY1() - POINT_DIAMETER / 2);
705
    pt4.setLocation(ctrlHandle4.getX1() - POINT_DIAMETER / 2, ctrlHandle4.getY1() - POINT_DIAMETER / 2);
706
707
    pt2Label.setLocation(Math.max(1, ctrlHandle1.getX1() - pt2Label.getWidth() / 2), ctrlHandle1.getY1() + pt2Label.getHeight());
708
    pt3Label.setLocation(ctrlHandle3.getX1() - pt3Label.getWidth() - POINT_DIAMETER, ctrlHandle3.getY1() + pt3Label.getMaxDescent());
709
    pt4Label.setLocation(ctrlHandle4.getX1() - pt4Label.getWidth() / 2, ctrlHandle4.getY1() + pt4Label.getHeight());
710
711
    lineToLabel.setLocation((bounds.getX() + ctrlHandle1.getX1()) / 2 + lineToLabel.getMaxDescent(), (bounds.getY() + ctrlHandle1.getY1()) / 2);
712
    curveToLabel.setLocation((ctrlHandle1.getX1() + ctrlHandle2.getX1()) / 2 - curveToLabel.getWidth() / 2, (ctrlHandle1.getY1() + ctrlHandle2.getY1()) / 2 + curveToLabel.getHeight());
713
    quadToLabel.setLocation((ctrlHandle3.getX1() + ctrlHandle4.getX1()) / 2 - quadToLabel.getWidth() / 2, (ctrlHandle3.getY1() + ctrlHandle4.getY1()) / 2);
714
715
    path.moveTo(bounds.getX(), bounds.getY());
716
    path.lineTo(ctrlHandle1.getX1(), ctrlHandle1.getY1());
717
    path.curveTo(
718
            ctrlHandle1.getX2(), ctrlHandle1.getY2(),
719
            ctrlHandle2.getX2(), ctrlHandle2.getY2(),
720
            ctrlHandle2.getX1(), ctrlHandle2.getY1()
721
    );
722
    path.quadTo(
723
            ctrlHandle3.getX2(), ctrlHandle3.getY2(),
724
            ctrlHandle4.getX1(), ctrlHandle4.getY1()
725
    );
726
727
    saveFigure("geom", "Path");
728
  }
729
730
  private void figureBezierQuadCurveFig1() {
731
    figureBezierQuadCurveFig1(true);
732
  }
733
734
  private void figureBezierQuadCurveFig1(boolean isStandAlone) {
735
    resetComponents(false);
736
    components.remove("ctrlPt2").removeFromDrawingPanel();
737
    components.remove("ctrlPt2Label").removeFromDrawingPanel();
738
739
    Line
740
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
741
            ctrlHandle2 = (Line) components.get("ctrlHandle2");
742
743
    Ellipse pt2 = (Ellipse) components.get("pt2");
744
745
    Text
746
            ctrlPtLabel = (Text) components.get("ctrlPt1Label"),
747
            pt2Label = (Text) components.get("pt2Label");
748
749
    ctrlHandle2.setLine(
750
            bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight(),
751
            ctrlHandle1.getX2(), ctrlHandle1.getY2()
752
    );
753
754
    QuadCurve quadCurve = new QuadCurve(0, 0, 0, 0, 0, 0, getDrawingPanel());
755
    components.put("quadCurve", quadCurve);
756
757
    ctrlPtLabel.setText("Control Point");
758
    ctrlPtLabel.setLocation(ctrlHandle1.getX2() - ctrlPtLabel.getWidth() / 2, ctrlPtLabel.getY());
759
760
    pt2.setLocation(ctrlHandle2.getX1() - POINT_DIAMETER / 2, ctrlHandle2.getY1() - POINT_DIAMETER / 2);
761
    pt2Label.setLocation(ctrlHandle2.getX1() - pt2Label.getWidth() / 2, pt2Label.getY());
762
763
    quadCurve.setCurve(
764
            ctrlHandle1.getX1(), ctrlHandle1.getY1(),
765
            ctrlHandle1.getX2(), ctrlHandle1.getY2(),
766
            ctrlHandle2.getX1(), ctrlHandle2.getY1()
767
    );
768
769
770
    if (isStandAlone) {
771
      saveFigure("geom", "Bezier-QuadCurve-fig1");
772
    }
773
  }
774
775
  private void figureBezierQuadCurveFig2() {
776
    figureBezierQuadCurveFig2(true, 3);
777
  }
778
779
  private void figureBezierQuadCurveFig2(boolean isStandAlone, int interpolations) {
780
    figureBezierQuadCurveFig1(false);
781
    components.get("quadCurve").removeFromDrawingPanel();
782
783
    Line
784
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
785
            ctrlHandle2 = (Line) components.get("ctrlHandle2");
786
787
    double
788
            dx1 = ctrlHandle1.getX2() - ctrlHandle1.getX1(),
789
            dy1 = ctrlHandle1.getY2() - ctrlHandle1.getY1(),
790
            dx2 = ctrlHandle2.getX1() - ctrlHandle2.getX2(),
791
            dy2 = ctrlHandle2.getY1() - ctrlHandle2.getY2();
792
793
    for (int i = 1; i < interpolations; i++) {
794
      double scale = (double) i / interpolations;
795
      Line line = new Line(
796
              ctrlHandle1.getX1() + dx1 * scale,
797
              ctrlHandle1.getY1() + dy1 * scale,
798
              ctrlHandle2.getX2() + dx2 * scale,
799
              ctrlHandle2.getY2() + dy2 * scale,
800
              getDrawingPanel()
801
      );
802
      components.put("interpolation" + i, line);
803
804
      Ellipse ellipse = new Ellipse(
805
              line.getX1() + (line.getX2() - line.getX1()) * scale - POINT_DIAMETER / 2,
806
              line.getY1() + (line.getY2() - line.getY1()) * scale - POINT_DIAMETER / 2,
807
              POINT_DIAMETER,
808
              POINT_DIAMETER,
809
              getDrawingPanel()
810
      );
811
      components.put("interpolationPt" + i, ellipse);
812
813
      line.setStrokeColor(Color.getHSBColor((float) scale, 1, 1));
814
      ellipse.setStrokeColor(line.getStrokeColor());
815
      ellipse.setFillColor(ellipse.getStrokeColor());
816
    }
817
818
    if (isStandAlone) {
819
      saveFigure("geom", "Bezier-QuadCurve-fig2");
820
    }
821
  }
822
823
  private void figureBezierQuadCurveFig3() {
824
    figureBezierQuadCurveFig3(true, BEZIER_CURVE_INTERPOLATIONS);
825
  }
826
827
  private void figureBezierQuadCurveFig3(boolean isStandAlone, int interpolations) {
828
    figureBezierQuadCurveFig2(false, interpolations);
829
    if (isStandAlone) {
830
      saveFigure("geom", "Bezier-QuadCurve-fig3");
831
    }
832
  }
833
834
  private void figureBezierQuadCurveFig4() {
835
    figureBezierQuadCurveFig4(BEZIER_CURVE_INTERPOLATIONS);
836
  }
837
838
  private void figureBezierQuadCurveFig4(int interpolations) {
839
    figureBezierQuadCurveFig3(false, interpolations);
840
    components.get("quadCurve").setDrawingPanel(getDrawingPanel());
841
    saveFigure("geom", "Bezier-QuadCurve-fig4");
842
  }
843
844
  private void figureBezierCubicCurveFig1() {
845
    figureBezierCubicCurveFig1(true);
846
  }
847
848
  private void figureBezierCubicCurveFig1(boolean isStandAlone) {
849
    resetComponents(false);
850
851
    Line
852
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
853
            ctrlHandle2 = (Line) components.get("ctrlHandle2"),
854
            ctrlHandle3 = new Line(0, 0, 0, 0, getDrawingPanel());
855
    components.put("ctrlHandle3", ctrlHandle3);
856
857
    CubicCurve cubicCurve = new CubicCurve(0, 0, 0, 0, 0, 0, 0, 0, getDrawingPanel()
858
    );
859
    components.put("cubicCurve", cubicCurve);
860
861
    Ellipse
862
            ctrlPt2 = (Ellipse) components.get("ctrlPt2"),
863
            pt2 = (Ellipse) components.get("pt2");
864
865
    Text
866
            ctrlPt2Label = (Text) components.get("ctrlPt2Label"),
867
            pt2Label = (Text) components.get("pt2Label");
868
869
    components.get("ctrlPt1").setDrawingPanel(getDrawingPanel());
870
    components.get("ctrlPt2").setDrawingPanel(getDrawingPanel());
871
872
    ctrlHandle2.setLine(ctrlHandle2.getX2(), ctrlHandle2.getY2(), ctrlHandle2.getX1(), ctrlHandle2.getY1());
873
874
    pt2.setLocation(ctrlHandle2.getX1() - POINT_DIAMETER / 2, ctrlHandle2.getY1() - POINT_DIAMETER / 2);
875
    pt2Label.setLocation(ctrlHandle2.getX1() - pt2Label.getWidth() / 2, ctrlHandle2.getY() + pt2Label.getHeight());
876
877
    ctrlPt2.setLocation(ctrlHandle2.getX2() - POINT_DIAMETER / 2, ctrlHandle2.getY2() - POINT_DIAMETER / 2);
878
    ctrlPt2Label.setLocation(ctrlHandle2.getX2() - ctrlPt2Label.getWidth() / 2, ctrlHandle2.getY2() + ctrlPt2Label.getHeight());
879
880
    ctrlHandle3.setLine(ctrlHandle1.getX2(), ctrlHandle1.getY2(), ctrlHandle2.getX2(), ctrlHandle2.getY2());
881
    ctrlHandle3.setStrokeColor(ctrlHandle1.getStrokeColor());
882
    ctrlHandle3.setStroke(ctrlHandle1.getStroke());
883
884
    cubicCurve.setCurve(
885
            ctrlHandle1.getX1(), ctrlHandle1.getY1(),
886
            ctrlHandle1.getX2(), ctrlHandle1.getY2(),
887
            ctrlHandle2.getX2(), ctrlHandle2.getY2(),
888
            ctrlHandle2.getX1(), ctrlHandle2.getY1()
889
    );
890
891
    if (isStandAlone) {
892
      saveFigure("geom", "Bezier-CubicCurve-fig1");
893
    }
894
  }
895
896
  private void figureBezierCubicCurveFig2() {
897
    figureBezierCubicCurveFig2(true, BEZIER_CURVE_INTERPOLATIONS);
898
  }
899
900
  private void figureBezierCubicCurveFig2(boolean isStandAlone, int interpolations) {
901
    figureBezierCubicCurveFig1(false);
902
    components.get("cubicCurve").removeFromDrawingPanel();
903
904
    Line
905
            ctrlHandle1 = (Line) components.get("ctrlHandle1"),
906
            ctrlHandle2 = (Line) components.get("ctrlHandle2");
907
908
    double
909
            cx1 = ctrlHandle1.getX2() - ctrlHandle1.getX1(),
910
            cy1 = ctrlHandle1.getY2() - ctrlHandle1.getY1(),
911
            cxi = ctrlHandle2.getX2() - ctrlHandle1.getX2(),
912
            cyi = ctrlHandle2.getY2() - ctrlHandle1.getY2(),
913
            cx2 = ctrlHandle2.getX1() - ctrlHandle2.getX2(),
914
            cy2 = ctrlHandle2.getY1() - ctrlHandle2.getY2(),
915
            dx1i, dy1i, dxi2, dyi2;
0 ignored issues
show
Unused Code introduced by
Consider removing the unused local variable dx1i.
Loading history...
Unused Code introduced by
Consider removing the unused local variable dy1i.
Loading history...
Unused Code introduced by
Consider removing the unused local variable dxi2.
Loading history...
Unused Code introduced by
Consider removing the unused local variable dyi2.
Loading history...
916
917
    for (int i = 1; i < interpolations; i++) {
918
      double scale = (double) i / interpolations;
919
      Line
920
              line1 = new Line(
921
              ctrlHandle1.getX1() + cx1 * scale,
922
              ctrlHandle1.getY1() + cy1 * scale,
923
              ctrlHandle1.getX2() + cxi * scale,
924
              ctrlHandle1.getY2() + cyi * scale,
925
              getDrawingPanel()
926
      ),
927
              line2 = new Line(
928
                      line1.getX2(),
929
                      line1.getY2(),
930
                      ctrlHandle2.getX2() + cx2 * scale,
931
                      ctrlHandle2.getY2() + cy2 * scale,
932
                      getDrawingPanel()
933
              );
934
      components.put("interpolation" + (2 * i - 1), line1);
935
      components.put("interpolation" + (2 * i), line2);
936
      line1.setStrokeColor(Color.getHSBColor((float) scale, 1, 1));
937
      line2.setStrokeColor(line1.getStrokeColor());
938
    }
939
940
    if (isStandAlone) {
941
      saveFigure("geom", "Bezier-CubicCurve-fig2");
942
    }
943
  }
944
945
  private void figureBezierCubicCurveFig3() {
946
    figureBezierCubicCurveFig3(true, 2);
947
  }
948
949
  private void figureBezierCubicCurveFig3(boolean isStandAlone, int interpolations) {
950
    figureBezierCubicCurveFig2(false, interpolations);
951
952
    for (int i = 1; i < interpolations; i++) {
953
      double scale = (double) i / interpolations;
954
      Line
955
              line1 = (Line) components.get("interpolation" + (2 * i - 1)),
956
              line2 = (Line) components.get("interpolation" + (2 * i)),
957
              line3 = new Line(
958
                      line1.getX1() + (line1.getX2() - line1.getX1()) * scale,
959
                      line1.getY1() + (line1.getY2() - line1.getY1()) * scale,
960
                      line2.getX1() + (line2.getX2() - line2.getX1()) * scale,
961
                      line2.getY1() + (line2.getY2() - line2.getY1()) * scale,
962
                      getDrawingPanel()
963
              );
964
      components.put("interpolation" + (2 * i - 1) + "-" + 2 * i, line3);
965
966
      Ellipse ellipse = new Ellipse(
967
              line3.getX1() + (line3.getX2() - line3.getX1()) * scale - POINT_DIAMETER / 2,
968
              line3.getY1() + (line3.getY2() - line3.getY1()) * scale - POINT_DIAMETER / 2,
969
              POINT_DIAMETER,
970
              POINT_DIAMETER,
971
              getDrawingPanel()
972
      );
973
      components.put("interpolated-point" + i, ellipse);
974
975
      line3.setStrokeColor(line1.getStrokeColor());
976
      ellipse.setFillColor(line2.getStrokeColor());
977
      ellipse.setStrokeColor(ellipse.getFillColor());
978
    }
979
980
    if (isStandAlone) {
981
      saveFigure("geom", "Bezier-CubicCurve-fig3");
982
    }
983
  }
984
985
  private void figureBezierCubicCurveFig4() {
986
    figureBezierCubicCurveFig4(true, BEZIER_CURVE_INTERPOLATIONS);
987
  }
988
989
  private void figureBezierCubicCurveFig4(boolean isStandAlone, int interpolations) {
990
    figureBezierCubicCurveFig3(false, interpolations);
991
    if (isStandAlone) {
992
      saveFigure("geom", "Bezier-CubicCurve-fig4");
993
    }
994
  }
995
996
  private void figureBezierCubicCurveFig5() {
997
    figureBezierCubicCurveFig5(true, BEZIER_CURVE_INTERPOLATIONS);
998
  }
999
1000
  private void figureBezierCubicCurveFig5(boolean isStandAlone, int interpolations) {
1001
    figureBezierCubicCurveFig4(false, interpolations);
1002
    components.get("cubicCurve").setDrawingPanel(getDrawingPanel());
1003
    if (isStandAlone) {
1004
      saveFigure("geom", "Bezier-CubicCurve-fig5");
1005
    }
1006
  }
1007
1008
  private void resetComponents() {
1009
    resetComponents(true);
1010
  }
1011
1012
  private void resetComponents(boolean is2D) {
1013
    getDrawingPanel().clear();
1014
    components.clear();
1015
    if (is2D) {
1016
      resetComponentsFor2D();
1017
    } else {
1018
      resetComponentsForPaths();
1019
    }
1020
  }
1021
1022
  private void resetComponentsFor2D() {
1023
    Line
1024
            leftEdge = new Line(0, 0, 0, 0, getDrawingPanel()),
1025
            rightEdge = new Line(0, 0, 0, 0, getDrawingPanel()),
1026
            topEdge = new Line(0, 0, 0, 0, getDrawingPanel()),
1027
            bottomEdge = new Line(0, 0, 0, 0, getDrawingPanel());
1028
    components.put("leftEdge", leftEdge);
1029
    components.put("rightEdge", rightEdge);
1030
    components.put("topEdge", topEdge);
1031
    components.put("bottomEdge", bottomEdge);
1032
1033
    Text
1034
            originLabel = new Text("(x, y)", 1, 0, getDrawingPanel()),
1035
            widthLabel = new Text("← Width →", 0, 0, getDrawingPanel()),
1036
            heightLabel1 = new Text("↑", 0, 0, getDrawingPanel()),
1037
            heightLabel2 = new Text("Height", 0, 0, getDrawingPanel()),
1038
            heightLabel3 = new Text("↓", 0, 0, getDrawingPanel());
1039
    components.put("originLabel", originLabel);
1040
    components.put("widthLabel", widthLabel);
1041
    components.put("heightLabel1", heightLabel1);
1042
    components.put("heightLabel2", heightLabel2);
1043
    components.put("heightLabel3", heightLabel3);
1044
1045
    Ellipse origin = new Ellipse(0, 0, POINT_DIAMETER, POINT_DIAMETER, getDrawingPanel());
1046
    components.put("origin", origin);
1047
1048
    for (String key : new String[]{"originLabel", "widthLabel", "heightLabel1", "heightLabel2", "heightLabel3"}) {
1049
      Text t = (Text) components.get(key);
1050
      t.setFont(LABEL);
1051
      if (key.equals("originLabel")) {
1052
        t.setStrokeColor(DIAGRAM);
1053
        t.setLocation(t.getX(), t.getHeight() - t.getMaxDescent() + 1);
1054
        bounds = new Rectangle2D.Double(
1055
                t.getX() + t.getWidth() / 2,
1056
                t.getY() + t.getMaxDescent() + POINT_DIAMETER,
1057
                DIAGRAM_WIDTH,
1058
                DIAGRAM_HEIGHT
1059
        );
1060
      } else {
1061
        t.setStrokeColor(HIGHLIGHT_1);
1062
      }
1063
    }
1064
1065
    widthLabel.setLocation(bounds.getX() + bounds.getWidth() / 2 - widthLabel.getWidth() / 2, bounds.getY() + bounds.getHeight() + widthLabel.getHeight() + 2);
1066
1067
    heightLabel2.setLocation(bounds.getX() + bounds.getWidth() + heightLabel2.getHeight(), bounds.getY() + bounds.getHeight() / 2 + (heightLabel2.getMaxAscent() / 2));
1068
    heightLabel1.setLocation(heightLabel2.getX() + heightLabel2.getWidth() / 2 - heightLabel1.getWidth() / 2, heightLabel2.getY() - heightLabel2.getHeight());
1069
    heightLabel3.setLocation(heightLabel2.getX() + heightLabel2.getWidth() / 2 - heightLabel3.getWidth() / 2, heightLabel2.getY() + heightLabel3.getHeight());
1070
1071
    origin.setFillColor(DIAGRAM);
1072
    origin.setLocation(bounds.getX() - POINT_DIAMETER / 2, bounds.getY() - POINT_DIAMETER / 2);
1073
1074
    leftEdge.setLine(bounds.getX(), bounds.getY(), bounds.getX(), widthLabel.getY());
1075
    rightEdge.setLine(bounds.getX() + bounds.getWidth(), bounds.getY(), bounds.getX() + bounds.getWidth(), widthLabel.getY());
1076
    topEdge.setLine(bounds.getX(), bounds.getY(), heightLabel1.getX() + heightLabel1.getWidth(), bounds.getY());
1077
    bottomEdge.setLine(bounds.getX(), bounds.getY() + bounds.getHeight(), heightLabel1.getX() + heightLabel1.getWidth(), bounds.getY() + bounds.getHeight());
1078
1079
    leftEdge.setStroke(DASHED);
1080
    leftEdge.setStrokeColor(widthLabel.getStrokeColor());
1081
1082
    rightEdge.setStroke(DASHED);
1083
    rightEdge.setStrokeColor(widthLabel.getStrokeColor());
1084
1085
    topEdge.setStroke(DASHED);
1086
    topEdge.setStrokeColor(heightLabel1.getStrokeColor());
1087
1088
    bottomEdge.setStroke(DASHED);
1089
    bottomEdge.setStrokeColor(heightLabel1.getStrokeColor());
1090
  }
1091
1092
  private void figurePathTranslate() {
1093
    figurePathTranslate(true);
1094
  }
1095
1096
  /**
1097
   * TODO Diagram
1098
   *
1099
   * @param isStandAlone
1100
   */
1101
  private void figurePathTranslate(boolean isStandAlone) {
1102
    getDrawingPanel().clear();
1103
    components.clear();
1104
    components.put("TODO", new Text("TODO Diagram", 1, 20, getDrawingPanel()));
1105
    if (isStandAlone) {
0 ignored issues
show
Bug introduced by
Consider removing the empty block or filling it with code. You can also add a comment to explain the empty block.
Loading history...
1106
    }
1107
1108
    saveFigure("geom", "Path-translate");
1109
  }
1110
1111
  /**
1112
   * TODO Diagram
1113
   */
1114
  private void figurePathScale() {
1115
    getDrawingPanel().clear();
1116
    components.clear();
1117
    figurePathTranslate(false);
1118
    saveFigure("geom", "Path-scale");
1119
  }
1120
1121
  /**
1122
   * TODO Diagram
1123
   */
1124
  private void figurePathRotate() {
1125
    getDrawingPanel().clear();
1126
    components.clear();
1127
    figurePathTranslate(false);
1128
    saveFigure("geom", "Path-rotate");
1129
  }
1130
1131
  /**
1132
   * TODO Diagram
1133
   */
1134
  private void figurePathShear() {
1135
    getDrawingPanel().clear();
1136
    components.clear();
1137
    figurePathTranslate(false);
1138
    saveFigure("geom", "Path-shear");
1139
  }
1140
1141
  private void resetComponentsForPaths() {
1142
    Text
1143
            pt1Label = new Text("Point 1", 0, 0, getDrawingPanel()),
1144
            pt2Label = new Text("Point 2", 0, 0, getDrawingPanel()),
1145
            ctrlPt1Label = new Text("Control Point 1", 0, 0, getDrawingPanel()),
1146
            ctrlPt2Label = new Text("Control Point 2", 0, 0, getDrawingPanel());
1147
    components.put("pt1Label", pt1Label);
1148
    components.put("pt2Label", pt2Label);
1149
    components.put("ctrlPt1Label", ctrlPt1Label);
1150
    components.put("ctrlPt2Label", ctrlPt2Label);
1151
1152
    pt1Label.setFont(LABEL);
1153
    pt1Label.setLocation(1, pt1Label.getHeight() - pt1Label.getMaxDescent() + 1);
1154
1155
    bounds.setFrame(pt1Label.getX() + pt1Label.getWidth() / 2, bounds.getY(), bounds.getWidth(), bounds.getHeight());
1156
1157
    double
1158
            ctrlX1 = bounds.getX() + bounds.getWidth() * 0.8,
1159
            ctrlY1 = bounds.getY() + bounds.getHeight() * 0.1,
1160
            ctrlX2 = bounds.getX() + bounds.getWidth() * 0.6,
1161
            ctrlY2 = bounds.getY() + bounds.getHeight() * 0.95;
1162
1163
    Line
1164
            ctrlHandle1 = new Line(bounds.getX(), bounds.getY(), ctrlX1, ctrlY1, getDrawingPanel()),
1165
            ctrlHandle2 = new Line(bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight(), ctrlX2, ctrlY2, getDrawingPanel());
1166
    components.put("ctrlHandle1", ctrlHandle1);
1167
    components.put("ctrlHandle2", ctrlHandle2);
1168
1169
    Ellipse
1170
            pt1 = new Ellipse(
1171
            bounds.getX() - POINT_DIAMETER / 2,
1172
            bounds.getY() - POINT_DIAMETER / 2,
1173
            POINT_DIAMETER,
1174
            POINT_DIAMETER,
1175
            getDrawingPanel()
1176
    ),
1177
            ctrlPt1 = new Ellipse(
1178
                    ctrlX1 - POINT_DIAMETER / 2,
1179
                    ctrlY1 - POINT_DIAMETER / 2,
1180
                    POINT_DIAMETER,
1181
                    POINT_DIAMETER,
1182
                    getDrawingPanel()
1183
            ),
1184
            ctrlPt2 = new Ellipse(
1185
                    ctrlX2 - POINT_DIAMETER / 2,
1186
                    ctrlY2 - POINT_DIAMETER / 2,
1187
                    POINT_DIAMETER,
1188
                    POINT_DIAMETER,
1189
                    getDrawingPanel()
1190
            ),
1191
            pt2 = new Ellipse(
1192
                    bounds.getX() + bounds.getWidth() - POINT_DIAMETER / 2,
1193
                    bounds.getY() + bounds.getHeight() - POINT_DIAMETER / 2,
1194
                    POINT_DIAMETER,
1195
                    POINT_DIAMETER,
1196
                    getDrawingPanel()
1197
            );
1198
    components.put("pt1", pt1);
1199
    components.put("ctrlPt1", ctrlPt1);
1200
    components.put("ctrlPt2", ctrlPt2);
1201
    components.put("pt2", pt2);
1202
1203
    pt2Label.setStrokeColor(pt1Label.getStrokeColor());
1204
    pt2Label.setFont(LABEL);
1205
    pt2Label.setLocation(bounds.getX() + bounds.getWidth() - pt2Label.getWidth() / 2, bounds.getY() + bounds.getHeight() + POINT_DIAMETER / 2 + pt2Label.getHeight());
1206
1207
    ctrlPt1Label.setStrokeColor(HIGHLIGHT_1);
1208
    ctrlPt1Label.setFont(LABEL);
1209
    ctrlPt1Label.setLocation(ctrlX1 - ctrlPt1Label.getWidth() / 2, ctrlY1 - POINT_DIAMETER / 2 - ctrlPt1Label.getMaxDescent());
1210
1211
    ctrlPt2Label.setStrokeColor(ctrlPt1Label.getStrokeColor());
1212
    ctrlPt2Label.setFont(LABEL);
1213
    ctrlPt2Label.setLocation(ctrlX2 - ctrlPt2Label.getWidth() / 2, ctrlY2 + POINT_DIAMETER / 2 + ctrlPt2Label.getHeight());
1214
1215
    ctrlHandle1.setStroke(DASHED);
1216
    ctrlHandle1.setStrokeColor(ctrlPt1Label.getStrokeColor());
1217
    ctrlHandle2.setStroke(DASHED);
1218
    ctrlHandle2.setStrokeColor(ctrlPt2Label.getStrokeColor());
1219
1220
    pt1.setFillColor(DIAGRAM);
1221
    pt2.setFillColor(pt1.getFillColor());
1222
1223
    ctrlPt1.setStrokeColor(HIGHLIGHT_1);
1224
    ctrlPt1.setFillColor(POINT_FILL);
1225
1226
    ctrlPt2.setStrokeColor(ctrlPt1.getStrokeColor());
1227
    ctrlPt2.setFillColor(ctrlPt1.getFillColor());
1228
  }
1229
1230
  @Override
1231
  public void setup() {
1232
    components = new HashMap<>();
1233
    resetDir(BASE_PATH + "/doc-files");
1234
    resetDir(BASE_PATH + "/geom/doc-files");
1235
    resetDir(BASE_PATH + "/ui/doc-files");
1236
    Figure[] figures = new Figure[]{
1237
            this::figureDrawingApp,
1238
            this::figureWindowCoordinates,
1239
            this::figureStrokeFill,
1240
            this::figureRectangle,
1241
            this::figureEllipse,
1242
            this::figureRoundRectangle,
1243
            this::figureArc,
1244
            this::figureBezierQuadCurveFig1,
1245
            this::figureBezierQuadCurveFig2,
1246
            this::figureBezierQuadCurveFig3,
1247
            this::figureBezierQuadCurveFig4,
1248
            this::figureBezierCubicCurveFig1,
1249
            this::figureBezierCubicCurveFig2,
1250
            this::figureBezierCubicCurveFig3,
1251
            this::figureBezierCubicCurveFig4,
1252
            this::figureBezierCubicCurveFig5,
1253
            this::figureQuadCurve,
1254
            this::figureLine,
1255
            this::figureCubicCurve,
1256
            this::figurePath,
1257
            this::figurePathTranslate,
1258
            this::figurePathScale,
1259
            this::figurePathRotate,
1260
            this::figurePathShear,
1261
            this::figureImage,
1262
            this::figureText
1263
    };
1264
    for (Figure figure : figures) {
1265
      figure.generate();
1266
    }
1267
1268
    System.exit(0);
1269
  }
1270
1271
  private interface Figure {
1272
    void generate();
1273
  }
1274
1275
}
1276