【问题标题】:Calculate points around a circle in android在android中计算一个圆圈周围的点
【发布时间】:2013-12-31 12:55:27
【问题描述】:

我正在用 android 编写一个游戏,其中一艘敌舰需要在其周围以星形图案开火。基本上,对于我让敌舰开火的任何 X 次射击,我希望它围绕自身 360 度除以射击次数,并以完全等边的角度射击。因此,将发射 3 枪,第一枪在 360 度,第二枪在 120 度,第三枪在 240 度。 4 个镜头将是 360,90,180,270 等等。然后每个镜头将沿对角线向外移动,直到它碰到屏幕边缘(或途中的其他东西)。到现在为止还挺好。这是我的代码 - 我显然做错了什么,因为虽然四枪会在四个相等的方向(北,南,东和西)发射,但 3 枪或 6 枪或 8 枪(等等)会朝错误的方向发射.只是角度不对。我很感激这方面的任何帮助,因为我已经为此苦苦挣扎了很长一段时间。在下面的示例中,iShotNumber 是齐射中的射击次数。距离是镜头在一个“滴答”内行进的距离(以像素为单位)。镜头以阵列的形式围绕船的圆周添加,然后通过每个“滴答”运行以将镜头向前推进一步。

围绕船的圆周绘制镜头的逻辑:

public void addShot(Context ctx, int iShotNumber, float distance) {



for (int iShot=1; iShot<=iShotNumber; iShot++) {

double 
        dAngle =0, //angle of the shot
        dCosFactor=0, //factor on the x-axis
        dSinFactor=0; //factor on the y-axis

        float 
        fNewX = 0, //new position on the x-axis
        fNewY =0; //new position on the y-axis

        dAngle = 360/iShotNumber;
        dAngle = dAngle*iShot;

        if (iShotNumber == 1) {dAngle=180;} //if there's only one shot then fire straight down

        if (dAngle!=360 && dAngle!=180) //if its 360 or 180 then fire straight up or straight down - no need for X
        {
            fNewX = (float) (getShipRadius()*Math.cos(Math.toRadians(dAngle)));

            if (dAngle<=180) {fNewX=fNewX+distance;} else {fNewX=fNewX-distance;}

            fNewX=fNewX+getXLocation();

        }
        else {fNewX=getXLocation();}        

        if (dAngle!=90 && dAngle !=270) //if its 90 or 270 then fire straight right or straight left - no need for Y
        {
            fNewY = (float) (getShipRadius()*Math.sin(Math.toRadians(dAngle)));

            if (dAngle<=90||dAngle>=270) {fNewY=fNewY+distance;} else {fNewY=fNewY-distance;}

            fNewY=fNewY+getYLocation();
        }
        else {fNewY=getYLocation();}


        if (dAngle>=90&&dAngle<=180) {dSinFactor = Math.sin(Math.toRadians(dAngle)-90); dCosFactor = Math.cos(Math.toRadians(dAngle)-90);}
        else if (dAngle>=181&&dAngle<=270) {dSinFactor = Math.sin(Math.toRadians(dAngle)-180); dCosFactor = Math.cos(Math.toRadians(dAngle)-180);}
        else if (dAngle>=271&&dAngle<360) {dSinFactor = Math.sin(Math.toRadians(dAngle)-270); dCosFactor = Math.cos(Math.toRadians(dAngle)-270);}
        else if (dAngle==360) {dSinFactor = Math.sin(Math.toRadians(dAngle)-271); dCosFactor = Math.cos(Math.toRadians(dAngle)-271);}
        else {dSinFactor = Math.sin(Math.toRadians(dAngle)); dCosFactor = Math.cos(Math.toRadians(dAngle));}

        //dSinFactor = Math.sin(Math.toRadians(dAngle)); dCosFactor = Math.cos(Math.toRadians(dAngle));

        //if (dSinFactor<=0){dSinFactor = dSinFactor*-1;} //neutralize negative angles on upshots
        //if (dCosFactor<=0){dCosFactor = dCosFactor*-1;} //neutralize negative angles on rightshots

        if ( MainActivity.iDebugLevel >= 1) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) 
                + " with dAngle " +String.valueOf(dAngle) +" cosan was " +String.valueOf(dCosFactor) +" sinan was " +String.valueOf(dSinFactor));}
        if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with fNewX " +String.valueOf(fNewX));}
        if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with fNewY " +String.valueOf(fNewY));}

        if (dAngle==90||dAngle==270) {newShot = new ShotClass(ctx, fNewX, fNewY, dCosFactor /*x-angle*/, 0 /*y-angle*/);} //fire straight to the right or left
        else if (dAngle==360||dAngle==180) {newShot = new ShotClass(ctx, fNewX, fNewY, 0 /*x-angle*/, dSinFactor /*y-angle*/);} //fire straight up or down
        else {newShot = new ShotClass(ctx, fNewX, fNewY, dCosFactor /*x-angle*/, dSinFactor /*y-angle*/);} //fire at an angle

        if ( dAngle <= 90 || dAngle >= 270) {
            newShot.setShotGoingUp(true);
        }
        else
        {
            newShot.setShotGoingUp(false);
        }

        if ( dAngle <= 180 ) {
            newShot.setShotGoingRight(true);
        }
        else
        {
            newShot.setShotGoingRight(false);
        }

        if ( MainActivity.iDebugLevel >= 1) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with goingup " +String.valueOf(newShot.getShotGoingUp()) +" with goingright " +String.valueOf(newShot.getShotGoingRight()));}

        arShots.add(newShot);
        if ( MainActivity.iDebugLevel >= 2) {Log.d("EnemyShip-addShot","add shot number " +String.valueOf(iShot) + " with position " +String.valueOf(getXLocation()) +" " +String.valueOf(getYLocation()) +" firing params: " +String.valueOf(dCosFactor) +" " +String.valueOf(dSinFactor) +" angle was " +String.valueOf(dAngle));}
    }

对角线投篮的逻辑:

        inpDistance = inpDistance * .2f; //slow down the shot to one fifth speed

        for (int iShotInTheSequence=1;iShotInTheSequence<=inpNumberShots;iShotInTheSequence++) {

            fFactor = (float) (inpDistance * getYFiringAngle());
            if ( getShotGoingUp() ) { //shot is going up

                fYLocation = fYLocation - fFactor;
            } //shot is going up
            else {//shot is going down

                fYLocation = fYLocation + fFactor; 
            } //shot is going down

            fFactor = (float) (inpDistance * getXFiringAngle());
            if ( getShotGoingRight() ) { //shot is going right
                fXLocation = fXLocation + fFactor;
            } //shot is going right
            else {//shot is going left
                fXLocation = fXLocation - fFactor;
            } //shot is going left


        }

【问题讨论】:

  • 在堆栈交换数学中发布这个,您可能会得到与数学计算相关的更好的解决方案
  • 当你大量编辑原始问题的代码时,你应该总是写一个评论。 @Joni 的解决方案是否解决了您的问题?
  • 哦,对不起 - 我在编辑屏幕上写了一条评论(不知道它没有出现在任何地方)。他添加的内容确实帮助了我,但镜头仍然没有出现在船周围的正确位置

标签: java android space trigonometry


【解决方案1】:

大多数编程语言(包括 Java)中的三角函数以弧度而不是度数来测量参数。有一个辅助函数可以进行转换,所以无论你在哪里调用sincos,你都可以添加对toRadians 的调用:

Math.cos(Math.toRadians(dAngle))

【讨论】:

  • 在我发布答案@HAL9000 后,OP 似乎已将其添加为编辑。不过他们没有修改问题的措辞,所以很难知道这是否解决了问题,或者他们是否仍然有问题。
  • 对不起,我没想到有人会在没有评论的情况下对问题做出如此大的改变。
【解决方案2】:

第一个错误:

dAngle = 360/iShotNumber;

你想要一个双精度作为除法的结果,那么你不能简单地做一个整数除法。你应该这样做:

dAngle = 360.0/(double)iShotNumber;

我正在检查以查找其他错误。

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    相关资源
    最近更新 更多