Reputation: 3
As mentioned in the title, I'm trying to draw rotating and / or concentric figures onto a panel using MVC. Those figures are Circles, Ellipses and Astroids.
I was given the parametric equation I'm supposed to use in the task description:
x = r_x * cos^power(phi * PI/180) and y = r_y * sin^power(phi * PI/180).
Power is 1 (so a normal cos/sin) for circles/ellipses and 3 for Astroids.
I am also supposed to solve this using MVC, which is somewhat new to me, so sometimes I'm unsure whether I can do something or should not do it, lest I violate the MVC character. Phi is used to calculate a certain point on the circle(or Ellipses) and thus can be used to calculate only 3,4,5 etc points, drawing a triangle, square, pentagon etc.
I managed to calculate and draw simple figures using the above formulas. The problem I'm now facing is rotating and/or making them concentric.
Here's the code I'm using right now (the important part):
DescView(mostly basic stuff like setting up Buttons, Labels etc)
public DescView(){
model = new DescModel();
createGUI(); // creates and sets up the frame
createCanvas(); // creates the Panel which is drawn upon(own Class, see below)
createChoiceStuff(); // creates Buttons, Labels, Textfields for Choices
createPanels(); // creates and places the Panel for Choices
addContentToPanels(); // adds the Buttons etc to the Panel
frame.setVisible(true);
controller = new DescController(model, this);
}
Canvas (inner Class to DescView):
class Canvas extends JPanel{
DescModel model;
int temp = 0;
public Canvas(DescModel _model){
this.model = _model;
}
public void paintComponent(Graphics _graphics){
super.paintComponent(_graphics);
//First while loop: Used to prevent drawing when Points is Empty
//which it always is when the program starts.
while(!model.getPoints().isEmpty()){
//second loop: Keeps drawing a Line using a Collection(Points) until
//the last element would go out of bounds.
//drawLine takes the first 4 Elements from Points, then the 2,3,4,5
//and so on.
while(3 + temp < model.getPoints().size()){
_graphics.drawLine(model.getPoints().get(0 + temp), model.getPoints().get(1 + temp), model.getPoints().get(2 + temp), model.getPoints().get(3 + temp));
temp += 2;
}
//drawing the last Line from the two last Points to the first two
_graphics.drawLine(model.getPoints().get(model.getPoints().size() - 2), model.getPoints().getLast(), model.getPoints().getFirst(), model.getPoints().get(1));
//resetting temp and Points so they can be used again
temp = 0;
model.getPoints().clear();
}
}
DescController
public class DescController implements ActionListener {
DescModel model;
DescView view;
DescController(DescModel _model, DescView _view){
this.model = _model;
this.view = _view;
view.addViewListener(this);
}
@Override
public void actionPerformed(ActionEvent ae) {
//asks the model to calculate a circle(or a part of it, depending on degree = phi)
//as you can see, Cirlce and Ellipse doe the same(which is good), unless RadiusX
//and RadiusY are different. After the calculation the Canvas is oredered to
//repainted
if(ae.getSource() == view.getBtCirlce()){
model.calcNumbers(Integer.parseInt(view.getTfRadiusX().getText()), Integer.parseInt(view.getTfRadiusY().getText()), 1, Integer.parseInt(view.getTfDegree().getText()));
view.getCanvas().repaint();
}
else if(ae.getSource() == view.getBtEllipse()){
model.calcNumbers(Integer.parseInt(view.getTfRadiusX().getText()), Integer.parseInt(view.getTfRadiusY().getText()), 1, Integer.parseInt(view.getTfDegree().getText()));
view.getCanvas().repaint();
}
else if(ae.getSource() == view.getBtAstroid()){
model.calcNumbers(Integer.parseInt(view.getTfRadiusX().getText()), Integer.parseInt(view.getTfRadiusY().getText()), 3, Integer.parseInt(view.getTfDegree().getText()));
view.getCanvas().repaint();
}
else if(ae.getSource() == view.getBtInfo()){
view.showInfo();
}
else if(ae.getSource() == view.getBtQuit()){
System.exit(0);
}
}
}
DescModel
public class DescModel {
int x = 1;
int y = 1;
LinkedList<Integer> points = new LinkedList<Integer>();
public DescModel() {
}
//calculates X and Y coordinates one by one. Phi is used to calculate only a
//certain number of points. For example for phi = 90 a Square is drawn
//and a full circle for phi = 1 (if X = Y).
//addOffset is used to place the figure in the middle of Canvas, which
//has a width and height of 600.
public void calcNumbers(int _radiusX, int _radiusY, int _potenz, int _phi){
for(int i = 1; i <= 360 / _phi; i++){
calcX(_radiusX, _potenz, _phi * i);
calcY(_radiusY, _potenz, _phi * i);
}
addOffset();
}
//Calculates using the above formula and adds the point to the Collection
private void calcX(int _radiusX, int _potenz, int _phi){
x = 300 + (int)(_radiusX * Math.pow(Math.cos(_phi * (Math.PI / 180)), _potenz));
addToPoints(x);
}
private void calcY(int _radiusY, int _potenz, int _phi){
y = 300 + (int)(_radiusY * Math.pow(Math.sin(_phi * (Math.PI / 180)), _potenz));
addToPoints(y);
}
private void addOffset(){
for(int i = 0; i < points.size(); i++){
}
}
private void addToPoints(int _number){
points.add(_number);
}
}
Now the next thing I want to / have to do is allowing the option of rotating with a fixed radius and drawing the same thing concentric. Obviously I could run the same model.calcNumbers() with smaller parameters. However, I'm not sure I can do that, since the view should not make a call to the model directly right? And even if that would be allowed, if I were to call repaint, the old circle would disappear. Using the same array also wouldn't work, since then I would draw circles which all had a single line connecting them. Regarding rotation, I'd probably add a certain value to each point and then draw it again. How would I go about that drawing part though? Same problem as with concentric: The old picture would be gone.
Thanks in advance for any help.
Edit: Since there appears to be some confusion: I don't need an animation of this. It'd be enough to have a set of shapes. For Example: Draw a circle with radius 100, another with radius 90, next with radius 80 etc.
On a side note: This is the first question for me, so any tips regarding formatting, formulating the question better etc. are of course welcome.
Upvotes: 0
Views: 418
Reputation: 205805
This AnimationTest
illustrates the basic approach using a simpler parametric equation. For rotations, you can use AffineTransform
, as shown here and here. Finally, this answer elaborates on how Swing uses the MVC pattern.
Upvotes: 1