[英]Drawing moving circle on edge of circle
I'm having troubles with my drawing: 我在绘画时遇到麻烦:
Basically, I have an arc drawn: 基本上,我画了一条弧:
g.drawArc(x1-75, y2, 150, 150, 90, 180);
and from what I'm getting, this draws me left half of a circle, based on rectangle(well, square in that case) with the edge of 150 and left right corner x1-75,y2. 从我得到的结果中,这得出了我的一个圆的左半部分,该矩形是基于矩形(在这种情况下是正方形),其边缘为150,左角为x1-75,y2。 It's radius should be 75.
半径应为75。
Now I'm drawing a small point: 现在,我要指出一点:
g.fillOval(x-5, y-5, 10, 10);
and I set 然后我设定
x = x1 + (75*cos(3*Math.PI/2));
y = y2 + 75 + (75*sin(3*Math.PI/2));
which I believe should set the small circle on the bottom of the arc. 我认为应该在圆弧的底部设置一个小圆圈。
Let's have 让我们
int n = 0;
Now I have a timer, that for every tick does 现在我有一个计时器,每一个刻度
n += 1;
and repaints component. 并重新绘制组件。
Shouldn't this code: 此代码不应该:
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))));
}
lead the small circle around the arc in clockwise direction? 沿顺时针方向绕弧线引导小圆圈?
Instead it seems to me it jumps to random point on screen and stays there. 相反,在我看来,它跳到屏幕上的随机点并停留在该位置。
This gets a lot easier with any kind of Object Oriented Model. 使用任何一种面向对象的模型,这都变得容易得多。 Start with a circle object that keeps track of its location and its radius, and is able to paint itself when given a graphics object.
从一个圆形对象开始,该对象跟踪其位置和半径,并在给定图形对象时能够绘制自身。
From there, I surrounded that with a CircleOrbit object that keeps track of: 从那里开始,我用一个CircleOrbit对象围绕了该对象,该对象跟踪:
center
center
orbiter
that changes its position as time goes on orbiter
I then added a method to recalculate the position of the oribiter
at a given tick
amount, updateOrbiterLoc()
. 然后我添加了一个方法来重新计算的位置
oribiter
在给定的tick
量, updateOrbiterLoc()
From there it is fairly simple to create a helper to both increase the tick and update the orbiter location, and a simple JPanel
subclass to paint the CircleOrbit
. 从那里开始,创建一个既增加刻度线又更新轨道器位置的助手非常简单,并创建一个简单的
JPanel
子类来绘制CircleOrbit
。
Finally, in the main
method, I created a simple JFrame
holding the JPanel
subclass, and created a timer to call the tick()
method and repaint the frame. 最后,在
main
方法中,我创建了一个包含JPanel
子类的简单JFrame
,并创建了一个计时器来调用tick()
方法并重新绘制框架。
The circle starts on the x-axis and rotates clockwise. 圆从x轴开始,然后顺时针旋转。 The rotation speed is determined by
TIMER_DELAY
. 旋转速度由
TIMER_DELAY
确定。
Here's a basic runnable implementation that gets the job done. 这是完成任务的基本可运行实现。
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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.