bresenham 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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bresenham.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Sean McCarthy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ # Bresenham
2
+
3
+ A set of functions implementing Bresenham's algorithm for lines and circles.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'bresenham'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install bresenham
18
+
19
+ ## Usage
20
+
21
+ require 'bresenham'
22
+ # x_start, y_start, x_end, y_end
23
+ line_points_set = Bresenham::Line::coordinates(0, 0, 3, 10)
24
+
25
+ # x_origin, y_origin, radius
26
+ circle_points_set = Bresenham::Circle::coordinates(0, 0, 10)
27
+
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = "test/*.rb"
7
+ end
@@ -0,0 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/bresenham/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Sean McCarthy"]
6
+ gem.email = ["sean@clanmccarthy.net"]
7
+ gem.description = %q{Implementation of Bresenham's algorithm for lines and circles. Functions return sets of coordinates that can be used for plotting.}
8
+ gem.summary = %q{Implementation of Bresenham's algorithm for lines and circles.}
9
+ gem.homepage = "https://github.com/seandmccarthy/bresenham"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "bresenham"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Bresenham::VERSION
17
+ end
@@ -0,0 +1,34 @@
1
+ class ASCIIPlot
2
+
3
+ DOT = '.'
4
+ EMPTY = ' '
5
+ X_AXIS = '-'
6
+ Y_AXIS = '|'
7
+
8
+ def initialize(x_start, x_end, y_start, y_end)
9
+ @x_start = x_start
10
+ @x_end = x_end
11
+ @y_start = y_start
12
+ @y_end = y_end
13
+ end
14
+
15
+ def plot(point_list)
16
+ output = ''
17
+ @y_end.downto(@y_start).each do |y|
18
+ (@x_start..@x_end).each do |x|
19
+ if point_list.include?([x,y])
20
+ output << DOT
21
+ elsif x == 0
22
+ output << Y_AXIS
23
+ elsif y == 0
24
+ output << X_AXIS
25
+ else
26
+ output << EMPTY
27
+ end
28
+ end
29
+ output << "\n"
30
+ end
31
+ output
32
+ end
33
+
34
+ end
@@ -0,0 +1,8 @@
1
+ require "bresenham/version"
2
+ require "bresenham/circle"
3
+ require "bresenham/line"
4
+ require 'set'
5
+
6
+ module Bresenham
7
+
8
+ end
@@ -0,0 +1,89 @@
1
+ module Bresenham
2
+ module Circle
3
+ def self.coordinates(xm, ym, radius)
4
+ x = -radius
5
+ y = 0
6
+ err = 2-2*radius
7
+ coords = Set.new
8
+
9
+ begin
10
+ coords << [xm + x, ym - y]
11
+ coords << [xm - x, ym + y]
12
+ coords << [xm + y, ym + x]
13
+ coords << [xm - y, ym - x]
14
+ radius = err
15
+ if radius <= y
16
+ y += 1
17
+ err += y * 2 + 1
18
+ end
19
+ if radius > x or err > y
20
+ x += 1
21
+ err += x * 2 + 1
22
+ end
23
+ end while (x < 0)
24
+ coords
25
+ end
26
+
27
+ def self.coordinates2(x0, y0, r)
28
+ p = 3 - 2 * r
29
+ x = 0
30
+ y = r
31
+ coords = Set.new
32
+
33
+ while (y >= x)
34
+ coords << [x0 + x, y0 + y]
35
+ coords << [x0 + x, y0 - y]
36
+ coords << [x0 - x, y0 + y]
37
+ coords << [x0 - x, y0 - y]
38
+ coords << [x0 + y, y0 + x]
39
+ coords << [x0 + y, y0 - x]
40
+ coords << [x0 - y, y0 + x]
41
+ coords << [x0 - y, y0 - x]
42
+ if (p < 0)
43
+ p += 4*x + 6
44
+ x += 1
45
+ else
46
+ p += 4*(x - y) + 10
47
+ x += 1
48
+ y -= 1
49
+ end
50
+ end
51
+ coords
52
+ end
53
+
54
+ def self.midpoint_algorithm(x0, y0, radius)
55
+ f = 1 - radius
56
+ ddF_x = 1
57
+ ddF_y = -2 * radius
58
+ x = 0
59
+ y = radius
60
+ coords = Set.new
61
+
62
+ coords << [x0, y0 + radius]
63
+ coords << [x0, y0 - radius]
64
+ coords << [x0 + radius, y0]
65
+ coords << [x0 - radius, y0]
66
+
67
+ while x < y
68
+ if f >= 0
69
+ y -= 1
70
+ ddF_y += 2
71
+ f += ddF_y
72
+ end
73
+ x += 1
74
+ ddF_x += 2;
75
+ f += ddF_x;
76
+ coords << [x0 + x, y0 + y]
77
+ coords << [x0 - x, y0 + y]
78
+ coords << [x0 + x, y0 - y]
79
+ coords << [x0 - x, y0 - y]
80
+ coords << [x0 + y, y0 + x]
81
+ coords << [x0 - y, y0 + x]
82
+ coords << [x0 + y, y0 - x]
83
+ coords << [x0 - y, y0 - x]
84
+ end
85
+ coords
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,26 @@
1
+ module Bresenham
2
+ module Line
3
+ def self.coordinates(x0, y0, x1, y1)
4
+ dx = (x1 - x0).abs
5
+ dy = -(y1 - y0).abs
6
+ step_x = x0 < x1 ? 1 : -1
7
+ step_y = y0 < y1 ? 1 : -1
8
+ err = dx + dy
9
+
10
+ coords = Set.new [[x0, y0]]
11
+ begin
12
+ e2 = 2*err;
13
+ if e2 >= dy
14
+ err += dy
15
+ x0 += step_x
16
+ end
17
+ if e2 <= dx
18
+ err += dx
19
+ y0 += step_y
20
+ end
21
+ coords << [x0, y0]
22
+ end until (x0 == x1 && y0 == y1)
23
+ coords
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Bresenham
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,174 @@
1
+ require 'minitest/autorun'
2
+ require 'bresenham'
3
+ require 'ascii_plot'
4
+
5
+ class TestASCIIPlot < MiniTest::Unit::TestCase
6
+
7
+ def test_short_line_plot
8
+ expected = <<EOP
9
+ |
10
+ |
11
+ |
12
+ |
13
+ |
14
+ |
15
+ |
16
+ | ..
17
+ | ....
18
+ | ...
19
+ ..---------
20
+ EOP
21
+ plot = ASCIIPlot.new(0, 10, 0, 10)
22
+ output = plot.plot Bresenham::Line::coordinates(0, 0, 10, 3)
23
+ assert_equal output, expected
24
+ end
25
+
26
+ def test_long_line_plot
27
+ expected = <<EOP
28
+ | .
29
+ | .
30
+ | .
31
+ | .
32
+ | .
33
+ | .
34
+ | .
35
+ | .
36
+ | .
37
+ | .
38
+ ----------|--.-------
39
+ | .
40
+ |.
41
+ .
42
+ .
43
+ .|
44
+ . |
45
+ . |
46
+ . |
47
+ . |
48
+ . |
49
+ EOP
50
+ plot = ASCIIPlot.new(-10, 10, -10, 10)
51
+ output = plot.plot Bresenham::Line::coordinates(-5, -10, 10, 10)
52
+ assert_equal output, expected
53
+ end
54
+
55
+ def test_small_circle_plot
56
+ expected = <<EOP
57
+ ...
58
+ . | .
59
+ . | .
60
+ . | .
61
+ .---|---.
62
+ . | .
63
+ . | .
64
+ . | .
65
+ ...
66
+ EOP
67
+ plot = ASCIIPlot.new(-4, 4, -4, 4)
68
+ output = plot.plot Bresenham::Circle::coordinates(0, 0, 4)
69
+ assert_equal output, expected
70
+ end
71
+
72
+ def test_mid_circle_plot
73
+ expected = <<EOP
74
+ .....
75
+ .. | ..
76
+ . | .
77
+ . | .
78
+ . | .
79
+ . | .
80
+ . | .
81
+ . | .
82
+ .-------|-------.
83
+ . | .
84
+ . | .
85
+ . | .
86
+ . | .
87
+ . | .
88
+ . | .
89
+ .. | ..
90
+ .....
91
+ EOP
92
+ plot = ASCIIPlot.new(-8, 8, -8, 8)
93
+ output = plot.plot Bresenham::Circle::coordinates(0, 0, 8)
94
+ assert_equal output, expected
95
+ end
96
+
97
+ def test_large_circle_plot
98
+ expected = <<EOP
99
+ .........
100
+ ... | ...
101
+ .. | ..
102
+ .. | ..
103
+ . | .
104
+ . | .
105
+ . | .
106
+ . | .
107
+ . | .
108
+ . | .
109
+ . | .
110
+ . | .
111
+ . | .
112
+ . | .
113
+ . | .
114
+ . | .
115
+ . | .
116
+ . | .
117
+ . | .
118
+ . | .
119
+ .-------------------|-------------------.
120
+ . | .
121
+ . | .
122
+ . | .
123
+ . | .
124
+ . | .
125
+ . | .
126
+ . | .
127
+ . | .
128
+ . | .
129
+ . | .
130
+ . | .
131
+ . | .
132
+ . | .
133
+ . | .
134
+ . | .
135
+ . | .
136
+ .. | ..
137
+ .. | ..
138
+ ... | ...
139
+ .........
140
+ EOP
141
+ plot = ASCIIPlot.new(-20, 20, -20, 20)
142
+ output = plot.plot Bresenham::Circle::coordinates(0, 0, 20)
143
+ assert_equal output, expected
144
+ end
145
+
146
+ def test_non_zero_origin_plot
147
+ expected = <<EOP
148
+ . |
149
+ . |
150
+ . |
151
+ . |
152
+ . |
153
+ . |
154
+ . |
155
+ . |
156
+ . |
157
+ . |
158
+ ------.---|----------
159
+ . |
160
+ . |
161
+ .|
162
+ .. ..
163
+ | .......
164
+ |
165
+ |
166
+ |
167
+ |
168
+ |
169
+ EOP
170
+ plot = ASCIIPlot.new(-10, 10, -10, 10)
171
+ output = plot.plot Bresenham::Circle::coordinates(5, 5, 10)
172
+ assert_equal output, expected
173
+ end
174
+ end
@@ -0,0 +1,26 @@
1
+ require 'minitest/autorun'
2
+ require 'bresenham'
3
+
4
+ class TestBresenham < MiniTest::Unit::TestCase
5
+
6
+ def test_unit_circle
7
+ expected = [[-1, 0], [0, -1], [0, 1], [1, 0]]
8
+ assert_equal Bresenham::Circle::coordinates(0, 0, 1).to_a.sort, expected
9
+ end
10
+
11
+ def test_odd_radius
12
+ expected = [[-3, -1], [-3, 0], [-3, 1], [-2, -2], [-2, 2], [-1, -3], [-1, 3], [0, -3], [0, 3], [1, -3], [1, 3], [2, -2], [2, 2], [3, -1], [3, 0], [3, 1]]
13
+ assert_equal Bresenham::Circle::coordinates(0, 0, 3).to_a.sort, expected
14
+ end
15
+
16
+ def test_even_radius
17
+ expected = [[-4, -1], [-4, 0], [-4, 1], [-3, -2], [-3, 2], [-2, -3], [-2, 3], [-1, -4], [-1, 4], [0, -4], [0, 4], [1, -4], [1, 4], [2, -3], [2, 3], [3, -2], [3, 2], [4, -1], [4, 0], [4, 1]]
18
+ assert_equal Bresenham::Circle::coordinates(0, 0, 4).to_a.sort, expected
19
+ end
20
+
21
+ def test_non_zero_origin
22
+ expected = [[-6, -3], [-6, -2], [-6, -1], [-5, -4], [-5, 0], [-4, -5], [-4, 1], [-3, -6], [-3, 2], [-2, -6], [-2, 2], [-1, -6], [-1, 2], [0, -5], [0, 1], [1, -4], [1, 0], [2, -3], [2, -2], [2, -1]]
23
+ assert_equal Bresenham::Circle::coordinates(-2, -2, 4).to_a.sort, expected
24
+ end
25
+
26
+ end
@@ -0,0 +1,31 @@
1
+ require 'minitest/autorun'
2
+ require 'bresenham'
3
+
4
+ class TestBresenhamLine < MiniTest::Unit::TestCase
5
+
6
+ def test_horizontal
7
+ expected = [[0, 0], [1, 0], [2, 0]]
8
+ assert_equal Bresenham::Line::coordinates(0, 0, 2, 0).to_a, expected
9
+ end
10
+
11
+ def test_diagonal
12
+ expected = [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5]]
13
+ assert_equal Bresenham::Line::coordinates(0, 0, 5, 5).to_a, expected
14
+ end
15
+
16
+ def test_30_degrees
17
+ expected = [[0, 0], [1, 0], [2, 1], [3, 1], [4, 1], [5, 2], [6, 2], [7, 2], [8, 2], [9, 3], [10, 3]]
18
+ assert_equal Bresenham::Line::coordinates(0, 0, 10, 3).to_a, expected
19
+ end
20
+
21
+ def test_30_degress_backwards
22
+ expected = [[10, 3], [9, 3], [8, 2], [7, 2], [6, 2], [5, 1], [4, 1], [3, 1], [2, 1], [1, 0], [0, 0]]
23
+ assert_equal Bresenham::Line::coordinates(10, 3, 0, 0).to_a, expected
24
+ end
25
+
26
+ def test_negative_axis
27
+ expected = [[1, 3], [1, 2], [0, 1], [0, 0], [0, -1], [-1, -2], [-1, -3]]
28
+ assert_equal Bresenham::Line::coordinates(1, 3, -1, -3).to_a, expected
29
+ end
30
+
31
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bresenham
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sean McCarthy
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-14 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Implementation of Bresenham's algorithm for lines and circles. Functions
15
+ return sets of coordinates that can be used for plotting.
16
+ email:
17
+ - sean@clanmccarthy.net
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE
25
+ - README.md
26
+ - Rakefile
27
+ - bresenham.gemspec
28
+ - lib/ascii_plot.rb
29
+ - lib/bresenham.rb
30
+ - lib/bresenham/circle.rb
31
+ - lib/bresenham/line.rb
32
+ - lib/bresenham/version.rb
33
+ - test/ascii_plot_test.rb
34
+ - test/circle_test.rb
35
+ - test/line_test.rb
36
+ homepage: https://github.com/seandmccarthy/bresenham
37
+ licenses: []
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubyforge_project:
56
+ rubygems_version: 1.8.15
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: Implementation of Bresenham's algorithm for lines and circles.
60
+ test_files:
61
+ - test/ascii_plot_test.rb
62
+ - test/circle_test.rb
63
+ - test/line_test.rb