在圈子的边缘上绘制移动圆圈

时间:2015-01-27 21:35:58

标签: java

我的绘图遇到了麻烦:

基本上,我画了一个圆弧:

g.drawArc(x1-75, y2, 150, 150, 90, 180);

从我得到的结果来看,这画了一个圆圈的左半部分,基于矩形(在这种情况下为正方形),边缘为150,左上角为x1-75,y2。它的半径应该是75。

现在我画一个小点:

g.fillOval(x-5, y-5, 10, 10);

我设置

x = x1 + (75*cos(3*Math.PI/2));
y = y2 + 75 + (75*sin(3*Math.PI/2));

我认为应该在圆弧的底部设置一个小圆圈。

我们有

int n = 0; 

现在我有一个计时器,每个刻度线都有

n += 1;

并重新绘制组件。

不应该使用此代码:

if(n < 180){
x = (int) (x1 + (75*(Math.cos(3*Math.PI/2 - n*Math.PI/180))));
y = (int) (y2 + 75 + (75*-(Math.sin(3*Math.PI/2 - n*Math.PI/180))));
}

沿顺时针方向绕圆弧引导小圆圈?

相反,在我看来,它会跳到屏幕上的随机点并停留在那里。

1 个答案:

答案 0 :(得分:1)

使用任何类型的面向对象模型都可以轻松实现。从一个跟踪其位置和半径的圆形对象开始,并且在给定图形对象时能够自己绘制。

从那里开始,我用CircleOrbit对象包围了该对象,该对象跟踪:

  • 未移动的中心圆center
  • 随着时间的推移改变其位置的轨道圈orbiter
  • 刻度线(轨道位置)。我把它实现为学位,但这很容易改变。

然后我添加了一种方法来重新计算给定oribiter金额tick updateOrbiterLoc()的位置JPanel。从那里创建一个助手来增加刻度并更新轨道器位置,以及一个简单的CircleOrbit子类来绘制main非常简单。

最后,在JFrame方法中,我创建了一个包含JPanel子类的简单tick(),并创建了一个计时器来调用TIMER_DELAY方法并重新绘制帧。

圆圈从x轴开始并顺时针旋转。转速由import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Point2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class CircleOrbit{ private Circle center; private Circle orbiter; private int tick; //Amount in degrees * this const = amount in radians private static final double DEG_TO_RAD = Math.PI / 180; private static final int TIMER_DELAY = 25; /** Constructor for a CircleOrbit object. * Uses the given circle as the center circle, creates an * orbiter circle 1/10th the radius of the center and * on the x-axis of the center circle to start. * These constants should probably be pulled out to final ints * in a real implementation. */ public CircleOrbit(Circle center){ this.center = center; orbiter = new Circle(new Point2D.Double(), center.radius/10); tick = 0; updateOrbiterLoc(); } /** Updates the location of the orbiter circle based on tick */ private void updateOrbiterLoc(){ Point2D.Double d = new Point2D.Double(); final double xCenter = center.center.x; final double yCenter = center.center.y; final double rad = center.radius; d.setLocation(xCenter + rad * Math.cos(tick * DEG_TO_RAD), yCenter + rad * Math.sin(tick * DEG_TO_RAD)); orbiter.setCenter(d); } /** Increases tick and recalculates the position of the orbiter */ public void tick(){ tick += 1; updateOrbiterLoc(); } /** Draws both of the circles in this CircleOrbit */ public void draw(Graphics2D g){ center.draw(g); orbiter.draw(g); } /** Creates a new panel to draw this orbit */ public OrbitPanel getPanel(){ return new OrbitPanel(); } public static void main(String[] args){ JFrame f = new JFrame(); final CircleOrbit c = new CircleOrbit(new Circle(new Point2D.Double(250, 250), 200)); final OrbitPanel o = c.getPanel(); f.add(o, BorderLayout.CENTER); f.pack(); f.setVisible(true); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); final Timer t = new Timer(TIMER_DELAY, null); t.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { c.tick(); o.repaint(); t.restart(); } }); t.start(); } @SuppressWarnings("serial") class OrbitPanel extends JPanel{ public OrbitPanel(){ //Quick and dirty way of making sure the panel is big enough setPreferredSize(new Dimension( (int)(center.center.x + center.radius * 1.1), (int)(center.center.y + center.radius * 1.1) )); } @Override public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.BLACK); CircleOrbit.this.draw((Graphics2D)g); } } static class Circle { private Point2D.Double center; private double radius; public Circle(Point2D.Double c, double r){ center = c; radius = r; } public void setCenter(Point2D.Double c){ center = c; } public void draw(Graphics2D g){ int x = (int)(center.x - radius); int y = (int)(center.y - radius); int size = (int)(radius * 2); g.drawOval(x, y, size, size); } public String toString(){ return center.toString() + " r=" + radius; } } } 确定。

这是一个基本的可运行实现,可以完成工作。

{{1}}