Issues (88)

src/main/java/example/RotationExample.java (13 issues)

1
package example;
2
3
import org.gannacademy.cdf.graphics.Text;
4
import org.gannacademy.cdf.graphics.geom.Path;
5
import org.gannacademy.cdf.graphics.ui.AppWindow;
6
7
import java.awt.*;
8
import java.awt.event.MouseEvent;
9
import java.awt.event.MouseListener;
10
import java.awt.geom.PathIterator;
11
import java.awt.geom.Point2D;
12
13
public class RotationExample extends AppWindow implements MouseListener {
14
    private static final double
15
            BASE = 50,
16
            HEIGHT = 100,
17
            THETA = Math.PI / 180.0,
18
            CROSSHAIR_ARM = 20;
19
    private Path path, crosshair;
0 ignored issues
show
Bug Best Practice introduced by
Fields like crosshair in a serializable class should either be transient or serializable.
Loading history...
Bug Best Practice introduced by
Fields like path in a serializable class should either be transient or serializable.
Loading history...
20
    private double x, y;
0 ignored issues
show
Comprehensibility introduced by
Your field or variable is shadowing field y in the class Component. Consider renaming it.
Loading history...
Comprehensibility introduced by
Your field or variable is shadowing field x in the class Component. Consider renaming it.
Loading history...
21
    private boolean mouseDown;
22
    private int button;
23
24
    @Override
25
    protected void setup() {
26
        // show instructions to user
27
        new Text("Left, middle, or right-click to rotate the triangle", 10, 40, getDrawingPanel());
0 ignored issues
show
Use try-with-resources or close this "Text" in a "finally" clause.

You may want to use try {} ... finally {} to close the resource or use the (relatively) new try-with-resources capability.

Loading history...
28
        x = getDrawingPanel().getWidth() / 2.0;
29
30
        // calculate top point of triangle
31
        y = (getDrawingPanel().getHeight() - HEIGHT) / 2.0;
32
33
        defineAnchorPointCrosshair();
34
        defineTriangle();
35
36
        // align crosshair to center of gravity
37
        Point2D center = getCentroid();
38
        crosshair.setLocation(center.getX() - CROSSHAIR_ARM, center.getY() - CROSSHAIR_ARM);
39
40
        // register to be notified of mouse events (and assume no one is clicking right now)
41
        mouseDown = false;
42
        getDrawingPanel().addMouseListener(this);
43
        getDrawingPanel().requestFocus();
44
    }
45
46
    private void defineTriangle() {
47
        path = new Path(getDrawingPanel());
48
        path.moveTo(x, y); // move to top point
49
        path.lineTo(x + BASE / 2.0, y + HEIGHT); // line to bottom-right point
50
        path.lineTo(x - BASE / 2.0, y + HEIGHT); // line to bottom-left point
51
        path.lineTo(x, y);
52
        path.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
53
    }
54
55
    private void defineAnchorPointCrosshair() {
56
        crosshair = new Path(getDrawingPanel());
57
        crosshair.moveTo(CROSSHAIR_ARM, 0);
58
        crosshair.lineTo(CROSSHAIR_ARM, CROSSHAIR_ARM * 2);
59
        crosshair.moveTo(0, CROSSHAIR_ARM);
60
        crosshair.lineTo(CROSSHAIR_ARM * 2, CROSSHAIR_ARM);
61
        crosshair.setStrokeColor(Color.RED);
62
    }
63
64
    @Override
65
    protected void loop() {
66
        if (mouseDown) {
67
68
            double theta = THETA; // default, rotate clockwise around mouse
69
            double x = this.x, y = this.y; // default, use whatever (roundRect, ellipse) is currently set for axis of rotation
0 ignored issues
show
Comprehensibility introduced by
The variable xshadows a field with the same name declared in line 20. Consider renaming it.
Loading history...
Comprehensibility introduced by
The variable yshadows a field with the same name declared in line 20. Consider renaming it.
Loading history...
70
71
            if (button == MouseEvent.BUTTON1) theta *= -1; // left button, rotate counter-clockwise around mouse
72
73
            else if (button == MouseEvent.BUTTON2) { // middle button, rotate around center of gravity
74
                // use center of gravity calculation as rotation axis
75
                Point2D center = getCentroid();
76
                x = center.getX();
77
                y = center.getY();
78
            }
79
80
            // rotate, using any adjustments to theta and axis of rotiation
81
            path.rotate(theta, x, y);
82
            crosshair.setLocation(x - CROSSHAIR_ARM, y - CROSSHAIR_ARM);
83
        }
84
        sleep(25);
85
    }
86
87
    public Point2D getCentroid() {
88
        double[] coords = new double[6]; // to hold coordinates
89
        double x = 0, y = 0; // tally roundRect and ellipse-coordinates
0 ignored issues
show
Comprehensibility introduced by
The variable xshadows a field with the same name declared in line 20. Consider renaming it.
Loading history...
Comprehensibility introduced by
The variable yshadows a field with the same name declared in line 20. Consider renaming it.
Loading history...
90
        int points = 0; // haven't visited any points yet!
91
        for (PathIterator i = path.getPathIterator(null); !i.isDone(); i.next()) {
92
            switch (i.currentSegment(coords)) {
93
                case PathIterator.SEG_MOVETO:
94
                case PathIterator.SEG_LINETO:
95
                    x += coords[0];
96
                    y += coords[1];
97
                    break;
98
                case PathIterator.SEG_QUADTO:
99
                    x += coords[2];
100
                    y += coords[3];
101
                    break;
102
                case PathIterator.SEG_CUBICTO:
103
                    x += coords[4];
104
                    y += coords[5];
105
                    break;
106
                case PathIterator.SEG_CLOSE:
107
                default:
108
                    // do nothing
109
            }
110
            points++;
111
        }
112
113
        // package (roundRect, ellipse) coordinates into r single object
114
        return new Point2D.Double(x / points, y / points);
0 ignored issues
show
Make sure "points" can't be zero before doing this division.
Loading history...
115
    }
116
117
    @Override
118
    public void mouseClicked(MouseEvent e) {
0 ignored issues
show
An empty method may be confusing. Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.
Loading history...
119
    }
120
121
    @Override
122
    public void mousePressed(MouseEvent e) {
123
        mouseDown = true;
124
        button = e.getButton();
125
        x = e.getX();
126
        y = e.getY();
127
    }
128
129
    @Override
130
    public void mouseReleased(MouseEvent e) {
131
        mouseDown = false;
132
    }
133
134
    @Override
135
    public void mouseEntered(MouseEvent e) {
0 ignored issues
show
An empty method may be confusing. Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.
Loading history...
136
    }
137
138
    @Override
139
    public void mouseExited(MouseEvent e) {
0 ignored issues
show
An empty method may be confusing. Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.
Loading history...
140
    }
141
142
    public static void main(String[] args) {
143
        new RotationExample();
144
    }
145
}
146