mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-24 08:08:15 -05:00
Update ellipse.coffee
An improved (and untested) implementation for containsPoint
This commit is contained in:
parent
63b24b9bf1
commit
9a85db4a91
1 changed files with 11 additions and 44 deletions
|
@ -50,50 +50,17 @@ class Ellipse
|
||||||
if shape.isEllipse then @distanceSquaredToEllipse shape else @distanceSquaredToRectangle shape
|
if shape.isEllipse then @distanceSquaredToEllipse shape else @distanceSquaredToRectangle shape
|
||||||
|
|
||||||
containsPoint: (p, withRotation=true) ->
|
containsPoint: (p, withRotation=true) ->
|
||||||
[a, b] = [@width / 2, @height / 2]
|
# "ellipse space" is the cartesian space
|
||||||
[h, k] = [@x, @y]
|
# where the ellipse becomes the unit
|
||||||
[x, y] = [p.x, p.y]
|
# circle centered at (0, 0)
|
||||||
x2 = Math.pow(x, 2)
|
[x, y] = [p.x - @x, p.y - @y] # translate point into ellipse space
|
||||||
a2 = Math.pow(a, 2)
|
if withRotation and @rotation # optionally rotate point into ellipse space
|
||||||
a4 = Math.pow(a, 4)
|
c = Math.cos(@rotation)
|
||||||
b2 = Math.pow(b, 2)
|
s = Math.sin(@rotation)
|
||||||
b4 = Math.pow(b, 4)
|
[x, y] = [x*c + y*s, y*c + x*s]
|
||||||
h2 = Math.pow(h, 2)
|
x = x / @width # scale point into ellipse space
|
||||||
k2 = Math.pow(k, 2)
|
y = y / @height
|
||||||
if withRotation and @rotation
|
x*x + y*y <= 1 #if the resulting point falls on/in the unit circle at 0, 0
|
||||||
sint = Math.sin(@rotation)
|
|
||||||
sin2t = Math.sin(2 * @rotation)
|
|
||||||
cost = Math.cos(@rotation)
|
|
||||||
cos2t = Math.cos(2 * @rotation)
|
|
||||||
numeratorLeft = (-a2 * h * sin2t) + (a2 * k * cos2t) + (a2 * k) + (a2 * x * sin2t)
|
|
||||||
numeratorMiddle = Math.SQRT2 * Math.sqrt((a4 * b2 * cos2t) + (a4 * b2) - (a2 * b4 * cos2t) + (a2 * b4) - (2 * a2 * b2 * h2) + (4 * a2 * b2 * h * x) - (2 * a2 * b2 * x2))
|
|
||||||
numeratorRight = (b2 * h * sin2t) - (b2 * k * cos2t) + (b2 * k) - (b2 * x * sin2t)
|
|
||||||
denominator = (a2 * cos2t) + a2 - (b2 * cos2t) + b2
|
|
||||||
solution1 = (numeratorLeft - numeratorMiddle + numeratorRight) / denominator
|
|
||||||
solution2 = (numeratorLeft + numeratorMiddle + numeratorRight) / denominator
|
|
||||||
if (not isNaN solution1) and (not isNaN solution2)
|
|
||||||
[bigSolution, littleSolution] = if solution1 > solution2 then [solution1, solution2] else [solution2, solution1]
|
|
||||||
if y > littleSolution and y < bigSolution
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
numeratorLeft = a2 * k
|
|
||||||
numeratorRight = Math.sqrt((a4 * b2) - (a2 * b2 * h2) + (2 * a2 * b2 * h * x) - (a2 * b2 * x2))
|
|
||||||
denominator = a2
|
|
||||||
solution1 = (numeratorLeft + numeratorRight) / denominator
|
|
||||||
solution2 = (numeratorLeft - numeratorRight) / denominator
|
|
||||||
if (not isNaN solution1) and (not isNaN solution2)
|
|
||||||
[bigSolution, littleSolution] = if solution1 > solution2 then [solution1, solution2] else [solution2, solution1]
|
|
||||||
if y > littleSolution and y < bigSolution
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
false
|
|
||||||
|
|
||||||
intersectsLineSegment: (p1, p2) ->
|
intersectsLineSegment: (p1, p2) ->
|
||||||
[px1, py1, px2, py2] = [p1.x, p1.y, p2.x, p2.y]
|
[px1, py1, px2, py2] = [p1.x, p1.y, p2.x, p2.y]
|
||||||
|
|
Loading…
Reference in a new issue