require 'spec_helper' describe GeometricLine do infinity = 1.0 / 0.0 describe '#initialize_by_numbers' do line = GeometricLine.new(1, 2) it 'to be equal' do expect(line.point1).to eq(1) expect(line.point2).to eq(2) end it 'to be not equal' do expect(line.point1).not_to eq(3) expect(line.point2).not_to eq(3) end end describe '#initialize_by_array' do point1 = GeometricPoint.new(1, 2) point2 = GeometricPoint.new(1, 1) line = GeometricLine.new_by_arrays([1, 2], [1, 1]) it 'to be equal' do expect(line.point1).to eq(point1) expect(line.point2).to eq(point2) end it 'to be not equal' do expect(line.point1).not_to eq(point2) expect(line.point2).not_to eq(point1) end end describe '#angle_to' do line = GeometricLine.new_by_arrays([0, 0], [1, 1]) it 'to be angle to self' do expect(line.angle_to(line)).to eq(0) end it 'to be angle to perpendicular' do perp = GeometricLine.new_by_arrays([0, 0], [1, -1]) expect(line.angle_to(perp)).to eq(Math::PI / 2) expect(perp.angle_to(line)).to eq(Math::PI / 2) end it 'to be angle to acute' do acute = GeometricLine.new_by_arrays([0, 0], [0, 1]) expect(line.angle_to(acute)).to eq(Math::PI / 4) expect(acute.angle_to(line)).to eq(Math::PI / 4) end end describe '#distance_to' do it 'to be point on line' do line = GeometricLine.new_by_arrays([0, 2], [2, 0]) point = GeometricPoint.new(1, 1) expect(line.distance_to(point)).to eq(0) end it 'to be flat line' do line = GeometricLine.new_by_arrays([0, 1], [2, 1]) point = GeometricPoint.new(1, 2) expect(line.distance_to(point)).to eq(1) end end describe '#horizontal?' do it 'to be horizontal' do line = GeometricLine.new_by_arrays([0, 0], [1, 0]) expect(line.horizontal?).to eq(true) end it 'to be not horizontal' do line = GeometricLine.new_by_arrays([0, 0], [1, 1]) expect(line.horizontal?).to eq(false) end end describe '#intersect_x' do it 'to be vertical non overlapping' do line1 = GeometricLine.new_by_arrays([0, 0], [0, 1]) line2 = GeometricLine.new_by_arrays([1, 0], [1, 1]) expect(line1.intersect_x(line2).nil?).to eq(true) end it 'to be vertical overlapping' do line1 = GeometricLine.new_by_arrays([0, 0], [0, 1]) line2 = GeometricLine.new_by_arrays([0, 0], [0, 1]) expect(line1.intersect_x(line2)).to eq(0) expect(line2.intersect_x(line1)).to eq(0) end it 'to be horizontal non overlapping' do line1 = GeometricLine.new_by_arrays([0, 0], [1, 0]) line2 = GeometricLine.new_by_arrays([0, 1], [1, 1]) expect(line1.intersect_x(line2).nil?).to eq(true) end it 'to be horizontal overlapping' do line1 = GeometricLine.new_by_arrays([0, 0], [1, 0]) line2 = GeometricLine.new_by_arrays([0, 0], [1, 0]) expect(line1.intersect_x(line2).nil?).to eq(true) end it 'to be perpendicular' do [-1, 0, 1].each do |xo| [-1, 0, 1].each do |yo| line1 = GeometricLine.new_by_arrays([xo, yo], [xo + 0, yo + 1]) line2 = GeometricLine.new_by_arrays([xo, yo], [xo + 1, yo + 0]) expect(line1.intersect_x(line2)).to eq(xo) expect(line2.intersect_x(line1)).to eq(xo) end end end end describe '#parallel_to?' do it 'to be identical' do (1..100).each do point1 = [rand-0.5, rand-0.5] point2 = [rand-0.5, rand-0.5] line = GeometricLine.new_by_arrays(point1, point2) expect(line.parallel_to?(line)).to eq(true) end end it 'to be vertical' do line1 = GeometricLine.new_by_arrays([0, 0], [0, 1]) line2 = GeometricLine.new_by_arrays([0, 0], [0, -1]) expect(line1.parallel_to?(line2)).to eq(true) expect(line2.parallel_to?(line1)).to eq(true) end it 'to be horizontal' do line1 = GeometricLine.new_by_arrays([0, 0], [-1, 0]) line2 = GeometricLine.new_by_arrays([0, 0], [1, 0]) expect(line1.parallel_to?(line2)).to eq(true) expect(line2.parallel_to?(line1)).to eq(true) end it 'to be shifted' do line1 = GeometricLine.new_by_arrays([0, 0], [1, 1]) line2 = GeometricLine.new_by_arrays([1, 0], [2, 1]) expect(line1.parallel_to?(line2)).to eq(true) expect(line2.parallel_to?(line1)).to eq(true) end it 'to be not parallel' do line1 = GeometricLine.new_by_arrays([0, 0], [-1, 1]) line2 = GeometricLine.new_by_arrays([0, 0], [1, -2]) expect(line1.parallel_to?(line2)).to eq(false) expect(line2.parallel_to?(line1)).to eq(false) end end describe '#slope' do it 'to be vertical' do [-1, 0, 1].each do |x| line = GeometricLine.new(GeometricPoint.new(x, 0), GeometricPoint.new(x, 1)) expect(line.slope).to eq(infinity) end end it 'to be vertical negative' do [-1, 0, 1].each do |x| line = GeometricLine.new(GeometricPoint.new(x, 0), GeometricPoint.new(x, -1)) expect(line.slope).to eq(-infinity) end end it 'to be horizontal' do [-1, 0, 1].each do |y| line = GeometricLine.new(GeometricPoint.new(0, y), GeometricPoint.new(1, y)) expect(line.slope).to eq(0) end end it 'to be horizontal negative' do [-1, 0, 1].each do |y| line = GeometricLine.new(GeometricPoint.new(0, y), GeometricPoint.new(-1, y)) expect(line.slope).to eq(0) end end it 'to be full circle' do delta = 0.000001 increment = Math::PI / 10 divisions = 2 * Math::PI / increment radius = 1 (0..divisions).each do |d| angle = d * increment y = radius * Math::sin(angle) x = radius * Math::cos(angle) line = GeometricLine.new(GeometricPoint.new(0, 0), GeometricPoint.new(x, y)) expect(line.slope).to be_within(delta).of(Math::tan(angle)) end end end describe '#vertical?' do it 'to be vertical' do line = GeometricLine.new_by_arrays([0, 0], [0, 1]) expect(line.vertical?).to eq(true) end it 'to be not vertical' do line = GeometricLine.new_by_arrays([0, 0], [1, 1]) expect(line.vertical?).to eq(false) end end describe '#x_intercept' do it 'to be anchored at x axis' do [-1, 0, 1].each do |xi| line = GeometricLine.new(GeometricPoint.new(xi, 0), GeometricPoint.new(1, 1)) expect(line.x_intercept).to eq(xi) end end it 'to be not floating' do [-1, 1].each do |slope| [-2, 0, 2].each do |yo| [-1, 0, 1].each do |xi| point1 = GeometricPoint.new(xi + yo / slope, yo) point2 = GeometricPoint.new(xi + (yo + 1) / slope, yo + 1) line = GeometricLine.new(point1, point2) expect(line.x_intercept).to eq(xi) end end end end it 'to be vertical' do [-1, 0, 1].each do |xi| line = GeometricLine.new(GeometricPoint.new(xi, 1), GeometricPoint.new(xi, 2)) expect(line.x_intercept).to eq(xi) end end it 'to be horizontal' do [-1, 0, 1].each do |yo| line = GeometricLine.new(GeometricPoint.new(0, yo), GeometricPoint.new(1, yo)) expect(line.x_intercept.nil?).to eq(true) end end end describe '#y_intercept' do it 'to be anchored at y axis' do [-1, 0, 1].each do |yi| line = GeometricLine.new(GeometricPoint.new(0, yi), GeometricPoint.new(1, 1)) expect(line.y_intercept).to eq(yi) end end it 'to be not floating' do [-1, 1].each do |slope| [-2, 0, 2].each do |xo| [-1, 0, 1].each do |yi| point1 = GeometricPoint.new(xo, yi + slope * xo) point2 = GeometricPoint.new(xo + 1, yi + slope * (xo + 1)) line = GeometricLine.new(point1, point2) expect(line.y_intercept).to eq(yi) end end end end it 'to be horizontal' do [-1, 0, 1].each do |yi| line = GeometricLine.new(GeometricPoint.new(1, yi), GeometricPoint.new(2, yi)) expect(line.y_intercept).to eq(yi) end end it 'to be vertical' do [-1, 0, 1].each do |xo| line = GeometricLine.new(GeometricPoint.new(xo, 0), GeometricPoint.new(xo, 1)) expect(line.y_intercept.nil?).to eq(true) end end end end