summaryrefslogtreecommitdiff
path: root/CSMath/src/CulkinAsssignmentNine.java
diff options
context:
space:
mode:
authorstudent <student@localhost>2018-04-09 17:43:42 -0400
committerstudent <student@localhost>2018-04-09 17:43:42 -0400
commit6a74c3b8f900487fdb1c2ae81251c68edecd2027 (patch)
tree2718e778919591599b15fa3135b0a96eee721254 /CSMath/src/CulkinAsssignmentNine.java
parent88fc0b666c58334009bc274105ea0d2b90edf75d (diff)
Update
Diffstat (limited to 'CSMath/src/CulkinAsssignmentNine.java')
-rw-r--r--CSMath/src/CulkinAsssignmentNine.java275
1 files changed, 258 insertions, 17 deletions
diff --git a/CSMath/src/CulkinAsssignmentNine.java b/CSMath/src/CulkinAsssignmentNine.java
index da4290d..e1e7da7 100644
--- a/CSMath/src/CulkinAsssignmentNine.java
+++ b/CSMath/src/CulkinAsssignmentNine.java
@@ -1,25 +1,47 @@
import java.awt.BorderLayout;
+import java.awt.Color;
import java.awt.Component;
+import java.awt.Dialog.ModalityType;
+import java.awt.Graphics;
import java.awt.GridLayout;
-import java.util.Arrays;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
+import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.ListCellRenderer;
+import javax.swing.border.BevelBorder;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+@SuppressWarnings("javadoc")
public class CulkinAsssignmentNine {
public static void main(String[] args) {
- JFrame fram = new JFrame();
+ JFrame fram = new JFrame("Bezier Grapher");
fram.setLayout(new GridLayout(1, 1));
- JPanel canvas = new JPanel();
- canvas.setLayout(new GridLayout(1, 1));
+ JPanel canvasPanel = new JPanel();
+ canvasPanel.setLayout(new GridLayout(1, 1));
+
+ Bezier curve = new Bezier();
+
+ BezierPanel canvas = new BezierPanel();
+ canvas.curves.add(curve);
+
+ canvasPanel.add(canvas);
JPanel points = new JPanel();
points.setLayout(new BorderLayout());
@@ -28,6 +50,7 @@ public class CulkinAsssignmentNine {
listPanel.setLayout(new GridLayout(1, 1));
DefaultListModel<TDPoint> pointModel = new DefaultListModel<>();
+ pointModel.addListDataListener(new CanvasRepainter(canvas));
JList<TDPoint> pointList = new JList<>(pointModel);
pointList.setCellRenderer(new TDPointRenderer());
@@ -39,9 +62,11 @@ public class CulkinAsssignmentNine {
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(1, 2));
- JButton addPoint = new JButton("Add Control Point");
+ JButton addPoint = new JButton("Add Control Points...");
+ addPoint.addActionListener(new PointAdder(pointModel, curve, fram));
JButton remPoint = new JButton("Remove Control Point");
+ remPoint.addActionListener(new PointRemover(fram, pointList, pointModel));
buttonPanel.add(addPoint);
buttonPanel.add(remPoint);
@@ -49,7 +74,7 @@ public class CulkinAsssignmentNine {
points.add(listPanel, BorderLayout.CENTER);
points.add(buttonPanel, BorderLayout.PAGE_END);
- JSplitPane main = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, points, canvas);
+ JSplitPane main = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, points, canvasPanel);
fram.add(main);
@@ -59,20 +84,233 @@ public class CulkinAsssignmentNine {
}
}
+class CanvasRepainter implements ListDataListener {
+ private final BezierPanel canvas;
+
+ public CanvasRepainter(BezierPanel canvas) {
+ this.canvas = canvas;
+ }
+
+ @Override
+ public void intervalRemoved(ListDataEvent e) {
+ canvas.repaint();
+ }
+
+ @Override
+ public void intervalAdded(ListDataEvent e) {
+ canvas.repaint();
+ }
+
+ @Override
+ public void contentsChanged(ListDataEvent e) {
+ canvas.repaint();
+ }
+}
+
+class PointAdder implements ActionListener {
+ private final DefaultListModel<TDPoint> pointModel;
+ private final Bezier curve;
+ private final JFrame fram;
+
+ public PointAdder(DefaultListModel<TDPoint> pointModel, Bezier curve, JFrame fram) {
+ this.pointModel = pointModel;
+ this.curve = curve;
+ this.fram = fram;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ JDialog dia = new JDialog(fram);
+ dia.setTitle("Add Control Point");
+ dia.setModalityType(ModalityType.MODELESS);
+ dia.setLayout(new BorderLayout());
+
+ JPanel fields = new JPanel();
+ fields.setLayout(new GridLayout(2, 1));
+
+ DoubleInputPanel xPanel = new DoubleInputPanel("X Coordinate: ");
+ DoubleInputPanel yPanel = new DoubleInputPanel("Y Coordinate: ");
+
+ fields.add(xPanel);
+ fields.add(yPanel);
+
+ JPanel buttons = new JPanel();
+ buttons.setLayout(new GridLayout(1, 2));
+
+ JButton add = new JButton("Add Control Point");
+
+ AddListener addListener = new AddListener(xPanel, yPanel);
+ add.addActionListener(addListener);
+
+ JButton cancel = new JButton("Cancel");
+ cancel.addActionListener((aev) -> {
+ dia.dispose();
+ });
+
+ buttons.add(add);
+ buttons.add(cancel);
+
+ xPanel.field.addActionListener((aev) -> {
+ yPanel.field.requestFocusInWindow();
+ });
+
+ yPanel.field.addActionListener((aev) -> {
+ addListener.actionPerformed(null);
+ });
+
+ dia.add(fields, BorderLayout.CENTER);
+ dia.add(buttons, BorderLayout.PAGE_END);
+
+ dia.pack();
+ dia.setVisible(true);
+ }
+
+ class AddListener implements ActionListener {
+ private final DoubleInputPanel xPanel;
+ private final DoubleInputPanel yPanel;
+
+ public AddListener(DoubleInputPanel xPanel, DoubleInputPanel yPanel) {
+ this.xPanel = xPanel;
+ this.yPanel = yPanel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent aev) {
+ double xVal = (Double) xPanel.field.getValue();
+ double yVal = (Double) yPanel.field.getValue();
+
+ TDPoint punkt = new TDPoint(xVal, yVal);
+
+ pointModel.addElement(punkt);
+ curve.controls.add(punkt);
+
+ xPanel.field.setValue(0.0);
+ yPanel.field.setValue(0.0);
+
+ xPanel.field.requestFocusInWindow();
+ }
+ }
+}
+
+class PointRemover implements ActionListener {
+ private final JFrame fram;
+ private final JList<TDPoint> pointList;
+ private final DefaultListModel<TDPoint> pointModel;
+
+ public PointRemover(JFrame fram, JList<TDPoint> pointList, DefaultListModel<TDPoint> pointModel) {
+ this.fram = fram;
+ this.pointList = pointList;
+ this.pointModel = pointModel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ int selectedIndex = pointList.getSelectedIndex();
+ TDPoint punkt = pointModel.get(selectedIndex);
+
+ String msg = String.format("Do you want to remove the control point (%.2f, %.2f)?", punkt.x, punkt.y);
+
+ int confirmed = JOptionPane.showConfirmDialog(fram, msg, "Remove Control Point?", JOptionPane.YES_NO_OPTION);
+
+ if (confirmed == JOptionPane.YES_OPTION) {
+ pointModel.remove(selectedIndex);
+ }
+ }
+}
+
+class DoubleInputPanel extends JPanel {
+ private static final long serialVersionUID = 1031310890698539040L;
+
+ public final JFormattedTextField field;
+
+ public DoubleInputPanel(String label) {
+ super();
+ setLayout(new BorderLayout());
+
+ JLabel xLabel = new JLabel(label);
+
+ field = new JFormattedTextField(0.0);
+
+ add(xLabel, BorderLayout.LINE_START);
+ add(field, BorderLayout.CENTER);
+ }
+}
+
+class BezierPanel extends JPanel {
+ public final List<Bezier> curves;
+
+ private static final long serialVersionUID = 8748298173487657108L;
+
+ public BezierPanel() {
+ super();
+
+ curves = new LinkedList<>();
+
+ setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ int ourWidth = getWidth();
+ int ourHeight = getHeight();
+
+ int halfWidth = ourWidth / 2;
+ int halfHeight = ourHeight / 2;
+
+ g.setColor(Color.WHITE);
+
+ g.translate(halfWidth, halfHeight);
+
+ g.fillRect(-halfWidth, -halfHeight, ourWidth, ourHeight);
+
+ g.setColor(Color.BLACK);
+
+ for (Bezier curve : curves) {
+ for (int i = 0; i < curve.parts; i++) {
+ double dT = 1.0 / curve.parts;
+
+ TDPoint first = curve.scaleEval(dT * i);
+ TDPoint second = curve.scaleEval(dT * (i + 1));
+
+ g.drawLine((int) first.x, (int) first.y, (int) second.x, (int) second.y);
+ }
+ }
+ }
+}
+
class Bezier {
- public final TDPoint[] controls;
+ public final List<TDPoint> controls;
+
+ public int parts = 100;
+ public int scale = 5;
public Bezier(TDPoint... points) {
- controls = points;
+ controls = new ArrayList<>();
+
+ for (TDPoint punkt : points) {
+ controls.add(punkt);
+ }
+ }
+
+ public TDPoint scaleEval(double t) {
+ return eval(t).multiply(scale);
}
public TDPoint eval(double t) {
- return evalIntern(t, controls.length, 0);
+ if (controls.isEmpty())
+ return new TDPoint(0, 0);
+
+ TDPoint punkt = evalIntern(t, controls.size() - 1, 0);
+
+ return punkt;
}
private TDPoint evalIntern(double t, int j, int k) {
- if (j == 0)
- return controls[k];
+ if (j <= 0) {
+ return controls.get(k);
+ }
TDPoint l = evalIntern(t, j - 1, k);
TDPoint r = evalIntern(t, j - 1, k + 1);
@@ -87,7 +325,7 @@ class Bezier {
Bezier[] curves = new Bezier[2];
{
- TDPoint[] points = new TDPoint[controls.length];
+ TDPoint[] points = new TDPoint[controls.size()];
for (int i = 0; i < points.length; i++) {
points[i] = evalIntern(t, i, 0);
}
@@ -95,7 +333,7 @@ class Bezier {
}
{
- TDPoint[] points = new TDPoint[controls.length];
+ TDPoint[] points = new TDPoint[controls.size()];
for (int i = 0; i < points.length; i++) {
points[i] = evalIntern(t, (points.length - 1) - i, i);
}
@@ -109,7 +347,7 @@ class Bezier {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + Arrays.hashCode(controls);
+ result = prime * result + ((controls == null) ? 0 : controls.hashCode());
return result;
}
@@ -122,14 +360,17 @@ class Bezier {
if (getClass() != obj.getClass())
return false;
Bezier other = (Bezier) obj;
- if (!Arrays.equals(controls, other.controls))
+ if (controls == null) {
+ if (other.controls != null)
+ return false;
+ } else if (!controls.equals(other.controls))
return false;
return true;
}
@Override
public String toString() {
- return "Bezier [controls=" + Arrays.toString(controls) + "]";
+ return String.format("Bezier [controls=%s]", controls);
}
}
@@ -208,7 +449,7 @@ final class TDPointRenderer extends JLabel implements ListCellRenderer<TDPoint>
setForeground(list.getForeground());
}
- setText(String.format("(%.2d, %.2d)", value.x, value.y));
+ setText(String.format("(%.2f, %.2f)", value.x, value.y));
return this;
}