bresenham 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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