summaryrefslogtreecommitdiffhomepage
path: root/run.rb
diff options
context:
space:
mode:
authortradam <git.tradam.fyi>2021-08-16 11:05:47 -0400
committertradam <git.tradam.fyi>2021-08-16 11:05:47 -0400
commitb4b6817a2a9fce437d83b04eb1bff55bd8c81a90 (patch)
tree71859dac1848800a91067818bd58dd7d79df0dd8 /run.rb
parentd5ccd4ea0d174c733d3fb57f520d261aeccfb8dc (diff)
downloadarbitrary-polygon-collision-b4b6817a2a9fce437d83b04eb1bff55bd8c81a90.tar.gz
arbitrary-polygon-collision-b4b6817a2a9fce437d83b04eb1bff55bd8c81a90.zip
.
Diffstat (limited to 'run.rb')
-rw-r--r--run.rb269
1 files changed, 146 insertions, 123 deletions
diff --git a/run.rb b/run.rb
index 5b56448..cb9329f 100644
--- a/run.rb
+++ b/run.rb
@@ -1,6 +1,19 @@
require 'ruby2d'
require 'ruby2d/camera'
+# SOURCES FOR MATH USED
+# here are the websites I tried to look at, understand, and implement the math from(unsuccessfully)
+#
+# Currently Main Source:
+# http://programmerart.weebly.com/separating-axis-theorem.html
+#
+# Other sources read through:
+# https://dyn4j.org/2010/01/sat/
+# https://www.sevenson.com.au/programming/sat/
+#
+# more stuff near the bottom of this link:
+# https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
+
#DEBUG: used to colour all debug lines unique colours
$colors = ['blue', 'teal', 'green', 'lime',
'yellow', 'orange', 'red', 'fuchsia']
@@ -19,29 +32,60 @@ class DebugLines
end
# The coordinates of the 2 shapes being tested for collision
-sv1 = {x1: 275.0 - 275.0, y1: 175.0 - 175.0,
- x2: 375.0 - 275.0, y2: 225.0 - 175.0,
- x3: 300.0 - 275.0, y3: 350.0 - 175.0,
- x4: 250.0 - 275.0, y4: 250.0 - 175.0}
-
-sv2 = {x1: 200.0, y1: 100.0,
+svA = {x1: 200.0, y1: 100.0,
x2: 200.0, y2: 200.0,
x3: 100.0, y3: 200.0,
x4: 100.0, y4: 100.0}
+svB = {x1: 275.0 - 275.0, y1: 175.0 - 175.0,
+ x2: 375.0 - 275.0, y2: 225.0 - 175.0,
+ x3: 300.0 - 275.0, y3: 350.0 - 175.0,
+ x4: 250.0 - 275.0, y4: 250.0 - 175.0}
+
# The 2 shapes being tested for collision
-s1 = Camera::Quad.new(
- **sv1,
- color: 'aqua',
+
+sA = Camera::Quad.new(
+ **svA,
+ color: 'olive',
z: 10
)
-s2 = Camera::Quad.new(
- **sv2,
- color: 'olive',
+sB = Camera::Quad.new(
+ **svB,
+ color: 'aqua',
z: 10
)
+# The hitbox logic
+def hitbox_check(shape_a, shape_b)
+
+ # Get normals of both shapes
+ inverted = build_inverted_edges(shape_b)
+ inverted.concat(build_inverted_edges(shape_a))
+
+ #DEBUG
+ debug_outer_loop(inverted)
+
+ inverted.each_with_index do |line, line_index|
+
+ # Determine max and min of a and b shapes
+ amax, amin = calculate_minmax(shape_a, line)
+ bmax, bmin = calculate_minmax(shape_b, line)
+
+ #DEBUG
+ debug_inner_loop(shape_a, shape_b, line_index, amax, amin, bmax, bmin)
+
+ if (((amin <= bmax) && (amin >= bmin)) || ((bmin <= amax) && (bmin >= amin)))
+ #next
+ else
+ # The logic should end the calculations early once it detects lack of collision
+ # however for debug purposes this is disabled
+ #return false
+ end
+ end
+ true
+end
+
# Creates edges out using coordinates and then gets the normal
def build_inverted_edges(shape)
edges = []
@@ -52,7 +96,7 @@ def build_inverted_edges(shape)
vertex_end = shape[index + 1]
end
edges.push [vertex_end[1] - vertex_start[1],
- -vertex_end[0] + vertex_start[0]]
+ -(vertex_end[0] - vertex_start[0])]
end
edges
end
@@ -62,108 +106,87 @@ def vecDotProd(a,b)
return (a[0] * b[0]) + (a[1] * b[1])
end
-# The hitbox logic
-def hitbox_check(shape_a, shape_b)
-
- # Get normals of both shapes
- inverted = build_inverted_edges(shape_b)
- inverted.concat(build_inverted_edges(shape_a))
-
- #DEBUG
- if $i == 0
- puts
- puts "debug of inverted edges:"
- pp inverted
- end
-
- inverted.each_with_index do |line, line_index|
-
- # Initialize max and min
- amin = vecDotProd(shape_a.first, line)
- amax = vecDotProd(shape_a.first, line)
- bmin = vecDotProd(shape_b.first, line)
- bmax = vecDotProd(shape_b.first, line)
-
- # Determine max and min of a_shape
- shape_a.each_with_index do |vertex, vertex_index|
- dot = vecDotProd(vertex, line)
- if dot > amax
- amax = dot
- elsif dot < amin
- amin = dot
- end
- end
-
- # Determine max and min of b_shape
- shape_b.each_with_index do |vertex, vertex_index|
- dot = vecDotProd(vertex, line)
- if dot > bmax
- bmax = dot
- elsif dot < bmin
- bmin = dot
- end
+# Calculates the minimum point and maximum point projected onto the line
+def calculate_minmax(shape, line)
+ min = vecDotProd(shape.first, line)
+ max = vecDotProd(shape.first, line)
+ shape.each_with_index do |vertex, vertex_index|
+ dot = vecDotProd(vertex, line)
+ if dot > max
+ max = dot
+ elsif dot < min
+ min = dot
end
+ end
+ [max, min]
+end
- #DEBUG: display the lines, transluscent if they are not "seperating"
- # If all lines are transluscent then the logic believes the
- # shapes are colliding
- if line_index < shape_a.length
- DebugLines[line_index].x1 = shape_a[line_index][0]
- DebugLines[line_index].y1 = shape_a[line_index][1]
- if shape_a[line_index].nil?
- DebugLines[line_index].x2 = shape_a[line_index + 1][0]
- DebugLines[line_index].y2 = shape_a[line_index + 1][1]
- else
- DebugLines[line_index].x2 = shape_a[0][0]
- DebugLines[line_index].y2 = shape_a[0][1]
- end
+# Displays debug info(used inside the inverted.each loop)
+def debug_inner_loop(shape_a, shape_b, line_index, amax, amin, bmax, bmin)
+ #DEBUG: display the lines(uninverted), transluscent if they are not "seperating"
+ # If all lines are transluscent then the logic believes the
+ # shapes are colliding
+ if line_index < shape_a.length
+ DebugLines[line_index].x1 = shape_a[line_index][0]
+ DebugLines[line_index].y1 = shape_a[line_index][1]
+ if shape_a[line_index].nil?
+ DebugLines[line_index].x2 = shape_a[line_index + 1][0]
+ DebugLines[line_index].y2 = shape_a[line_index + 1][1]
else
- DebugLines[line_index].x1 = shape_b[line_index - shape_a.length][0]
- DebugLines[line_index].y1 = shape_b[line_index - shape_a.length][1]
- if shape_a[line_index - shape_a.length + 1].nil?
- DebugLines[line_index].x2 = shape_b[0][0]
- DebugLines[line_index].y2 = shape_b[0][1]
- else
- DebugLines[line_index].x2 = shape_b[line_index - shape_a.length + 1][0]
- DebugLines[line_index].y2 = shape_b[line_index - shape_a.length + 1][1]
- end
- end
- DebugLines[line_index].color = $colors[line_index % $colors.length]
-
- #DEBUG: print out line information
- if $i == 0
- puts
- puts $colors[line_index % $colors.length]
- puts line_index
- puts "x1 #{DebugLines[line_index].x1}"
- puts "y1 #{DebugLines[line_index].y1}"
- puts "x2 #{DebugLines[line_index].x2}"
- puts "y2 #{DebugLines[line_index].y2}"
- puts "(((#{amin} < #{bmax}) && (#{amin} > #{bmin})) || ((#{bmin} < #{amax}) && (#{bmin} > #{amin})))"
+ DebugLines[line_index].x2 = shape_a[0][0]
+ DebugLines[line_index].y2 = shape_a[0][1]
end
- if (((amin <= bmax) && (amin >= bmin)) || ((bmin <= amax) && (bmin >= amin)))
- DebugLines[line_index].color.a = 0.2
+ else
+ DebugLines[line_index].x1 = shape_b[line_index - shape_a.length][0]
+ DebugLines[line_index].y1 = shape_b[line_index - shape_a.length][1]
+ if shape_a[line_index - shape_a.length + 1].nil?
+ DebugLines[line_index].x2 = shape_b[0][0]
+ DebugLines[line_index].y2 = shape_b[0][1]
else
- DebugLines[line_index].color.a = 1.0
-
- # The logic should end the calculations early once it detects lack of collision
- # however for debug purposes this is disabled
- #return false
+ DebugLines[line_index].x2 = shape_b[line_index - shape_a.length + 1][0]
+ DebugLines[line_index].y2 = shape_b[line_index - shape_a.length + 1][1]
end
+ end
+ DebugLines[line_index].color = $colors[line_index % $colors.length]
- #DEBUG: make the debug lines effectively infinitly long
- tempx1 = DebugLines[line_index].x1
- tempx2 = DebugLines[line_index].x2
- tempy1 = DebugLines[line_index].y1
- tempy2 = DebugLines[line_index].y2
- DebugLines[line_index].x1 = (tempx1 *(1+1000)/2) + (tempx2 * (1-1000)/2)
- DebugLines[line_index].y1 = (tempy1 *(1+1000)/2) + (tempy2 * (1-1000)/2)
- DebugLines[line_index].x2 = (tempx2 *(1+1000)/2) + (tempx1 * (1-1000)/2)
- DebugLines[line_index].y2 = (tempy2 *(1+1000)/2) + (tempy1 * (1-1000)/2)
+ #DEBUG: print out line information
+ if $i == 0
+ puts
+ puts $colors[line_index % $colors.length]
+ puts line_index
+ puts "x1 #{DebugLines[line_index].x1}"
+ puts "y1 #{DebugLines[line_index].y1}"
+ puts "x2 #{DebugLines[line_index].x2}"
+ puts "y2 #{DebugLines[line_index].y2}"
+ puts "(((#{amin} < #{bmax}) && (#{amin} > #{bmin})) || ((#{bmin} < #{amax}) && (#{bmin} > #{amin})))"
end
- true
+ if (((amin <= bmax) && (amin >= bmin)) || ((bmin <= amax) && (bmin >= amin)))
+ DebugLines[line_index].color.a = 0.2
+ else
+ DebugLines[line_index].color.a = 1.0
+ end
+
+ #DEBUG: make the debug lines effectively infinitly long
+ tempx1 = DebugLines[line_index].x1
+ tempx2 = DebugLines[line_index].x2
+ tempy1 = DebugLines[line_index].y1
+ tempy2 = DebugLines[line_index].y2
+ DebugLines[line_index].x1 = (tempx1 *(1+1000)/2) + (tempx2 * (1-1000)/2)
+ DebugLines[line_index].y1 = (tempy1 *(1+1000)/2) + (tempy2 * (1-1000)/2)
+ DebugLines[line_index].x2 = (tempx2 *(1+1000)/2) + (tempx1 * (1-1000)/2)
+ DebugLines[line_index].y2 = (tempy2 *(1+1000)/2) + (tempy1 * (1-1000)/2)
end
+# Displays debug info(used outside the inverted.each loop)
+def debug_outer_loop(inverted)
+ if $i == 0
+ puts
+ puts "debug of inverted edges:"
+ pp inverted
+ end
+end
+
+
# Move camera
on :key_held do |event|
if event.key == 'w'
@@ -193,31 +216,31 @@ update do
$i %= 5
# Update shape 1 position to mouse
- s1.x = Camera.coordinate_to_worldspace(get(:mouse_x),0)[0]
- s1.y = Camera.coordinate_to_worldspace(0, get(:mouse_y))[1]
+ sB.x = Camera.coordinate_to_worldspace(get(:mouse_x),0)[0]
+ sB.y = Camera.coordinate_to_worldspace(0, get(:mouse_y))[1]
# Check hitboxes
a = hitbox_check(
- [[s2.x1, s2.y1],
- [s2.x2, s2.y2],
- [s2.x3, s2.y3],
- [s2.x4, s2.y4]],
- [[s1.x1 + s1.x, s1.y1 + s1.y],
- [s1.x2 + s1.x, s1.y2 + s1.y],
- [s1.x3 + s1.x, s1.y3 + s1.y],
- [s1.x4 + s1.x, s1.y4 + s1.y]],
+ [[sA.x1, sA.y1],
+ [sA.x2, sA.y2],
+ [sA.x3, sA.y3],
+ [sA.x4, sA.y4]],
+ [[sB.x1 + sB.x, sB.y1 + sB.y],
+ [sB.x2 + sB.x, sB.y2 + sB.y],
+ [sB.x3 + sB.x, sB.y3 + sB.y],
+ [sB.x4 + sB.x, sB.y4 + sB.y]],
)
#DEBUG
if $i == 0
- pp [[s2.x1, s2.y1],
- [s2.x2, s2.y2],
- [s2.x3, s2.y3],
- [s2.x4, s2.y4]]
- pp [[s1.x1 + s1.x, s1.y1 + s1.y],
- [s1.x2 + s1.x, s1.y2 + s1.y],
- [s1.x3 + s1.x, s1.y3 + s1.y],
- [s1.x4 + s1.x, s1.y4 + s1.y]]
+ pp [[sA.x1, sA.y1],
+ [sA.x2, sA.y2],
+ [sA.x3, sA.y3],
+ [sA.x4, sA.y4]]
+ pp [[sB.x1 + sB.x, sB.y1 + sB.y],
+ [sB.x2 + sB.x, sB.y2 + sB.y],
+ [sB.x3 + sB.x, sB.y3 + sB.y],
+ [sB.x4 + sB.x, sB.y4 + sB.y]]
end
end