Skip to content

Instantly share code, notes, and snippets.

@safiire
Created August 28, 2014 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save safiire/15c298d3a1e889ba5fa5 to your computer and use it in GitHub Desktop.
Save safiire/15c298d3a1e889ba5fa5 to your computer and use it in GitHub Desktop.
Line Intersection with Matrices
require 'matrix'
####
## Random program that uses matrices to find intersection between 2 lines
## the linear algebra way.
## I am not sure why I made this, but it's probably because I like matrices
class Line
attr_reader :slope, :offset
def initialize(slope, offset)
@slope = slope
@offset = offset
end
def to_s
"y = #{slope}x + #{offset}"
end
alias :inspect :to_s
end
####
## Parse equation for a line looking like 'y = 3/4x + 12'
def parse_line(str)
match_data = str.match(/^y\s+?=\s+?(\d+\/\d+)\s?x\s+?\+\s+?(\d+)/)
fail("Could not parse #{str}") if match_data.nil?
offset = match_data[2].to_i
numerator, denominator = match_data[1].split(/\//).map(&:to_i)
Line.new(Rational(numerator, denominator), offset)
end
####
## Turn a system of linear equations into a matrix equation
def to_matrices(lines)
fail("Need two lines") unless lines.size == 2
rows = lines.map{|line| [-line.slope, 1] }
matrix_a = Matrix.rows(rows)
rows = lines.map{|line| [line.offset] }
matrix_b = Matrix.rows(rows)
[matrix_a, matrix_b]
end
# So since A * [x] = B
# [y]
# then [x] = A^-1 * B
# [y]
def intersection(lines)
fail("Need two lines") unless lines.size == 2
a, b = to_matrices(lines)
x = a.inverse * b
x.column(0).map do |element|
element.denominator == 1 ? element.to_i : element
end
end
## Make some lines.
lines = [
parse_line('y = 2/4x + 2'),
parse_line('y = 5/2x + 10')
]
puts "Finding the intersection between these lines:\n\n"
lines.each do |line|
puts line
end
puts "\nThe point of intersection is:\n\n"
puts intersection(lines)
## Output #######################################
# Finding the intersection between these lines:
#
# y = 1/2x + 2
# y = 5/2x + 10
# The point of intersection is:
# Vector[-4, 0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment