椭圆和直线的交点

时间:2015-01-21 01:41:01

标签: math lua collision-detection intersection

使用此功能绘制“圆圈”,我真的想出了一个椭圆形的东西。这是因为我正在使用的格式错误的像素除了使这个功能成为必要之外并不是真正相关的。

local function drawCircle( centerX, centerY, radius, col, solid )
  solid = solid or false
  local isAdvanced = term.isColor and term.isColor()
  local char = isAdvanced and " " or "|"
  if isAdvanced then term.setBackgroundColor( col ) end
  local radStep = 1/(1.5*radius)
  for angle = 1, math.pi+radStep, radStep do
    local pX = math.cos( angle ) * radius * 1.5
    local pY = math.sin( angle ) * radius
    if solid then
        local chord = 2*math.abs(pX)
        term.setCursorPos( centerX - chord/2, centerY - pY )
        write( char:rep( chord ) )
        term.setCursorPos( centerX - chord/2, centerY + pY )
        write( char:rep( chord ) )
    else
        for i=-1,1,2 do
            for j=-1,1,2 do
                term.setCursorPos( centerX + i*pX, centerY + j*pY )
                write( char )
            end
        end
    end
  end
end

现在,我正在制作一个涉及行星(即圆圈)的游戏,但由于局限性,我只能以10 FPS运行它。我最终在游戏中获得了如此多的加速度,以至于船舶每十分之一秒可以比“圆圈”的直径移动得更快,所以我正在寻找一种简单(并且希望很快)的方法来计算船是否会当它在A点和B点之间神奇地传送时击中了这个星球。

举个例子,假设我的船只有75,100,它的动量会将它移动到+ 80,-50。它最终将达到155,50。在这两点之间是我的星球,但我该如何检测它呢?

我用Google搜索了一下,但没有想出任何我能理解的内容。我是11年级的数学,只是求解方程组,虽然我也在工程课上,在那里我学习了力矢量。

如果有帮助,地球就不会移动。

1 个答案:

答案 0 :(得分:2)

你有两个方程式:

(1)圆圈:

(k*x)^2 + y^2 = r^2

(' k'挤压图形以获得椭圆形。在你的情况下k = 2/3。有一个网站"紫色数学"有一章关于& #34;转换"。阅读。)

(2)行:

a*x + b*y = c

现在,您会注意到,为简单起见,我假设圆圈的中心位于原点。在你的情况下,它通常不是,所以你只需移动线的起点和终点来匹配它。 (对象的位置并不重要:它只关注它们彼此之间的关系。因此,我们可以按照我们想要的方式向上/向下向上/向下移动对象。 )

所以我们有两个方程式。 "解决他们" ="找到他们触摸的点#34; ="碰撞"。所以我们需要解决它们。为了解决这些问题,你可以从等式(2)中找到y并将其替换为等式(1)。你得到一个只有x(和x ^ 2)的方程:

.... x ... x^2 .... = ....

你在x:

上安排(" factor")这个等式
x^2(b^2 k^2 + a^2) + x(-2ac) + c^2 - r^2 b^2 = 0

这是一个二次方程式。

现在,你要问的是椭圆和线是否相交("计算船是否会击中行星")。换句话说,您要问的是这个等式是否有任何解决方案(您 > 如果判别式大于/等于零,则存在解决方案。判别式是" B ^ 2 - 4AC",其中:

A = b^2 k^2 + a^2
B = -2ac
C = c^2 - r^2 b^2

所以" B ^ 2 - 4AC"是:

4*b^2*(a^2*r^2+b^2*r^2*k^2-k^2*c^2)

这就是全部!

这是一个简单的表达。

你知道b,a,r,k,c,所以你把它们放在那个表达式中,如果它大于/等于零你知道那里有碰撞。

如果您不理解我的解释,请安装GeoGebra,然后输入:

k = 0.5
r = 1
circ: (k x)² + y² = r²

a = 5
b = -2.5
c = 4
line: a x + b y = c

dis = 4a² b² r² + 4b⁴ k² r² - 4b² c² k²

现在,制作k / r / a / b / c滑块并用鼠标更改它们的值。您会注意到,当发生碰撞时," dis" (判别)是否定的。

最后,你还要做什么:

您需要编写一个获取圆和线的函数,并告知是否存在碰撞:

function do_collide(
    -- the circle:
    centerX, centerY, radius,
    -- the line:
    x1, y1, x2, y2)

  -- Step 1:
  -- You already know r and k.

  -- Step 2:
  -- Shift the coordinates (x1,x2) and (x2,y2) by (centerX, centerY).
  -- Find the line equation and you have a,b,c.

  -- Step 3:
  return 4*b^2*(a^2*r^2+b^2*r^2*k^2-k^2*c^2) >= 0

end