正如标题中所提到的,我试图使用MVC将旋转和/或同心图形绘制到面板上。这些数字是Circles,Ellipses和Astroids。
我得到了我应该在任务描述中使用的参数方程式:
x = r_x * cos^power(phi * PI/180) and y = r_y * sin^power(phi * PI/180).
圆圈/椭圆的功率为1(因此是正常的cos / sin),星形的功率为3。
我也应该使用MVC来解决这个问题,这对我来说有点新鲜,所以有时候我不确定我是否可以做某事或者不应该这样做,以免我违反MVC角色。 Phi用于计算圆(或椭圆)上的某个点,因此可用于计算3,4,5等点,绘制三角形,正方形,五边形等。
我设法使用上面的公式计算和绘制简单的数字。 我现在面临的问题是旋转和/或使它们同心。
这是我现在正在使用的代码(重要部分):
DescView(主要是设置按钮,标签等基本内容)
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(内部类到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);
}
}
现在接下来我想要/必须做的是允许选择以固定半径旋转并同心绘制相同的东西。 显然,我可以使用较小的参数运行相同的model.calcNumbers()。但是,我不确定我能做到这一点,因为视图不应该直接调用模型吗?即使这是允许的,如果我要重新打电话,旧圈子也会消失。 使用相同的数组也不会起作用,因为那时我会绘制圆圈,它们都有一条连接它们的线。 关于旋转,我可能会为每个点添加一定值,然后再次绘制它。我怎么会去那个绘图部分呢?与同心相同的问题:旧图片将消失。
提前感谢您的帮助。
编辑:因为似乎有些混乱:我不需要动画这个。它足以拥有一组形状。例如:绘制一个半径为100的圆,另一个半径为90的圆,其次是半径80等。
旁注:这是我的第一个问题,所以有关格式化,更好地制定问题等的提示当然是受欢迎的。
答案 0 :(得分:1)
这个AnimationTest
说明了使用更简单的参数方程的基本方法。对于轮换,您可以使用AffineTransform
,如here和here所示。最后,这个answer详细说明了Swing如何使用MVC模式。