在圆形轨迹中移动物体的问题

3

我对安卓动画不太熟悉。我正在使用在YouTube上找到的教程进行学习。该应用程序在画布上绘制了一个球的图片,然后将其对角线移动。我想让球按圆形轨迹移动。我已经找到了一些有关圆周运动基本数学的信息,但是我无法实现它。有人能看看我的代码并告诉我哪里出了问题吗?谢谢。

以下是我的代码:

public class DrawingTheBall extends View {

Bitmap bball; 
int x,y;

public DrawingTheBall(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
    x = 0;
    y = 0;
}

@Override
public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    Rect ourRect = new Rect();
    ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
    float a = 10;
    float b = 10;
    float r = 20;
    double theta = 0;
    theta = Math.toRadians(45);

    Paint blue = new Paint();
    blue.setColor(Color.BLUE);
    blue.setStyle(Paint.Style.FILL);

    canvas.drawRect(ourRect, blue);

    if(x < canvas.getWidth()){
        //x += 10;
        x = (int) (a +r*Math.cos(theta));
    }else{
        x = 0;
    }
    if(y < canvas.getHeight()){
        //y += 10;
        y = (int) (b +r*Math.sin(theta));
    }else{
        y = 0;
    }
    Paint p = new Paint();
    canvas.drawBitmap(bball, x, y, p);
    invalidate();
}

}


看起来没问题,不过我认为你应该尝试交换cos和sin的位置,这样x = (int)(a + r * Math.sin(100)),y = (int)(b + r * Math.cos(100)),然后增加100的值以使其继续在圆形路径上移动。 - Andrew Cumming
当他的坐标依赖于常数角度时,不要认为他会在圆上运动,他需要做的是每次更新角度。 "a"和"b"只决定了圆的中心。 - arynaq
3个回答

6
基本上,您需要使用正弦和余弦三角函数,它们可以根据角度给出在屏幕上相应的x和y坐标的比率。
double x = a + r * sin(angle);
double y = b + r * cos(angle);

应该能够正常工作。

其中:

r - is the radius of the circle
(a,b) - is the center of the circle
angle - is the desired angle

当然你需要增加角度,来使你的物体移动。

6

从数学上讲,圆上的一个点由角度theta和到中心的距离radius定义。在你的代码中,角度是一个常数100,所以它永远不会在圆上移动。你想要做的是在更新中增加角度。

theta = theta + Math.toRadians(10);
x = a + r*Math.cos(theta);
y = b + r*Math.sin(theta);

这将让你沿着以圆心(a,b)为中心,半径为r的圆形移动,每次移动10度

在你的评论中,添加一个theta字段,并且不要在onDraw中设置它为45。如果想要从45度开始,可以在构造函数中初始化它为45。

int x,y; 
to
int x,y, theta;

针对您的评论

int x,y, theta;

public DrawingTheBall(Context context) {
    super(context);
    bball = BitmapFactory.decodeResource(getResources(), R.drawable.blueball);
    x = 0;
    y = 0;
    theta = 45;
}

并且

public void onDraw(Canvas canvas){
super.onDraw(canvas);

Rect ourRect = new Rect();
ourRect.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
float a = 10;
float b = 10;
float r = 20;
//    double theta = 0;  //You are using a local variable that shadows the field, it starts at 0 everytime
 //   theta = Math.toRadians(45); //You are setting it to 45 degrees everytime, instead:
    theta = theta + Math.toRadians(10); //Increase of 10 degrees

Paint blue = new Paint();
blue.setColor(Color.BLUE);
blue.setStyle(Paint.Style.FILL);

canvas.drawRect(ourRect, blue);

if(x < canvas.getWidth()){
    //x += 10;
    x = (int) (a +r*Math.cos(theta));
}else{
    x = 0;
}
if(y < canvas.getHeight()){
    //y += 10;
    y = (int) (b +r*Math.sin(theta));
}else{
    y = 0;
}
Paint p = new Paint();
canvas.drawBitmap(bball, x, y, p);
invalidate();
}

你可能想将theta声明为theta = Math.toRadians(45); 另外,你每次都使用55度(变量在每次调用onDraw时都被声明并设置为相同的值),所以你应该将它设置为一个字段。 - arynaq
我在哪里使用了55?我切换到theta = Math.toRadians(45),但它仍然静止不动。同时,将theta设置为onDraw的字段只会使球不出现。 - David

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接