aurora-geometry 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE +21 -0
  5. data/README.markdown +105 -0
  6. data/Rakefile +24 -0
  7. data/aurora-geometry.gemspec +23 -0
  8. data/lib/geometry.rb +22 -0
  9. data/lib/geometry/arc.rb +94 -0
  10. data/lib/geometry/circle.rb +122 -0
  11. data/lib/geometry/cluster_factory.rb +15 -0
  12. data/lib/geometry/edge.rb +140 -0
  13. data/lib/geometry/line.rb +154 -0
  14. data/lib/geometry/obround.rb +238 -0
  15. data/lib/geometry/path.rb +67 -0
  16. data/lib/geometry/point.rb +163 -0
  17. data/lib/geometry/point_zero.rb +107 -0
  18. data/lib/geometry/polygon.rb +368 -0
  19. data/lib/geometry/polyline.rb +318 -0
  20. data/lib/geometry/rectangle.rb +378 -0
  21. data/lib/geometry/regular_polygon.rb +136 -0
  22. data/lib/geometry/rotation.rb +190 -0
  23. data/lib/geometry/size.rb +75 -0
  24. data/lib/geometry/size_zero.rb +70 -0
  25. data/lib/geometry/square.rb +113 -0
  26. data/lib/geometry/text.rb +24 -0
  27. data/lib/geometry/transformation.rb +171 -0
  28. data/lib/geometry/transformation/composition.rb +39 -0
  29. data/lib/geometry/triangle.rb +78 -0
  30. data/lib/geometry/vector.rb +34 -0
  31. data/test/geometry.rb +5 -0
  32. data/test/geometry/arc.rb +25 -0
  33. data/test/geometry/circle.rb +112 -0
  34. data/test/geometry/edge.rb +132 -0
  35. data/test/geometry/line.rb +132 -0
  36. data/test/geometry/obround.rb +25 -0
  37. data/test/geometry/path.rb +66 -0
  38. data/test/geometry/point.rb +258 -0
  39. data/test/geometry/point_zero.rb +177 -0
  40. data/test/geometry/polygon.rb +214 -0
  41. data/test/geometry/polyline.rb +266 -0
  42. data/test/geometry/rectangle.rb +154 -0
  43. data/test/geometry/regular_polygon.rb +120 -0
  44. data/test/geometry/rotation.rb +108 -0
  45. data/test/geometry/size.rb +97 -0
  46. data/test/geometry/size_zero.rb +153 -0
  47. data/test/geometry/square.rb +66 -0
  48. data/test/geometry/transformation.rb +169 -0
  49. data/test/geometry/transformation/composition.rb +49 -0
  50. data/test/geometry/triangle.rb +32 -0
  51. data/test/geometry/vector.rb +41 -0
  52. metadata +115 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 679c3759dd2dedb0e7c23c68c1e7cf57d7e3a062
4
+ data.tar.gz: 91861bec8416024680f582a465478dbd2ed9dee3
5
+ SHA512:
6
+ metadata.gz: fc0d69e2b233c88288628217c2cc3bb665590c2f904431397c22d70c1f4636215f9c92d3b83a8572f6fb00aa3fae9837b338103dc4ffd5e03a4ec5f00c50f9d1
7
+ data.tar.gz: 899e24c83db56901a937b9da0593cbe0a4be071b662593c6b7ec3c2dbdd7280208174be2c1f574ad8158632e74b4681e5c339e89417bb40e60d4778ca589c3fc
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ .yardoc
4
+ Gemfile.lock
5
+ pkg/*
6
+ doc
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rake'
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2012, Brandon Fosdick <bfoz@bfoz.net>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided
5
+ that the following conditions are met:
6
+
7
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the
8
+ following disclaimer.
9
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
10
+ the following disclaimer in the documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
20
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.markdown ADDED
@@ -0,0 +1,105 @@
1
+ Geometry for Ruby
2
+ =================
3
+
4
+ [![Build Status](https://travis-ci.org/bfoz/geometry.png)](https://travis-ci.org/bfoz/geometry)
5
+
6
+ Classes and methods for the handling of all of the basic geometry that you
7
+ learned in high school (and then forgot).
8
+
9
+ The classes in this libary are based on the Vector class provided by the Ruby
10
+ standard library. Geometric primitives are generally assumed to lie in 2D space,
11
+ but aren't necessarily restricted to it. Please let me know if you find cases
12
+ that don't work in higher dimensions and I'll do my best to fix them.
13
+
14
+ License
15
+ -------
16
+
17
+ Copyright 2012-2014 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
18
+
19
+ Primitives
20
+ ----------
21
+
22
+ - Point
23
+ - Size
24
+ - Line
25
+ - Edge
26
+ - [Arc](http://en.wikipedia.org/wiki/Arc_(geometry)), Circle
27
+ - Rectangle, Square
28
+ - Path, [Polyline](http://en.wikipedia.org/wiki/Polyline), [Polygon](http://en.wikipedia.org/wiki/Polygon), [RegularPolygon](http://en.wikipedia.org/wiki/Regular_polygon)
29
+ - Transformation
30
+ - [Triangle](http://en.wikipedia.org/wiki/Triangle)
31
+ - [Obround](http://en.wiktionary.org/wiki/obround)
32
+
33
+ Examples
34
+ --------
35
+
36
+ ### Point
37
+ ```ruby
38
+ point = Geometry::Point[3,4] # 2D Point at coordinate 3, 4
39
+
40
+ # Copy constructors
41
+ point2 = Geometry::Point[point]
42
+ point2 = Geometry::Point[Vector[5,6]]
43
+
44
+ # Accessors
45
+ point.x
46
+ point.y
47
+ point[2] # Same as point.z
48
+
49
+ # Zero
50
+ PointZero.new # A Point full of zeros of unspecified length
51
+ Point.zero # Another way to do the same thing
52
+ Point.zero(3) # => Point[0,0,0]
53
+ ```
54
+
55
+ ### Line
56
+ ```ruby
57
+ # Two-point constructors
58
+ line = Geometry::Line[[0,0], [10,10]]
59
+ line = Geometry::Line[Geometry::Point[0,0], Geometry::Point[10,10]]
60
+ line = Geometry::Line[Vector[0,0], Vector[10,10]]
61
+
62
+ # Slope-intercept constructors
63
+ Geometry::Line[Rational(3,4), 5] # Slope = 3/4, Intercept = 5
64
+ Geometry::Line[0.75, 5]
65
+
66
+ # Point-slope constructors
67
+ Geometry::Line(Geometry::Point[0,0], 0.75)
68
+ Geometry::Line(Vector[0,0], Rational(3,4))
69
+
70
+ # Special constructors (2D only)
71
+ Geometry::Line.horizontal(y=0)
72
+ Geometry::Line.vertical(x=0)
73
+ ```
74
+
75
+ ### Rectangle
76
+ ```ruby
77
+ # A Rectangle made from two corner points
78
+ Geometry::Rectangle.new [1,2], [2,3]
79
+ Geometry::Rectangle.new from:[1,2], to:[2,3]
80
+
81
+ Geometry::Rectangle.new center:[1,2], size:[1,1] # Using a center point and a size
82
+ Geometry::Rectangle.new origin:[1,2], size:[1,1] # Using an origin point and a size
83
+
84
+ # A Rectangle with its origin at [0, 0] and a size of [10, 20]
85
+ Geometry::Rectangle.new size: [10, 20]
86
+ Geometry::Rectangle.new size: Size[10, 20]
87
+ Geometry::Rectangle.new width: 10, height: 20
88
+ ```
89
+
90
+ ### Circle
91
+ ```ruby
92
+ # A circle at Point[1,2] with a radius of 3
93
+ circle = Geometry::Circle.new center:[1,2], radius:3
94
+ ```
95
+
96
+ ### Polygon
97
+ ```ruby
98
+ # A polygon that looks a lot like a square
99
+ polygon = Geometry::Polygon.new [0,0], [1,0], [1,1], [0,1]
100
+ ```
101
+ ### Regular Polygon
102
+ ```ruby
103
+ # Everyone loves a good hexagon
104
+ hexagon = Geometry::RegularPolygon.new 6, :diameter => 3
105
+ ```
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ task :default => :test
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push "lib"
8
+ t.test_files = FileList['test/**/*.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :fixdates do
13
+ branch = `git branch --no-color -r --merged`.strip
14
+ `git fix-dates #{branch}..HEAD`
15
+ end
16
+
17
+ task :fixdates_f do
18
+ branch = `git branch --no-color -r --merged`.strip
19
+ `git fix-dates -f #{branch}..HEAD`
20
+ end
21
+
22
+ task :trim_whitespace do
23
+ system(%Q[git status --short | awk '{if ($1 != "D" && $1 != "R") print $2}' | grep -e '.*\.rb$' | xargs sed -i '' -e 's/[ \t]*$//g;'])
24
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "aurora-geometry"
6
+ s.version = '0.0.2'
7
+ s.authors = ["Brandon Fosdick", "Meseker Yohannes"]
8
+ s.email = ["meseker.yohannes@gmail.com"]
9
+ s.homepage = "http://github.com/meseker/geometry"
10
+ s.summary = %q{Geometric primitives and algoritms}
11
+ s.description = %q{Geometric primitives and algorithms for Ruby}
12
+
13
+ s.rubyforge_project = "aurora-geometry"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ # specify any dependencies here; for example:
21
+ # s.add_development_dependency "rspec"
22
+ # s.add_runtime_dependency "rest-client"
23
+ end
data/lib/geometry.rb ADDED
@@ -0,0 +1,22 @@
1
+ require_relative 'geometry/arc'
2
+ require_relative 'geometry/circle'
3
+ require_relative 'geometry/line'
4
+ require_relative 'geometry/obround'
5
+ require_relative 'geometry/path'
6
+ require_relative 'geometry/point'
7
+ require_relative 'geometry/point_zero'
8
+ require_relative 'geometry/polygon'
9
+ require_relative 'geometry/polyline'
10
+ require_relative 'geometry/rectangle'
11
+ require_relative 'geometry/regular_polygon'
12
+ require_relative 'geometry/rotation'
13
+ require_relative 'geometry/size'
14
+ require_relative 'geometry/size_zero'
15
+ require_relative 'geometry/square'
16
+ require_relative 'geometry/transformation'
17
+ require_relative 'geometry/triangle'
18
+ require_relative 'geometry/vector'
19
+ require_relative 'geometry/text'
20
+
21
+ module Geometry
22
+ end
@@ -0,0 +1,94 @@
1
+ require_relative 'point'
2
+
3
+ require_relative 'cluster_factory'
4
+ require_relative 'point'
5
+
6
+ module Geometry
7
+
8
+ =begin rdoc
9
+ {http://en.wikipedia.org/wiki/Arc_(geometry) Arcs} are Circles that don't quite go all the way around
10
+
11
+ == Usage
12
+ An {Arc} with its center at [1,1] and a radius of 2 that starts at the X-axis and goes to the Y-axis (counter-clockwise)
13
+ arc = Geometry::Arc.new center:[1,1], radius:2, start:0, end:90
14
+ =end
15
+
16
+ class Arc
17
+ include ClusterFactory
18
+
19
+ attr_reader :center
20
+ attr_reader :radius
21
+ attr_reader :start_angle, :end_angle
22
+
23
+ # @overload new(center, start, end)
24
+ # Create a new {Arc} given center, start and end {Point}s
25
+ # @option options [Point] :center (PointZero) The {Point} at the center
26
+ # @option options [Point] :start The {Arc} starts at the start {Point}
27
+ # @option options [Point] :end The {Point} where it all ends
28
+ # @return [Arc]
29
+ # @overload new(center, radius, start, end)
30
+ # Create a new {Arc} given a center {Point}, a radius and start and end angles
31
+ # @option options [Point] :center (PointZero) The {Point} at the center of it all
32
+ # @option options [Numeric] :radius Radius
33
+ # @option options [Numeric] :start Starting angle
34
+ # @option options [Numeric] :end Ending angle
35
+ # @return [ThreePointArc]
36
+ def self.new(options={})
37
+ center = options.delete(:center) || PointZero.new
38
+
39
+ if options.has_key?(:radius)
40
+ original_new(center, options[:radius], options[:start], options[:end])
41
+ else
42
+ ThreePointArc.new(center, options[:start], options[:end])
43
+ end
44
+ end
45
+
46
+ # Construct a new {Arc}
47
+ # @overload initialize(center, radius, start_angle, end_angle)
48
+ # @param [Point] center The {Point} at the center of it all
49
+ # @param [Numeric] radius Radius
50
+ # @param [Numeric] start_angle Starting angle
51
+ # @param [Numeric] end_angle Ending angle
52
+ def initialize(center, radius, start_angle, end_angle)
53
+ @center = Point[center]
54
+ @radius = radius
55
+ @start_angle = start_angle
56
+ @end_angle = end_angle
57
+ end
58
+
59
+ # @return [Point] The starting point of the {Arc}
60
+ def first
61
+ @center + @radius * Vector[Math.cos(@start_angle), Math.sin(@start_angle)]
62
+ end
63
+
64
+ # @return [Point] The end point of the {Arc}
65
+ def last
66
+ @center + @radius * Vector[Math.cos(@end_angle), Math.sin(@end_angle)]
67
+ end
68
+ end
69
+
70
+ class ThreePointArc < Arc
71
+ attr_reader :center
72
+ attr_reader :start, :end
73
+
74
+ # Contruct a new {Arc} given center, start and end {Point}s
75
+ # Always assumes that the {Arc} is counter-clockwise. Reverse the order
76
+ # of the start and end points to get an {Arc} that goes around the other way.
77
+ # @overload initialize(center_point, start_point, end_point)
78
+ # @param [Point] center_point The {Point} at the center
79
+ # @param [Point] start_point The {Arc} starts at the start {Point}
80
+ # @param [Point] end_point The {Point} where it all ends
81
+ def initialize(center_point, start_point, end_point)
82
+ @center, @start, @end = [center_point, start_point, end_point].map {|p| Point[p]}
83
+ raise ArgumentError unless [@center, @start, @end].all? {|p| p.is_a?(Point)}
84
+ end
85
+
86
+ # The starting point of the {Arc}
87
+ # @return [Point]
88
+ alias :first :start
89
+
90
+ # The end point of the {Arc}
91
+ # @return [Point]
92
+ alias :last :end
93
+ end
94
+ end
@@ -0,0 +1,122 @@
1
+ require_relative 'cluster_factory'
2
+ require_relative 'point'
3
+
4
+ module Geometry
5
+
6
+ =begin rdoc
7
+ Circles come in all shapes and sizes, but they're usually round.
8
+
9
+ == Usage
10
+ circle = Geometry::Circle.new [1,2], 3
11
+ circle = Geometry::Circle.new center:[1,2], radius:3
12
+ circle = Geometry::Circle.new center:[1,2], diameter:6
13
+ circle = Geometry::Circle.new diameter:6
14
+ =end
15
+
16
+ class Circle
17
+ include ClusterFactory
18
+
19
+ # @return [Point] The {Circle}'s center point
20
+ attr_reader :center
21
+
22
+ # @return [Number] The {Circle}'s radius
23
+ attr_reader :radius
24
+
25
+ # @overload new(center, radius)
26
+ # Construct a {Circle} using a centerpoint and radius
27
+ # @param [Point] center The center point of the {Circle}
28
+ # @param [Number] radius The radius of the {Circle}
29
+ # @overload new(center, radius)
30
+ # Construct a circle using named center and radius parameters
31
+ # @option options [Point] :center (PointZero)
32
+ # @option options [Number] :radius
33
+ # @overload new(center, diameter)
34
+ # Construct a circle using named center and diameter parameters
35
+ # @option options [Point] :center (PointZero)
36
+ # @option options [Number] :diameter
37
+ def self.new(*args, &block)
38
+ options, args = args.partition {|a| a.is_a? Hash}
39
+ options = options.reduce({}, :merge)
40
+ center, radius = args[0..1]
41
+
42
+ center ||= (options[:center] || PointZero.new)
43
+ radius ||= options[:radius]
44
+
45
+ if radius
46
+ self.allocate.tap {|circle| circle.send :initialize, center, radius, &block }
47
+ elsif options.has_key?(:diameter)
48
+ CenterDiameterCircle.new center, options[:diameter], &block
49
+ else
50
+ raise ArgumentError, "Circle.new requires a radius or a diameter"
51
+ end
52
+ end
53
+
54
+ # Construct a new {Circle} from a centerpoint and radius
55
+ # @param [Point] center The center point of the {Circle}
56
+ # @param [Number] radius The radius of the {Circle}
57
+ # @return [Circle] A new {Circle} object
58
+ def initialize(center, radius)
59
+ @center = Point[center]
60
+ @radius = radius
61
+ end
62
+
63
+ def eql?(other)
64
+ (self.center == other.center) && (self.radius == other.radius)
65
+ end
66
+ alias :== :eql?
67
+
68
+ # @!group Accessors
69
+ # @return [Rectangle] The smallest axis-aligned {Rectangle} that bounds the receiver
70
+ def bounds
71
+ return Rectangle.new(self.min, self.max)
72
+ end
73
+
74
+ # @!attribute [r] diameter
75
+ # @return [Numeric] The diameter of the {Circle}
76
+ def diameter
77
+ @radius*2
78
+ end
79
+
80
+ # @return [Point] The upper right corner of the bounding {Rectangle}
81
+ def max
82
+ @center+radius
83
+ end
84
+
85
+ # @return [Point] The lower left corner of the bounding {Rectangle}
86
+ def min
87
+ @center-radius
88
+ end
89
+
90
+ # @return [Array<Point>] The lower left and upper right corners of the bounding {Rectangle}
91
+ def minmax
92
+ [self.min, self.max]
93
+ end
94
+ # @!endgroup
95
+ end
96
+
97
+ class CenterDiameterCircle < Circle
98
+ # @return [Number] The {Circle}'s diameter
99
+ attr_reader :diameter
100
+
101
+ # Construct a new {Circle} from a centerpoint and a diameter
102
+ # @param [Point] center The center point of the {Circle}
103
+ # @param [Number] diameter The radius of the {Circle}
104
+ # @return [Circle] A new {Circle} object
105
+ def initialize(center, diameter)
106
+ @center = Point[center]
107
+ @diameter = diameter
108
+ end
109
+
110
+ def eql?(other)
111
+ (self.center == other.center) && (self.diameter == other.diameter)
112
+ end
113
+ alias :== :eql?
114
+
115
+ # @!group Accessors
116
+ # @return [Number] The {Circle}'s radius
117
+ def radius
118
+ @diameter/2
119
+ end
120
+ # @!endgroup
121
+ end
122
+ end