椭圆与直线的交点

Intersection points of oval and line

用这个函数画了一个"Circle",我真的想出了一个椭圆形的东西。这是因为我正在使用的格式错误的像素除了使此功能成为必需之外并没有真正相关。

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

现在,我正在制作一款涉及行星(ei 圆圈)的游戏,但由于限制,我只能 运行 以 10 FPS 的速度进行游戏。我最终在游戏中获得如此大的加速度,以至于飞船每十分之一秒的移动速度比 "circle" 的直径还快,所以我正在寻找一种简单(希望是快速)的方法来计算是否当飞船在 A 点和 B 点之间神奇地传送时,它将撞击地球。

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

我用谷歌搜索了一下,但没有找到任何我能理解的东西。我在学习 11 年级的数学,只是求解方程组,尽管我也在工程学 类,在那里我学习了力向量。

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

你有两个等式:

(1) 圆圈:

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

('k' 挤压图表以实现椭圆形。在您的情况下,k = 2/3。有一个站点 "Purple Math",其中有一章是关于 "Transformations" 的。请阅读它。 )

(2) 行:

a*x + b*y = c

现在,您会注意到,为简单起见,我假设圆心位于原点。在你的情况下通常不是,所以你只需移动线的起点和终点以匹配它。 (对象在哪里并不重要:重要的只是它们彼此之间的关系。所以我们可以将对象作为一个组 up/down right/left 随心所欲地移动。)

所以我们有两个等式。 "Solving them" = "finding the points where they touch" = "collision"。所以我们需要解决它们。要解决这些问题,您可以从等式 (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

这是一个二次公式。

现在,您要问椭圆和直线是否相交 ("calculate if the ship will hit the planet")。换句话说,您是在问这个方程式是否有解(您是 而不是 自己求解)。如果判别式 greater/equal 为零,则有一个解决方案。判别式为 "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,所以你把它们放在那个表达式中,如果它 greater/equal 为零,你就知道有碰撞。

如果你不明白我的解释,安装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