Created
November 25, 2016 09:41
-
-
Save JoshCheek/86d36548336d5f2bb0b0d1e01c0a28a2 to your computer and use it in GitHub Desktop.
Given a point, a line, and a distance, calculate the two points on that line that are that distance away.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# encoding: utf-8 | |
# Given a point, a line, and a distance, calculate the two points on that line that are that distance away. | |
# Relevant equations | |
# eqn for line (m here is our gslope, b is the y-intercept) | |
# y = mx + b | |
# pythagorean theorem from origin (r, the radius, will be our gdist, the distance between the points) | |
# r**2 = x**2 + y**2 | |
# Make floats less irritating to look at | |
class Float | |
def inspect | |
sprintf('%f', self).gsub(/\.?0+$/, '') # => "6", "2", "6", "8", "1.333333", "12", "10", "0", "-6", "10", "10", "10", "12", "10", "0", "-6", "10", "12", "10", "0", "-6", "10", "12", "10", "0", "-6", "10", "12", "10", "0", "-6", "10", "6", "8", "12", "10", "0", "-6", "6", "8", "12", "10", "0", "-6", "6", "8", "6", "8", "12", "10", "0", "-6", "6", "8", "12", "10", "0", "-6", "6", "8", "12", "10", "0", "-6" | |
end # => :inspect | |
end # => :inspect | |
# make math functions more convenient | |
include Math # => Object | |
alias √ sqrt | |
# GIVENS (indicated by starting the var name w/ a g) | |
gx1, gy1 = 6.0, 2.0 # => [6, 2] | |
g∆x, g∆y = 6.0, 8.0 # => [6, 8] | |
gslope = g∆y / g∆x # => 1.333333 | |
gdist = 10 # => 10 | |
gx2, gy2 = 12, 10 # => [12, 10] | |
gx3, gy3 = 0, -6 # => [0, -6] | |
# An assertion function to explode if we get it wrong | |
define_method :assert do |named_values| | |
named_values.each do |name, calculated| # => {:gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6, :gdist=>10}, {:"g\u2206x"=>6, :"g\u2206y"=>8, :gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6} | |
expected = binding.local_variable_get name # => 12, 10, 0, -6, 10, 6, 8, 12, 10, 0, -6 | |
next if calculated == expected # => true, true, true, true, true, true, true, true, true, true, true | |
raise "Expected #{name} = #{expected.inspect} but it calculated to #{calculated.inspect}" | |
end # => {:gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6, :gdist=>10}, {:"g\u2206x"=>6, :"g\u2206y"=>8, :gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6} | |
end # => :assert | |
# Show we can find calculate the distance | |
lambda do | |
assert( | |
gx2: x2 = gx1 + g∆x, # => 12 | |
gy2: y2 = gy1 + g∆y, # => 10 | |
gx3: x3 = gx1 - g∆x, # => 0 | |
gy3: y3 = gy1 - g∆y, # => -6 | |
gdist: √( (x2 - gx1)**2 + (y2 - gy1)**2 ), # => 10 | |
gdist: √( (x3 - gx1)**2 + (y3 - gy1)**2 ), # => 10 | |
gdist: √( (g∆x)**2 + (g∆y)**2 ), # => 10 | |
) # => {:gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6, :gdist=>10} | |
end.call # => {:gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6, :gdist=>10} | |
# Show we can find (x2, y2) and (x3, y3) | |
lambda do | |
# Points on that line will satisfy | |
# y = gslope * x + b | |
# The points will be gdist from (gx1, gy1), | |
# thus they make a circle around that point | |
# We'll translate (x1, y1) to the origin to solve | |
# Thus there is a circle of possible values given by | |
# gdist**2 = x**2 + y**2 | |
# Solve for x: | |
# gdist**2 = x**2 + (gslope * x)**2 | |
# = x**2 + gslope**2 * x**2 | |
# = x**2 (1 + gslope**2) | |
# x**2 = gdist**2 / (1 + gslope**2) | |
# x = ±√(gdist**2 / (1 + gslope**2)) | |
# Since we translated x1 to the origin, the x we found is ∆x | |
# x = (x2 - x1) | |
# = ∆x | |
# Thus | |
# ∆x = ±√(gdist**2 / (1 + gslope**2)) | |
# And the rest is trivial | |
assert( | |
g∆x: ∆x = √(gdist**2 / (gslope**2 + 1)), # => 6 | |
g∆y: ∆y = gslope * ∆x, # => 8 | |
gx2: gx1 + ∆x, # => 12 | |
gy2: gy1 + ∆y, # => 10 | |
gx3: gx1 - ∆x, # => 0 | |
gy3: gy1 - ∆y, # => -6 | |
) # => {:"g\u2206x"=>6, :"g\u2206y"=>8, :gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6} | |
end.call # => {:"g\u2206x"=>6, :"g\u2206y"=>8, :gx2=>12, :gy2=>10, :gx3=>0, :gy3=>-6} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment