Skip to content

Instantly share code, notes, and snippets.

@IdahoEv
Last active August 29, 2015 14:12
Show Gist options
  • Select an option

  • Save IdahoEv/6f50c5d3499dd8d70320 to your computer and use it in GitHub Desktop.

Select an option

Save IdahoEv/6f50c5d3499dd8d70320 to your computer and use it in GitHub Desktop.
find_hits/2 is always returning an empty list
defmodule Collider.Detector do
def collision?({ :circle, c1}, { :circle, c2 }) do
maxdist = c1.radius + c2.radius
dx = c1.position.x - c2.position.x
dy = c1.position.y - c2.position.y
dist = :math.sqrt( dx * dx + dy * dy )
cond do
dist <= maxdist ->
IO.puts "Found collision between #{inspect(c1.position)} and #{inspect(c2.position)}"
# TODO: return the vector of the collision as the 2nd argument
{ :collision, vector_between(c1, c2) }
true ->
IO.puts "No collision between #{inspect(c1.position)} and #{inspect(c2.position)}"
:no_collision
end
end
def vector_between(c1, c1) do
%{ x: c1.position.x - c2.position.x,
y: c1.position.y - c2.position.y }
end
end
Code.require_file "../../test_helper.exs", __ENV__.file
defmodule ColliderDetectorFacts do
use Amrita.Sweet
alias Collider.Detector
defmodule Fixture do
def circle(x, y, radius) do
{ :circle, %{ position: %{ x: x, y: y}, radius: radius } }
end
end
facts "circle to circle collision" do
fact "Can detect collisions in the SE quadrant" do
c1 = Fixture.circle(1.0,1.0,0.5)
Detector.collision?(c1, Fixture.circle(0.5,0.5,0.5)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(1.5,1.5,0.5)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(0.5,1.5,0.5)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(1.5,0.5,0.5)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(1.0,1.0,0.25)) |> { :collision, _ }
end
fact "Can detect misses in the SE quadrant " do
c1 = Fixture.circle(1.0,1.0,0.5)
Detector.collision?(c1, Fixture.circle(2.0,2.0,0.5)) |> :no_collision
Detector.collision?(c1, Fixture.circle(2.0,1.0,0.125)) |> :no_collision
end
fact "Can detect collisions in the NE quadrant" do
c1 = Fixture.circle(2.0,-1.5,0.25)
Detector.collision?(c1, Fixture.circle(2.0,-1.5,0.25)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(1.0,-1.5,1.5)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(2.0,-1.25,0.25)) |> { :collision, _ }
Detector.collision?(c1, Fixture.circle(0.0,0.0,2.5)) |> { :collision, _ }
end
fact "Can detect misses in the NE quadrant " do
c1 = Fixture.circle(2.0,-1.5,0.25)
Detector.collision?(c1, Fixture.circle(2.0,-2.0,0.1)) |> :no_collision
Detector.collision?(c1, Fixture.circle(2.5,-0.5,0.5)) |> :no_collision
end
end
end
defmodule Collider.ListCollider do
# find the intersecting pairs between list_1 and list_2
#
# Each item in the list should be in the form:
# { <thing>, { :circle, %{ position: %{ x: <num>, y: <num>}, radius: <num> } }
def find_hits(list_1, list_2) do
for { item_1, geom_1 } <- list_1,
{ item_2, geom_2 } <- list_2,
vector = hit?(Collider.Detector.collision?(geom_1, geom_1)) do
{ item_1, item_2, vector}
end
end
def hit?(:no_collision), do: nil
def hit?({:collision, vector}), do: vector
end
Code.require_file "../../test_helper.exs", __ENV__.file
defmodule ListColliderFacts do
use Amrita.Sweet
alias Collider.ListCollider
defmodule Fixture do
def circle(x, y, radius) do
{ :circle, %{ position: %{ x: x, y: y}, radius: radius } }
end
end
# Fails. find_hits is always empty []
fact "returns the hits in a 1xN comparison of lists" do
list_1 = [ { '12345', Fixture.circle(0, 0, 0.5 ) }]
list_2 = [ { '00001', Fixture.circle(2, 2, 0.1 ) },
{ '00002', Fixture.circle(0, 0.5, 0.1 ) },
{ '00003', Fixture.circle(0.3, 0.3, 0.1 ) },
{ '00004', Fixture.circle(2, 2, 0.1 ) }
]
ListCollider.find_hits(list_1, list_2) |> [ { '12345', '00002', _},
{ '12345', '00003', _} ]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment