【问题标题】:Intersection points of oval and line椭圆与直线的交点
【发布时间】:2015-01-21 01:41:01
【问题描述】:

用这个函数画一个“圆”,我真的想出了一个椭圆的东西。这是因为我正在使用的格式错误的像素除了使此功能变得必要之外,它们并不真正相关。

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 的速度运行它。我最终在游戏中获得了如此大的加速度,以至于船每 10 秒的移动速度比“圆”的直径更快,所以我正在寻找一种简单(希望是快速)的方法来计算船是否会当它神奇地在 A 点和 B 点之间传送时击中地球。

例如,假设我的船在 75、100,它的动量会使它移动 +80、-50。它最终会是 155、50。在这两点之间是我的星球,但我如何检测它呢?

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

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

【问题讨论】:

    标签: math lua collision-detection intersection


    【解决方案1】:

    你有两个方程:

    (1) 圆圈:

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

    (“k”挤压图形以形成椭圆形。在您的情况下,k = 2/3。有一个网站“Purple Math”,其中有一章是关于“转换”的。阅读它。)

    (2) 行:

    a*x + b*y = c
    

    现在,您会注意到,为简单起见,我假设圆的中心位于原点。在您的情况下,它通常不是,因此您只需移动线的起点和终点以匹配它。 (对象在哪里并不重要:重要的是它们相互关联的位置。因此,我们可以根据需要将对象作为一个组向上/向下向右/向左移动。)

    所以我们有两个方程。 “解决它们”=“找到它们接触的点”=“碰撞”。所以我们需要解决它们。为了解决它们,您从等式(2)中找到 y 并将其替换为等式(1)。你得到一个只有 x(和 x^2)的方程:

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

    你在 x 上排列(“因子”)这个方程:

    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
    

    【讨论】:

    • 谢谢!这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-12
    • 1970-01-01
    相关资源
    最近更新 更多