Java 使用MVC绘制同心/旋转图形

Java 使用MVC绘制同心/旋转图形,java,swing,model-view-controller,jpanel,draw,Java,Swing,Model View Controller,Jpanel,Draw,正如标题中提到的,我正在尝试使用MVC在面板上绘制旋转和/或同心图形。这些图形是圆、椭圆和星体 我得到了任务描述中应该使用的参数方程: x = r_x * cos^power(phi * PI/180) and y = r_y * sin^power(phi * PI/180). 圆/椭圆的幂为1(所以是正常的cos/sin),星体的幂为3 我还应该用MVC来解决这个问题,这对我来说有些陌生,所以有时候我不确定我是否可以做一些事情或者不应该做,以免违反MVC的特性。Phi用于计算

正如标题中提到的,我正在尝试使用MVC在面板上绘制旋转和/或同心图形。这些图形是圆、椭圆和星体

我得到了任务描述中应该使用的参数方程:

    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等点,绘制三角形、正方形、五边形等

我设法用上述公式计算并画出简单的数字。 我现在面临的问题是旋转和/或使它们同心

下面是我现在正在使用的代码(重要部分):

描述视图(主要是设置按钮、标签等基本内容)

画布(要描述视图的内部类):

描述模型

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);
    }
}
公共类模型{
int x=1;
int y=1;
LinkedList points=新建LinkedList();
公共模型(){
}
//逐个计算X和Y坐标。φ仅用于计算a
//一定数量的点。例如,对于φ=90,绘制一个正方形
//和一个完整的圆表示φ=1(如果X=Y)。
//AddiS偏移用于将图形放置在画布中间,
//具有600的宽度和高度。
公共空白计算编号(整数半径x、整数半径y、整数波滕兹、整数φ){

对于(int i=1;i这说明了使用更简单的参数方程的基本方法。对于旋转,您可以使用
仿射变换,如图所示和所示。最后,这详细说明了Swing如何使用MVC模式。

对于我来说,还不完全清楚最后要绘制什么。对象应该设置动画,还是简单地设置动画可以是多个对象,排列成一个圆圈?(顺便说一句:当你发布一个,你通常会很快得到更好的帮助。只需将代码复制粘贴到IDE中并查看当前状态总是很有帮助的…)@Marco13:在整件事的结尾做一个编辑,希望能把它弄清楚。关于mcve:因为我的部分问题是MVC模型(相反,我能做什么,不能做什么),当我需要几个类时,我应该如何创建最少的代码?如果我要发布可用的代码,我必须添加一些东西(比如框架、按钮等)。可能有一种方法可以解决这个问题,尽管我看不到。也许垃圾神的链接已经回答了这个问题。但是我在再次滚动代码时注意到:你不应该调用
model.getPoints().clear();
方法中的
paintComponent
从“高级”从角度来看,这意味着视图修改了模型,这是不合适的。但更重要的是:
paintComponent
可能会被多次调用,目前,它只会在第一次调用时绘制内容。一般来说,
paintComponent
方法不应该有任何副作用(也就是说,它不应该更改任何状态)。感谢您对clear()的提示。我可能只需将clear位置更改为calcNUmbers()的模型调用或者别的什么。我不知道这些链接是否会有帮助,我目前正在尝试弄清楚如何处理g2d的东西。尽管这些链接不能解决我的问题,但它们在理解概念、我的选项等方面起到了辩护性的帮助。非常感谢。所以最后,我没有使用g2d。相反,我只使用一个集合来存储每个点。为了当一个新的更小的圆开始时,我在中间加了一个“-1”。此外,我还更改了calcNumbers()的参数,使其也采用两个布尔值,“旋转”和“同心”.根据他们的不同,我调用了不同的计算。这些计算主要是利用for循环来减小半径或改变位置。尽管如此,这些技巧确实有助于了解一般情况下的情况(甚至不知道存在仿射变换)。谢谢你们两位。
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();
        }               
    }   
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);
        }
    }
}
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);
    }
}