正如标题中提到的,我正在尝试使用 MVC 在面板上绘制旋转和/或同心图形。这些图形是圆形、椭圆形和星形。
我得到了我应该在任务描述中使用的参数方程:
x = r_x * cos^power(phi * PI/180) and y = r_y * sin^power(phi * PI/180).
圆/椭圆的幂为 1(因此是正常的余弦/正弦),星体的幂为 3。
我还应该使用 MVC 来解决这个问题,这对我来说有点新,所以有时我不确定我是否可以做某事或不应该做某事,以免违反 MVC 特性。 Phi 用于计算圆(或椭圆)上的某个点,因此只能用于计算 3、4、5 等点,绘制三角形、正方形、五边形等。
我设法使用上述公式计算并绘制了简单的图形。 我现在面临的问题是旋转和/或使它们同心。
这是我现在使用的代码(重要部分):
描述 View (主要是基本的东西,比如设置按钮、标签等)
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(DESView 的内部类):
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();
}
}
描述 Controller
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);
}
}
现在我想要/必须做的下一件事是允许选择以固定半径旋转并同心绘制相同的物体。 显然我可以使用较小的参数运行相同的 model.calcNumbers() 。但是,我不确定我可以这样做,因为 View 不应该直接调用模型,对吗?即使允许这样做,如果我调用重新绘制,旧的圆圈也会消失。 使用相同的数组也是行不通的,因为从那时起我会画一些圆圈,这些圆圈都有一条线连接它们。 关于旋转,我可能会为每个点添加一定的值,然后再次绘制它。我该如何进行绘图部分呢?与同心圆相同的问题:旧图片会消失。
预先感谢您的帮助。
编辑:由于似乎存在一些困惑:我不需要这个动画。有一组形状就足够了。例如:画一个半径为 100 的圆,另一个半径为 90,再画一个半径为 80 等。
旁注:这是我的第一个问题,因此当然欢迎任何有关格式设置、更好地表述问题等方面的提示。
最佳答案
这个AnimationTest
使用更简单的参数方程说明基本方法。对于旋转,您可以使用AffineTransform
,如图here和 here 。最后这个answer详细阐述了 Swing 如何使用 MVC 模式。
关于java - 使用 MVC 绘制同心/旋转图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24713455/