简体   繁体   English

椭圆和直线的交点

[英]Intersection points of oval and line

Using this function to draw a "Circle", I really come up with something of an oval. 使用这个功能画一个“圆”,我真的想出了一个椭圆形的东西。 This is because of malformed pixels I am working with that aren't really relevant other than they make this function necessary. 这是因为我正在使用的畸形像素与它们无关,除了它们使此功能必要之外,这些像素并没有其他意义。

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

Now, I'm making a game that involves planets (ei the circle), but because of limitations I can only run it at 10 FPS. 现在,我正在制作一个涉及行星(即圆圈)的游戏,但是由于限制,我只能以10 FPS的速度运行它。 I end up with so much acceleration in the game that the ship can move faster per 10th of a second than the diameter of the "circle", so I'm looking for a simple (and hopefully fast) way to calculate if the ship will hit the planet when it magically teleports between point A and point B. 我在游戏中最终获得了如此大的加速度,以至于飞船每10秒就可以移动一次,而不是“圆”的直径。因此,我正在寻找一种简单(希望更快)的方法来计算飞船是否会当它神奇地在A点和B点之间传送时,撞击了行星。

As an example, lets say I have my ship at 75, 100 and it's momentum will move it +80, -50. 举例来说,假设我的飞船在75,100,其动量会将其移动+80,-50。 It'll end up at 155, 50. Between those two points is my planet, but how do I detect it? 最终将以155、50结束。在这两点之间是我的星球,但是我如何检测到它呢?

I've googled a bit, but didn't come up with anything I could comprehend. 我已经用谷歌搜索了一下,但是没有提出我能理解的任何东西。 I'm in 11th grade math, just solving systems of equations, although I'm also in engineering classes, where I learned force vectors. 我上11年级的数学,只是求解方程组,尽管我也在工程课上学习力矢量。

If it helps, the planet doesn't move. 如果有帮助,行星就不会移动。

You have two equations: 您有两个方程式:

(1) The circle: (1)圆圈:

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

(The 'k' squeezes the graph to achieve an oval. In your case k = 2/3. There's a site "Purple Math" with a chapter on "Transformations". Read it.) (“ k”将图压缩成椭圆形。在您的情况下,k = 2/3。有一个“ Purple Math”站点,其中有一章“ Transformations”。请阅读。)

(2) The line: (2)行:

a*x + b*y = c

Now, you'll notice that, for simplicity, I assumed the circle's center is at the origin. 现在,您会注意到,为简单起见,我假设圆的中心位于原点。 In your case it usually isn't, so you'll simply shift the line's start and end points to match it. 在您的情况下,通常情况并非如此,因此您只需移动线的起点和终点以使其匹配即可。 (It doesn't matter where objects are: it only matters where they're in relation to each other. So we're allowed to move objects as a group up/down right/left however we want.) (对象的位置无关紧要;仅在它们彼此之间的相对位置上很重要。因此,我们可以根据需要将对象作为一个组上下左右移动。)

So we have two equations. 因此,我们有两个方程。 "Solving them" = "finding the points where they touch" = "collision". “解决它们” =“找到它们接触的点” =“碰撞”。 So we need to solve them. 因此,我们需要解决它们。 To solve them you find y from equation (2) and replace it in equation (1). 为了求解它们,您可以从等式(2)中找到y并将其替换为等式(1)。 You get an equation with only x (and x^2): 您得到的方程式只有x(和x ^ 2):

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

You arrange ("factor") this equation on x: 您在x上排列(“因子”)此等式:

x^2(b^2 k^2 + a^2) + x(-2ac) + c^2 - r^2 b^2 = 0

That's a quadratic formula. 那是一个二次方程式。

Now, you're asking whether the oval and line intersect ("calculate if the ship will hit the planet"). 现在,您要问椭圆形和直线是否相交(“计算飞船是否会撞上行星”)。 In other words, you're asking whether there's any solution to this equation (you're not asking for the solutions themselves). 换句话说,您要问的是这个方程式是否有任何解决方案(您自己并不是在寻求解决方案)。 There's a solution if the discriminant is greater/equal to zero. 如果判别式大于/等于零,则有解决方案。 The discriminant is "B^2 - 4AC", where: 判别式为“ B ^ 2-4AC”,其中:

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

So "B^2 - 4AC" is: 因此,“ B ^ 2-4AC”为:

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

That's all! 就这样!

It's a simple expression. 这是一个简单的表达。

You know b,a,r,k,c, so you put them in that expression and if it's greater/equal to zero you know there's a collision. 您知道b,a,r,k,c,因此将它们放在该表达式中,如果它大于/等于零,则说明存在冲突。

If you don't understand my explanation, install GeoGebra, then type into it: 如果您不理解我的解释,请安装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²

Now, make k/r/a/b/c sliders and change their values with your mouse. 现在,制作k / r / a / b / c滑块并用鼠标更改其值。 You'll notice that when there's a collision, "dis" (the discriminant) is negative. 您会注意到,发生碰撞时,“ dis”(判别式)为负。

Finally, what you've left to do: 最后,您要做的是:

You need to write a function that gets the circle and line and tells if there's a collision: 您需要编写一个获取圆和线并判断是否存在碰撞的函数:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM