org.gannacademy.cdf.graphics.geom.QuadCurve   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 175
rs 10
eloc 56
wmc 19

17 Methods

Rating   Name   Duplication   Size   Complexity  
A getY1() 0 2 1
A setShape(Shape) 0 6 2
A setCurve(double,double,double,double,double,double) 0 2 1
A getX1() 0 2 1
A getCtrlY() 0 2 1
A getP1() 0 2 1
A setHeight(double) 0 8 1
A getX2() 0 2 1
A setWidth(double) 0 8 1
A getCtrlX() 0 2 1
A translate(double,double) 0 3 1
A getY2() 0 2 1
A getCtrlPt() 0 2 1
A QuadCurve(double,double,double,double,double,double,DrawingPanel) 0 7 2
A getShapeAsQuadCurve() 0 2 1
A setLocation(double,double) 0 3 1
A getP2() 0 2 1
1
package org.gannacademy.cdf.graphics.geom;
2
3
import org.gannacademy.cdf.graphics.Drawable;
4
import org.gannacademy.cdf.graphics.DrawableException;
5
import org.gannacademy.cdf.graphics.ui.DrawingPanel;
6
7
import java.awt.*;
8
import java.awt.geom.Point2D;
9
import java.awt.geom.QuadCurve2D;
10
11
/**
12
 * <p>Draw a quadratic Bézier curve</p>
13
 *
14
 * <p><img src="doc-files/Bezier-QuadCurve-fig4.png" alt="Quadratic Bézier curve"></p>
15
 *
16
 * <p>Refer to {@link CubicCurve} for a full explanation of the Bézier interpolation process (which explains what the
17
 * control point does).</p>
18
 *
19
 * @author <a href="https://github.com/gann-cdf/graphics/issues" target="_blank">Seth Battis</a>
20
 */
21
public class QuadCurve extends Drawable {
22
  /**
23
   * <p>Construct a new quadratic Bézier curve</p>
24
   *
25
   * <p><img src="doc-files/QuadCurve.png" alt="Diagram of QuadCurve parameters"></p>
26
   *
27
   * <p>All window coordinates are measured in pixels, with the X-axis increasing from left to right and the Y-axis
28
   * increasing from top to bottom. All window coordinates exist in the first quadrant.</p>
29
   *
30
   * <p><img src="../doc-files/window-coordinates.png" alt="Diagram of window coordinates"></p>
31
   *
32
   * @param x1           X-coordinate of starting point
33
   * @param y1           Y-coordinate of starting point
34
   * @param controlX     X-coordinate of control point
35
   * @param controlY     Y-coordinate of control point
36
   * @param x2           X-coordinate of ending point
37
   * @param y2           Y-coordinate of ending point
38
   * @param drawingPanel on which to draw
39
   */
40
  public QuadCurve(double x1, double y1, double controlX, double controlY, double x2, double y2, DrawingPanel drawingPanel) {
41
    try {
42
      setShape(new QuadCurve2D.Double(x1, y1, controlX, controlY, x2, y2));
43
      setDrawingPanel(drawingPanel);
44
    } catch (DrawableException e) {
45
        System.err.println(e.getMessage());
46
      e.printStackTrace();
0 ignored issues
show
Best Practice introduced by
Throwable.printStackTrace writes to the console which might not be available at runtime. Using a logger is preferred.
Loading history...
47
    }
48
  }
49
50
  /**
51
   * @return Underlying {@link QuadCurve2D} geometry
52
   */
53
  protected QuadCurve2D getShapeAsQuadCurve() {
54
    return (QuadCurve2D) getShape();
55
  }
56
57
  @Override
58
  public void setShape(Shape shape) throws DrawableException {
59
    if (shape instanceof QuadCurve2D) {
60
      super.setShape(shape);
61
    } else {
62
      throw new DrawableException("Attempt to set QuadCurve's underlying shape to a non-QuadCurve2D instance");
63
    }
64
  }
65
66
  @Override
67
  public void setWidth(double width) {
68
    // FIXME this feels hacktacular -- surely there's a better way to do this
0 ignored issues
show
Code Smell introduced by
Tasks associated with this FIXME comment should be completed and this comment removed.
Loading history...
69
    double scale = width / getWidth();
70
    setCurve(
71
            getX() + (getX1() - getX()) * scale, getY1(),
72
            getX() + (getCtrlX() - getX()) * scale, getCtrlY(),
73
            getX() + (getX2() - getX()) * scale, getY2()
74
    );
75
  }
76
77
  @Override
78
  public void setHeight(double height) {
79
    // FIXME this feels hacktacular -- surely there's a better way to do this
0 ignored issues
show
Code Smell introduced by
Tasks associated with this FIXME comment should be completed and this comment removed.
Loading history...
80
    double scale = height / getHeight();
81
    setCurve(
82
            getX1(), getY() + (getY1() - getY()) * scale,
83
            getCtrlX(), getY() + (getCtrlY() - getY()) * scale,
84
            getX2(), getY() + (getY2() - getY()) * scale
85
    );
86
  }
87
88
  /**
89
   * Starting point
90
   *
91
   * @return Coordinates of starting point
92
   */
93
  public Point2D getP1() {
94
    return getShapeAsQuadCurve().getP1();
95
  }
96
97
  /**
98
   * Ending point
99
   *
100
   * @return Coordinates of ending point
101
   */
102
  public Point2D getP2() {
103
    return getShapeAsQuadCurve().getP2();
104
  }
105
106
  /**
107
   * <p>Replace the underlying {@link QuadCurve2D} geometry</p>
108
   *
109
   * <p><img src="doc-files/QuadCurve.png" alt="Diagram of QuadCurve parameters"></p>
110
   *
111
   * <p>Replacing the underlying geometry leaves other characteristics (fill, stroke) unchanged</p>
112
   *
113
   * @param x1    X-coordinate of starting point
114
   * @param y1    Y-coordinate of starting point
115
   * @param ctrlX X-Coordinate of control point
116
   * @param ctrlY Y-coordinate of control point
117
   * @param x2    X-coordinate of ending point
118
   * @param y2    Y-coordinate of ending point
119
   */
120
  public void setCurve(double x1, double y1, double ctrlX, double ctrlY, double x2, double y2) {
121
    getShapeAsQuadCurve().setCurve(x1, y1, ctrlX, ctrlY, x2, y2);
122
  }
123
124
  /**
125
   * X-coordinate of starting point
126
   *
127
   * @return X-coordinate of starting point
128
   */
129
  public double getX1() {
130
    return getShapeAsQuadCurve().getX1();
131
  }
132
133
  /**
134
   * Y-coordinate of starting point
135
   *
136
   * @return Y-coordinate of starting point
137
   */
138
  public double getY1() {
139
    return getShapeAsQuadCurve().getY1();
140
  }
141
142
  /**
143
   * X-coordinate of control point
144
   *
145
   * @return X-coordinate of control point
146
   */
147
  public double getCtrlX() {
148
    return getShapeAsQuadCurve().getCtrlX();
149
  }
150
151
  /**
152
   * Y-coordinate of control point
153
   *
154
   * @return Y-coordinate of control point
155
   */
156
  public double getCtrlY() {
157
    return getShapeAsQuadCurve().getCtrlY();
158
  }
159
160
  /**
161
   * Control point
162
   *
163
   * @return Coordinates of control point
164
   */
165
  public Point2D getCtrlPt() {
166
    return getShapeAsQuadCurve().getCtrlPt();
167
  }
168
169
170
  /**
171
   * X-coordinate of ending point
172
   *
173
   * @return X-coordinate of ending point
174
   */
175
  public double getX2() {
176
    return getShapeAsQuadCurve().getX2();
177
  }
178
179
  /**
180
   * Y-coordinate of ending point
181
   *
182
   * @return Y-coordinate of ending point
183
   */
184
  public double getY2() {
185
    return getShapeAsQuadCurve().getY2();
186
  }
187
188
  @Override
189
  public void translate(double dx, double dy) {
190
    getShapeAsQuadCurve().setCurve(getX1() + dx, getY1() + dy, getCtrlX() + dx, getCtrlY() + dy, getX2() + dx, getY2() + dy);
191
  }
192
193
  @Override
194
  public void setLocation(double x, double y) {
195
    translate(x - getX(), y - getY());
196
  }
197
}
198