2013-07-30 28 views
0

我想實現一個數學過程來確保一個圓c1完全在另一個圓c2內。函數在圓內循環修正?

它應該工作方式如下:

鑑於C1(X,Y,R)和C2(X,Y,R)和c2.r> c1.r

  • 返回真,如果c1在c2內
  • 返回向量V(x,y)是應用於c1的最小修正,因此它位於c2內。

它看起來如何?對於數學家或物理學家來說應該很容易,但對我來說很難。

我已經在lua嘗試了一個實現,但是肯定有錯誤。

local function newVector(P1, P2) 
    local w, h=(P2.x-P1.x), (P2.y-P1.y) 
    local M=math.sqrt(w^2 + h^2) 
    local alpha=math.atan(h/w) 
    return {m=M, alpha=alpha} 
end 

local function isWithin(C1, C2) 
    local V12=newVector(C1, C2) 
    local R12=C2.r-C1.r 
    local deltaR=R12-V12.m 
    if deltaR>=0 then 
     return true 
    else 
     local correctionM=(V12.m+deltaR) --module value to correct 
     local a=V12.alpha 
     print("correction angle: "..math.deg(a)) 
     local correctionX=correctionM*math.cos(a) 
     local correctionY=correctionM*math.sin(a) 
     return {x=correctionX, y=correctionY} 
    end 
end 

謝謝!

+1

你應該使用'math.atan2'。 – lhf

+0

你的意思是什麼樣的修正?翻譯中心?半徑比例?都? – lhf

+0

我的意思是圓1的平移,以便將返回的向量V(x,y)添加到C1使得C1位於C2內部。例如,如果C1在C2右邊2px和下邊1px之外,返回值應該是{x = -2,y = -1} – nest

回答

1

檢查距離(中心1,中心2)+半徑1 < =半徑2還不夠嗎?

local function isWithin(C1, C2) 
    local distance = math.sqrt((C1.x-C2.x)^2+(C1.y-C2.y)^2) 
    return distance + C1.r <= C2.r + Epsilon 

Epsilon用於避免數值錯誤。 (例如Epsilon = 1e-9)

聽起來很容易。

+1

什麼是'Epsilon'? – lhf

+0

對於數字錯誤。在回覆中添加了它。 – David

+0

@大衛是的,這應該夠了。畢竟,圓是一個非常簡單的(數學)形狀。然而,修正向量稍微複雜一些。不過多 – dualed

0

好吧,最後我工作得很好。

關鍵是使用math.atan2作爲lhf建議。我在修正值中有一些數字錯誤。

下面是最終的代碼。我還包含了用於從任何電暈顯示對象創建圓的circleFromBounds函數。

local function newVector(P1, P2) 
    local w, h=(P2.x-P1.x), (P2.y-P1.y) 
    local M=math.sqrt(w^2 + h^2) 
    local alpha=math.atan2(h, w) 
    return {m=M, alpha=alpha} 
end 

local function isWithin(C1, C2) 
    local V12=newVector(C1, C2) 
    local epsilon = 10^(-9) 
    if (V12.m + C1.r <= C2.r + epsilon) then 
     return true 
    else 
     local correctionM=(C2.r-(C1.r+V12.m)) --module value to correct 
     local A=V12.alpha 
     local correctionX=correctionM*math.cos(A) 
     local correctionY=correctionM*math.sin(A) 
     return {x=correctionX, y=correctionY} 
    end 
end 

local function circleFromBounds(bounds, type) 
    local x, y, r 
    local width, height = (bounds.xMax-bounds.xMin), (bounds.yMax-bounds.yMin) 
    local ratio=width/height 

    x=bounds.xMin+width*.5 
    y=bounds.yMin+height*.5 

    if "inner"==type then 
     if ratio>1 then 
      r=height*.5 
     else 
      r=width*.5 
     end 
    elseif "outer"==type then 
     local c1, c2 = width*.5, height*.5 
     r = math.sqrt(c1^2 + c2^2) 
    end 

    return {x=x, y=y, r=r} 
end 

感謝您的幫助!