2016-04-16 88 views
1

我正在製作一個簡單的遊戲,其中我有一個圍繞中心旋轉的球和圓弧。當用戶觸摸屏幕時,球沿指針方向移動並擊中弧線。但我無法找到任何方法來檢測碰撞 的圖像已經附加了更好的理解用圓弧碰撞檢測球

Game Image 遊戲圖像

Debug File

調試快照..

我有一個圈圍繞我的球... 我在做什麼是

檢測圓弧>旋轉的圓心與圓的交點。 但是我無法檢測到球是否與球相交? 請幫助...:'(

代碼使電弧:

public void arc (float x, float y, float radius, float start, float degrees,int segments) { 
    // int segments = (int)(6 * (float)Math.cbrt(radius) * (degrees/360.0f)); 

    if (segments <= 0) throw new IllegalArgumentException("segments must be > 0."); 
    float colorBits = color.toFloatBits(); 
    float theta = (2 * MathUtils.PI * (degrees/360.0f))/segments; 
    float cos = MathUtils.cos(theta); 
    float sin = MathUtils.sin(theta); 
    float cx = radius * MathUtils.cos(start * MathUtils.degreesToRadians); 
    float cy = radius * MathUtils.sin(start * MathUtils.degreesToRadians); 

    for (int i = 0; i < segments; i++) { 
     renderer.color(colorBits); 
     Gdx.gl20.glLineWidth(10); 
     Gdx.gl.glEnable(GL20.GL_BLEND); 
     renderer.vertex(x + cx, y + cy, 0); 
     float temp = cx; 
     cx = cos * cx - sin * cy; 
     cy = sin * temp + cos * cy; 
     renderer.color(colorBits); 
     renderer.vertex(x + cx, y + cy, 0); 
    } 
} 
+0

如何定義你的弧?您可以比較交叉角度是否在弧線範圍內。 – MBo

回答

3

什麼是弧?簡單地說:兩個圓的區別,限制在兩個向量(或三角形)內。

圖表可能有幫助;

Diagram

較大紅圓的半徑等於圓弧的外半徑。較小的藍色圓圈的半徑等於圓弧的內部半徑減去球的直徑。三角形顯示弧的邊緣。

從這裏,只需測試球[從中心]與球的半徑的歐氏距離,然後找到從原點到球的兩個切線,看看它們中的任何一個是否通過角度測量的弧線。

編輯:實現我需要在我自己的項目中這樣的事情,所以我決定寫出來;

double ball_radius = //Your radius of the ball 

    //the start and end angles of the arc 
    double start = //i.e -PI/4; 
    double end = //i.e PI/4; 

    double innerRadius = //inner radius of arc 
    double outerRadius = innerRadius + [width of lines, 10 in your code] 

    /* Now all the fun mathsy stuff */ 

    boolean collides = false; 

    double dx = bx - cx; //[bx, by] = ball coords 
    double dy = by - cy; //[cx, cy] = center coords 

    //get distance and direction to ball from center 
    double dist = Math.sqrt(dx * dx + dy * dy); 
    double dir = Math.atan2(dy, dx); 

    //angles for tangents to ball from center 
    double tangent_angle = Math.asin(ball_radius/ dist); 
    double dir0 = dir + tangent_angle; 
    double dir1 = dir - tangent_angle; 

    //check if distance is good 
    if (dist + ball_radius> innerRadius && dist - ball_radius < outerRadius) 
    { 
     //check edges of ball against start and end of arc 
     boolean d = dir > start && dir < end; 
     boolean d0 = dir0 > start && dir0 < end; 
     boolean d1 = dir1 > start && dir1 < end; 

     //if both tangents are inside the angular measure 
     if (d || d0 && d1) 
     { 
      collides = true; 
     } 
     //otherwise if one tangent is inside 
     //We need to test the outside corners more precisely 
     else if (d0 != d1) 
     { 
       double x0 = cx + outerRadius * Math.cos(start) - bx; 
       double y0 = cy + outerRadius * Math.sin(start) - by; 

       double x1 = cx + outerRadius * Math.cos(end) - bx; 
       double y1 = cy + outerRadius * Math.sin(end) - by; 

       /** And so on for the other 2 corners */ 
       /** If the arc is very thick, you will need to test against 
        the actual line segments at the ends of the arc */ 

       if (x0 * x0 + y0 * y0 < ball_radius * ball_radius 
        || x1 * x1 + y1 * y1 < ball_radius * ball_radius) 
        collides = true; 

     } 
    } 

如果球只有永遠會打弧內,或不精確的3-4像素是好的擊球弧線的邊角時,那麼你就可以在更換整個如果條件上面的代碼,這是更高效的方式(但很容易在角落混亂);

if (dist > innerRadius - ball_radius && dist + ball_radius < outerRadius) 
{ 
    //if any tangent falls within the arc 
    collides = ((dir0 > start && dir0 < end) || (dir1 > start && dir1 < end)); 
} 

最終結果:

End Result

+0

愛你的迴應....謝謝噸....它給了我另一種方法,我讀了這個東西的地方,但不知道它是如何從我腦海中跳過...非常感謝.. :) – Ashwani

+0

什麼是在這種情況下'半徑'? – Ashwani

+0

啊,我的不好,所有的'半徑'都和'ball_radius'一樣。我將代碼粘貼到答案中時修改了代碼,看起來有些事情搞砸了。編輯並修復。 – KookieMonster

0

如果有可能爲你找到它彌補了弧段,那麼你可以使用Intersector類我不知道你是如何製作弧線的,所以我不知道你是否可以得到弧段。

2

arc(float x,float y ,浮動半徑,浮動開始,浮動度

似乎x,y爲圓心,start開始角度,degrees是後掠角,因此最終角end = start + degrees

如果您交點ix, iy,那麼你可以檢查這些跨產品的跡象:

cp_1 = (ix-x)*sin(start)-(iy-y)*Cos(start) 
cp_2 = (ix-x)*sin(end)-(iy-y)*Cos(end) 

如果CP1具有負號和CP2是正的(對於正方向弧度),然後(ix,iy)交點之間(start,end)電弧結束。 (工程Abs(degrees) < Pi=180

Delphi實例爲-15〜30度產生電弧,並檢查從光線到cx,cy一些點是否相交,此弧:

function IsPointInArcLimits(cx, cy, ix, iy, StartAngle, Deg: Double): Boolean; 
    var 
    EndAngle, cp_1, cp_2: Double; 
    begin 
    EndAngle := DegToRad(StartAngle + Deg); 
    StartAngle := degToRad(StartAngle); 
    cp_1 := (ix - cx) * Sin(StartAngle) - (iy - cy) * Cos(StartAngle); 
    cp_2 := (ix - cx) * Sin(EndAngle) - (iy - cy) * Cos(EndAngle); 
    Result := (cp_1 <= 0) and (cp_2 >= 0); 
    end; 

var 
    cx, cy, ix, iy, StartAngle, Degrees: Integer; 
begin 
    cx := 0; 
    cy := 0; 
    ix := 10; 
    StartAngle := -15; 
    Degrees := 45; 
    for iy := -5 to 7 do 
    if IsPointInArcLimits(cx, cy, ix, iy, StartAngle, Degrees) then 
     Memo1.Lines.Add(Format('Yes y=%d an=%f arc %d+%d', 
     [iy, RadToDeg(ArcTan(iy/ix)), StartAngle, Degrees])) 
    else 
     Memo1.Lines.Add(Format('No y=%d an=%f arc %d+%d', 
     [iy, RadToDeg(ArcTan(iy/ix)), StartAngle, Degrees])); 

輸出:

No y=-5 an=-26.57 arc -15+45 
No y=-4 an=-21.80 arc -15+45 
No y=-3 an=-16.70 arc -15+45 
Yes y=-2 an=-11.31 arc -15+45 
Yes y=-1 an=-5.71 arc -15+45 
Yes y=0 an=0.00 arc -15+45 
Yes y=1 an=5.71 arc -15+45 
Yes y=2 an=11.31 arc -15+45 
Yes y=3 an=16.70 arc -15+45 
Yes y=4 an=21.80 arc -15+45 
Yes y=5 an=26.57 arc -15+45 
No y=6 an=30.96 arc -15+45 
No y=7 an=34.99 arc -15+45 
+0

我會試一試,肯定會upvote你的答案,如果它解決了我的問題..謝謝 – Ashwani

+0

沒有...它不工作... :( – Ashwani

+0

Abs(度) Ashwani