draught 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +4 -0
- data/.ruby-version +1 -0
- data/.travis.yml +19 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/draught.gemspec +28 -0
- data/lib/draught.rb +4 -0
- data/lib/draught/arc_builder.rb +161 -0
- data/lib/draught/bounding_box.rb +76 -0
- data/lib/draught/boxlike.rb +148 -0
- data/lib/draught/container.rb +39 -0
- data/lib/draught/corner.rb +163 -0
- data/lib/draught/cubic_bezier.rb +62 -0
- data/lib/draught/curve.rb +66 -0
- data/lib/draught/line.rb +272 -0
- data/lib/draught/path.rb +89 -0
- data/lib/draught/path_builder.rb +39 -0
- data/lib/draught/path_cleaner.rb +77 -0
- data/lib/draught/pathlike.rb +57 -0
- data/lib/draught/point.rb +53 -0
- data/lib/draught/pointlike.rb +35 -0
- data/lib/draught/renderer.rb +93 -0
- data/lib/draught/sheet.rb +45 -0
- data/lib/draught/sheet_builder.rb +144 -0
- data/lib/draught/transformations.rb +63 -0
- data/lib/draught/transformations/affine.rb +33 -0
- data/lib/draught/transformations/common.rb +21 -0
- data/lib/draught/transformations/composer.rb +51 -0
- data/lib/draught/transformations/composition.rb +31 -0
- data/lib/draught/transformations/proclike.rb +43 -0
- data/lib/draught/vector.rb +48 -0
- data/lib/draught/version.rb +3 -0
- metadata +153 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
require_relative 'point'
|
3
|
+
require_relative 'transformations/affine'
|
4
|
+
require_relative 'transformations/proclike'
|
5
|
+
require_relative 'transformations/composer'
|
6
|
+
|
7
|
+
module Draught
|
8
|
+
module Transformations
|
9
|
+
extend self
|
10
|
+
|
11
|
+
MM_TO_PT = 2.8346456692913
|
12
|
+
|
13
|
+
def mm_to_pt
|
14
|
+
Affine.new(Matrix[
|
15
|
+
[MM_TO_PT, 0, 0],
|
16
|
+
[0, MM_TO_PT, 0],
|
17
|
+
[0, 0, 1]
|
18
|
+
])
|
19
|
+
end
|
20
|
+
|
21
|
+
def x_axis_reflect
|
22
|
+
Affine.new(Matrix[
|
23
|
+
[1,0,0],
|
24
|
+
[0,-1,0],
|
25
|
+
[0,0,1]
|
26
|
+
])
|
27
|
+
end
|
28
|
+
|
29
|
+
def y_axis_reflect
|
30
|
+
Affine.new(Matrix[
|
31
|
+
[-1,0,0],
|
32
|
+
[0,1,0],
|
33
|
+
[0,0,1]
|
34
|
+
])
|
35
|
+
end
|
36
|
+
|
37
|
+
def xy_axis_reflect
|
38
|
+
Composer.compose(x_axis_reflect, y_axis_reflect)
|
39
|
+
end
|
40
|
+
|
41
|
+
def scale(factor)
|
42
|
+
Transformations::Affine.new(Matrix[
|
43
|
+
[factor, 0, 0],
|
44
|
+
[0, factor, 0],
|
45
|
+
[0, 0, 1]
|
46
|
+
])
|
47
|
+
end
|
48
|
+
|
49
|
+
def rotate(radians)
|
50
|
+
cos = Math.cos(radians)
|
51
|
+
sin = Math.sin(radians)
|
52
|
+
Transformations::Affine.new(Matrix[
|
53
|
+
[cos, -sin, 0],
|
54
|
+
[sin, cos, 0],
|
55
|
+
[0, 0, 1]
|
56
|
+
])
|
57
|
+
end
|
58
|
+
|
59
|
+
def round_to_n_decimal_places(n)
|
60
|
+
Proclike.new(->(p) { [p.x.round(n), p.y.round(n)] })
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
require_relative '../point'
|
3
|
+
|
4
|
+
module Draught
|
5
|
+
module Transformations
|
6
|
+
class Affine
|
7
|
+
include Common
|
8
|
+
|
9
|
+
attr_reader :transformation_matrix
|
10
|
+
|
11
|
+
def initialize(transformation_matrix)
|
12
|
+
@transformation_matrix = transformation_matrix
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(point)
|
16
|
+
Point.from_matrix(transformation_matrix * point.to_matrix)
|
17
|
+
end
|
18
|
+
|
19
|
+
def affine?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
other.respond_to?(:transformation_matrix) && other.transformation_matrix == transformation_matrix
|
25
|
+
end
|
26
|
+
|
27
|
+
def coalesce(other)
|
28
|
+
raise TypeError, "other must be a matrix-based Affine transform" unless other.affine?
|
29
|
+
self.class.new(other.transformation_matrix * self.transformation_matrix)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Draught
|
2
|
+
module Transformations
|
3
|
+
module Common
|
4
|
+
def call(point)
|
5
|
+
raise NotImplementedError, "Classes including Transformations::Common must implement #call, taking a Point and returning a new, transformed, Point"
|
6
|
+
end
|
7
|
+
|
8
|
+
def affine?
|
9
|
+
raise NotImplementedError, "Classes including Transformations::Common must implement #affine?"
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_transform
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def transforms
|
17
|
+
[self]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative './composition'
|
2
|
+
|
3
|
+
module Draught
|
4
|
+
module Transformations
|
5
|
+
class Composer
|
6
|
+
def self.compose(*transforms)
|
7
|
+
new(transforms).composition
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :transforms
|
11
|
+
|
12
|
+
def initialize(transforms)
|
13
|
+
@transforms = transforms
|
14
|
+
end
|
15
|
+
|
16
|
+
def composition
|
17
|
+
Composition.new(coalesced_transforms)
|
18
|
+
end
|
19
|
+
|
20
|
+
def coalesced_transforms
|
21
|
+
return [] if transforms.empty?
|
22
|
+
start_transforms = flattened_transforms
|
23
|
+
finished = start_transforms.shift(1)
|
24
|
+
return finished if start_transforms.empty?
|
25
|
+
|
26
|
+
start_transforms.each do |next_transform|
|
27
|
+
coalesce_pair(finished.pop, next_transform).each do |coalesced_transform|
|
28
|
+
finished << coalesced_transform
|
29
|
+
end
|
30
|
+
end
|
31
|
+
finished
|
32
|
+
end
|
33
|
+
|
34
|
+
def flattened_transforms
|
35
|
+
transforms.flat_map { |transform|
|
36
|
+
transform.to_transform.transforms
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def coalesce_pair(first, second)
|
43
|
+
begin
|
44
|
+
[first.coalesce(second)]
|
45
|
+
rescue TypeError
|
46
|
+
[first, second]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative './common'
|
2
|
+
|
3
|
+
module Draught
|
4
|
+
module Transformations
|
5
|
+
class Composition
|
6
|
+
include Transformations::Common
|
7
|
+
|
8
|
+
attr_reader :transforms
|
9
|
+
|
10
|
+
def initialize(transforms)
|
11
|
+
@transforms = transforms
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(point)
|
15
|
+
transforms.inject(point) { |result_point, transform| transform.call(result_point) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def affine?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_transform
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(other)
|
27
|
+
other.transforms == transforms
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative './common'
|
2
|
+
require_relative '../point'
|
3
|
+
|
4
|
+
module Draught
|
5
|
+
module Transformations
|
6
|
+
class Proclike
|
7
|
+
include Common
|
8
|
+
|
9
|
+
attr_reader :proclike
|
10
|
+
|
11
|
+
def initialize(proclike)
|
12
|
+
@proclike = proclike
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(point)
|
16
|
+
point_from_tuple_or_point(proclike.call(point))
|
17
|
+
end
|
18
|
+
|
19
|
+
def affine?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other)
|
24
|
+
other.respond_to?(:proclike) && proclike == other.proclike
|
25
|
+
end
|
26
|
+
|
27
|
+
def flattened_transforms
|
28
|
+
[self]
|
29
|
+
end
|
30
|
+
|
31
|
+
def coalesce(_)
|
32
|
+
raise TypeError, "non-Affine transforms cannot be coalesced"
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def point_from_tuple_or_point(tuple_or_point)
|
38
|
+
return Point.new(*tuple_or_point) if tuple_or_point.respond_to?(:each)
|
39
|
+
tuple_or_point
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
require_relative './transformations/affine'
|
3
|
+
require_relative './point'
|
4
|
+
|
5
|
+
module Draught
|
6
|
+
class Vector
|
7
|
+
def self.from_xy(x, y)
|
8
|
+
new(x, y)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.from_degrees_and_magnitude(degrees, magnitude)
|
12
|
+
radians = degrees * (Math::PI / 180)
|
13
|
+
from_radians_and_magnitude(radians, magnitude)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_radians_and_magnitude(radians, magnitude)
|
17
|
+
x = Math.cos(radians) * magnitude
|
18
|
+
y = Math.sin(radians) * magnitude
|
19
|
+
new(x, y)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.translation_to_zero(point)
|
23
|
+
translation_between(point, Point::ZERO)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.translation_between(point_1, point_2)
|
27
|
+
from_xy(point_2.x - point_1.x, point_2.y - point_1.y)
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :x, :y
|
31
|
+
|
32
|
+
def initialize(x, y)
|
33
|
+
@x, @y = x, y
|
34
|
+
end
|
35
|
+
|
36
|
+
def ==(other)
|
37
|
+
other.respond_to?(:to_transform) && other.x == x && other.y == y
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_transform
|
41
|
+
@transform ||= Transformations::Affine.new(
|
42
|
+
Matrix[[1, 0, x], [0, 1, y], [0, 0, 1]]
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
NULL = new(0,0)
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: draught
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Patterson
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: prawn
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- matt@reprocessed.org
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".ruby-version"
|
93
|
+
- ".travis.yml"
|
94
|
+
- CODE_OF_CONDUCT.md
|
95
|
+
- Gemfile
|
96
|
+
- Gemfile.lock
|
97
|
+
- LICENSE.txt
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- bin/console
|
101
|
+
- bin/setup
|
102
|
+
- draught.gemspec
|
103
|
+
- lib/draught.rb
|
104
|
+
- lib/draught/arc_builder.rb
|
105
|
+
- lib/draught/bounding_box.rb
|
106
|
+
- lib/draught/boxlike.rb
|
107
|
+
- lib/draught/container.rb
|
108
|
+
- lib/draught/corner.rb
|
109
|
+
- lib/draught/cubic_bezier.rb
|
110
|
+
- lib/draught/curve.rb
|
111
|
+
- lib/draught/line.rb
|
112
|
+
- lib/draught/path.rb
|
113
|
+
- lib/draught/path_builder.rb
|
114
|
+
- lib/draught/path_cleaner.rb
|
115
|
+
- lib/draught/pathlike.rb
|
116
|
+
- lib/draught/point.rb
|
117
|
+
- lib/draught/pointlike.rb
|
118
|
+
- lib/draught/renderer.rb
|
119
|
+
- lib/draught/sheet.rb
|
120
|
+
- lib/draught/sheet_builder.rb
|
121
|
+
- lib/draught/transformations.rb
|
122
|
+
- lib/draught/transformations/affine.rb
|
123
|
+
- lib/draught/transformations/common.rb
|
124
|
+
- lib/draught/transformations/composer.rb
|
125
|
+
- lib/draught/transformations/composition.rb
|
126
|
+
- lib/draught/transformations/proclike.rb
|
127
|
+
- lib/draught/vector.rb
|
128
|
+
- lib/draught/version.rb
|
129
|
+
homepage: https://github.com/fidothe/draught
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.6.11
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: A library for creating 2D vector graphics as PDF.
|
153
|
+
test_files: []
|