Created
August 28, 2014 04:02
-
-
Save safiire/15c298d3a1e889ba5fa5 to your computer and use it in GitHub Desktop.
Line Intersection with Matrices
This file contains hidden or 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
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