diff --git a/Rakefile b/Rakefile
index 2d95954..697427c 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,7 +3,6 @@ require 'rake/testtask'
desc 'Test'
task :test do
- sh 'jruby test/pbisector_test.rb'
sh 'jruby test/circumcircle_test.rb'
sh 'jruby test/triangle_points_test.rb'
end
diff --git a/lib/math_demo/circumcircle.rb b/lib/math_demo/circumcircle.rb
index a10a42c..86a48cc 100644
--- a/lib/math_demo/circumcircle.rb
+++ b/lib/math_demo/circumcircle.rb
@@ -1,5 +1,5 @@
# Circumcircle from 3 points
-require_relative './pbisector'
+require 'matrix'
class Circumcircle
attr_reader :center, :radius, :points
@@ -8,29 +8,36 @@ def initialize(points)
end
def calculate
- ab = PBisector.new(points[0], points[1]) # find 2 midpoints
- bc = PBisector.new(points[1], points[2])
- @center = circumcenter(ab, bc)
+ @center = Vec2D.new(-(bx / am), -(by / am))
@radius = center.dist(points[2]) # points[2] = c
end
private
- Vect = Struct.new(:x, :y, :z)
+ # Matrix math see matrix_math.md and in detail
+ # http://mathworld.wolfram.com/Circumcircle.html
- def circumcenter(pb1, pb2)
- # equation of the first bisector (ax - y = -b)
- a0 = Math.tan pb1.angle
- v0 = pb1.midpoint
- a1 = Math.tan pb2.angle
- v1 = pb2.midpoint
- eq0 = Vect.new(a0, -1, -1 * (v0.y - v0.x * a0))
- eq1 = Vect.new(a1, -1, -1 * (v1.y - v1.x * a1))
- # calculate x and y coordinates of the circumcenter
- ox = (eq1.y * eq0.z - eq0.y * eq1.z) /
- (eq0.x * eq1.y - eq1.x * eq0.y)
- oy = (eq0.x * eq1.z - eq1.x * eq0.z) /
- (eq0.x * eq1.y - eq1.x * eq0.y)
- Vec2D.new(ox, oy)
+ def am
+ 2 * Matrix[
+ [points[0].x, points[0].y, 1],
+ [points[1].x, points[1].y, 1],
+ [points[2].x, points[2].y, 1]
+ ].determinant
+ end
+
+ def bx
+ -Matrix[
+ [points[0].x * points[0].x + points[0].y * points[0].y, points[0].y, 1],
+ [points[1].x * points[1].x + points[1].y * points[1].y, points[1].y, 1],
+ [points[2].x * points[2].x + points[2].y * points[2].y, points[2].y, 1]
+ ].determinant
+ end
+
+ def by
+ Matrix[
+ [points[0].x * points[0].x + points[0].y * points[0].y, points[0].x, 1],
+ [points[1].x * points[1].x + points[1].y * points[1].y, points[1].x, 1],
+ [points[2].x * points[2].x + points[2].y * points[2].y, points[2].x, 1]
+ ].determinant
end
end
diff --git a/lib/math_demo/matrix_math.md b/lib/math_demo/matrix_math.md
new file mode 100644
index 0000000..56729c8
--- /dev/null
+++ b/lib/math_demo/matrix_math.md
@@ -0,0 +1,17 @@
+### Matrix Math ###
+
+For detailed workings see [Circumcircle at Mathworld Wolfram.com][circumcircle]
+
+
+a = {{x1 y1 1}, {x2 y2 1}, {x3 y3 1}}
+
+bx = -{{x12 + y12 y1 1}, {x22 + y22 y2 1}, {x32 + y32 y3 1}}
+
+by = {{x12 + y12 x1 1}, {x22 + y22 x2 1}, {x32 + y32 x3 1}}
+
+xo = -bx / 2 * a
+
+yo = -by / 2 * a
+
+
+[circumcircle]:http://mathworld.wolfram.com/Circumcircle.html
diff --git a/lib/math_demo/pbisector.rb b/lib/math_demo/pbisector.rb
deleted file mode 100644
index da68edb..0000000
--- a/lib/math_demo/pbisector.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-require 'propane'
-
-# Perpendicular Bisector class, takes two points as Vec2D objects
-class PBisector
- attr_reader :midpoint, :angle
- def initialize(a, b)
- @midpoint = (a + b) / 2.0
- dvector = b - a
- @angle = Math.atan2(dvector.y, dvector.x) - Math::PI / 2
- end
-end
diff --git a/lib/math_demo/version.rb b/lib/math_demo/version.rb
index 07d65ed..8de73a7 100644
--- a/lib/math_demo/version.rb
+++ b/lib/math_demo/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
# A wrapper for version
module MathDemo
- VERSION = '0.0.1'.freeze
+ VERSION = '0.1.0'.freeze
end
diff --git a/test/pbisector_test.rb b/test/pbisector_test.rb
deleted file mode 100644
index f95a2b1..0000000
--- a/test/pbisector_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require_relative './test_helper'
-require_relative '../lib/math_demo/pbisector'
-
-METHODS = %i(midpoint angle).freeze
-
-class PBisectorTest < Minitest::Test
- def setup
- @bisector = PBisector.new(Vec2D.new(100, 50), Vec2D.new(500, 350))
- end
-
- def test_respond
- METHODS.each do |method_string|
- assert_respond_to @bisector, method_string
- end
- end
-
- def test_midpoint
- assert_equal @bisector.midpoint, Vec2D.new(300, 200)
- end
-
- def test_angle # Angle of bisector to the 3, 4, 5 triangle
- assert_in_delta @bisector.angle, 36.87.radians - Math::PI / 2
- end
-
- def tear_down
- @bisector = nil?
- end
-end