openscad-text 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/openscad-text/text.rb +33 -75
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f135ca27a17a3fe7cb2cfdf46c1523b03f309ef0
|
4
|
+
data.tar.gz: 858a02acf97aeed8d7e7cf1fac8f3975e96dbe72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 180046888ad588d800db4f4ca2b3b3a0c54f254d674e21cb62fcd128d525790bbd26333183f1ac4d4d3a5cac4deefa50c121cd05868dce109673cb38b1390f5e
|
7
|
+
data.tar.gz: a8dd610d9c7d493fd95f8872fc9a23ed1dd5e764848b76b95f77efdb4edf424126d66b19375c197d6d36ca9fb48b64d4cc6be9c6d547e502c9ebcca15924c40b
|
data/lib/openscad-text/text.rb
CHANGED
@@ -1,32 +1,3 @@
|
|
1
|
-
class Text
|
2
|
-
# This yields 8 vectors turned counter-clockwise 45 degrees each
|
3
|
-
class TurnVector
|
4
|
-
include Enumerable
|
5
|
-
VECTORS = [
|
6
|
-
Vector[-1, 0],
|
7
|
-
Vector[-1,-1],
|
8
|
-
Vector[ 0,-1],
|
9
|
-
Vector[ 1,-1],
|
10
|
-
Vector[ 1, 0],
|
11
|
-
Vector[ 1, 1],
|
12
|
-
Vector[ 0, 1],
|
13
|
-
Vector[-1, 1],
|
14
|
-
].freeze
|
15
|
-
|
16
|
-
def initialize(state)
|
17
|
-
@state = VECTORS.find_index Vector[*state]
|
18
|
-
end
|
19
|
-
|
20
|
-
def each
|
21
|
-
VECTORS.length.times do
|
22
|
-
@state = 0 if @state >= VECTORS.length
|
23
|
-
yield VECTORS[@state]
|
24
|
-
@state += 1
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
1
|
# Represents a Text with a font
|
31
2
|
class Text
|
32
3
|
include Magick
|
@@ -96,28 +67,44 @@ class Text
|
|
96
67
|
].uniq - [[x,y]]
|
97
68
|
end
|
98
69
|
|
99
|
-
|
100
|
-
|
101
|
-
|
70
|
+
# finds next point in chain from current point
|
71
|
+
def find_next_point(current)
|
72
|
+
# 8 vectors turned counter-clockwise 45 degrees each
|
73
|
+
vecs = [
|
74
|
+
Vector[-1, 0],
|
75
|
+
Vector[-1,-1],
|
76
|
+
Vector[ 0,-1],
|
77
|
+
Vector[ 1,-1],
|
78
|
+
Vector[ 1, 0],
|
79
|
+
Vector[ 1, 1],
|
80
|
+
Vector[ 0, 1],
|
81
|
+
Vector[-1, 1],
|
82
|
+
]
|
102
83
|
|
103
|
-
#
|
104
|
-
|
84
|
+
# color of the last pixel
|
85
|
+
last_color = @matrix[*(Vector[*current]+vecs.last).to_a]
|
105
86
|
|
106
87
|
# turn the vector and find each which touches a white pixel
|
107
|
-
last = :black
|
108
88
|
touchy_vecs = vecs.map.with_index do |vec,i|
|
109
|
-
|
110
|
-
color_changed =
|
111
|
-
|
112
|
-
|
89
|
+
current_color = @matrix[*(Vector[*current]+vec).to_a]
|
90
|
+
color_changed = current_color != last_color
|
91
|
+
last_color = current_color
|
92
|
+
|
93
|
+
# return a vec or nil
|
113
94
|
if color_changed
|
114
95
|
# return the black point of the two touching the borderline
|
115
|
-
|
96
|
+
if current_color == :black
|
97
|
+
vec
|
98
|
+
else
|
99
|
+
# the one before vec, if i==0 the last one is the one before
|
100
|
+
i-1 >= 0 ? vecs[i-1] : vecs.last
|
101
|
+
end
|
116
102
|
end
|
117
103
|
end
|
118
104
|
|
119
105
|
#remove nil(s) and duplicates
|
120
|
-
touchy_vecs.compact
|
106
|
+
touchy_vecs.compact!
|
107
|
+
touchy_vecs.uniq!
|
121
108
|
|
122
109
|
# possible next points
|
123
110
|
touchy_points = touchy_vecs.map { |vec| (Vector[*current] + vec).to_a }
|
@@ -129,45 +116,17 @@ class Text
|
|
129
116
|
touchy_points[0]
|
130
117
|
end
|
131
118
|
|
132
|
-
# finds one possible last point from current_point
|
133
|
-
def find_last_point(current_point)
|
134
|
-
t = TurnVector.new([-1,-1]).to_a
|
135
|
-
|
136
|
-
# ary with bools true for :black, false for :white
|
137
|
-
is_black = t.map { |vec| @matrix[*(Vector[*current_point]+vec).to_a] == :black }
|
138
|
-
|
139
|
-
possible_vecs = []
|
140
|
-
is_black.each_cons(2).with_index do |cons,i|
|
141
|
-
a,b = cons
|
142
|
-
if ! a and b
|
143
|
-
possible_vecs << t[i+1]
|
144
|
-
elsif a and ! b
|
145
|
-
possible_vecs << t[i]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# corner cases for [false, false, true, true]
|
150
|
-
# and [true, true, false, false]
|
151
|
-
# then the first/last one is also a border point
|
152
|
-
possible_vecs << t.first if ! is_black.first and is_black.last
|
153
|
-
possible_vecs << t.last if is_black.first and ! is_black.last
|
154
|
-
|
155
|
-
# return last point
|
156
|
-
(possible_vecs.first + Vector[*current_point]).to_a
|
157
|
-
end
|
158
|
-
|
159
119
|
# starting with point(x,y), try to create a path (or chain)
|
160
120
|
# until the starting point is reached again
|
161
121
|
def create_pixel_chain(x,y)
|
162
122
|
# can't create a chain if the point is invalid
|
163
123
|
return if point_invalid?(x,y)
|
164
124
|
|
165
|
-
# create a new ary in the
|
125
|
+
# create a new ary in the paths ary
|
166
126
|
@paths << []
|
167
127
|
|
168
128
|
# setup state
|
169
129
|
current_point = [x,y]
|
170
|
-
last_point = find_last_point(current_point)
|
171
130
|
|
172
131
|
while current_point
|
173
132
|
# add the point to the points array
|
@@ -177,9 +136,7 @@ class Text
|
|
177
136
|
@paths.last << @points.count - 1
|
178
137
|
|
179
138
|
# try to find next point (nil if none was found)
|
180
|
-
|
181
|
-
last_point = current_point
|
182
|
-
current_point = next_point
|
139
|
+
current_point = find_next_point(current_point)
|
183
140
|
end
|
184
141
|
end
|
185
142
|
|
@@ -196,15 +153,16 @@ class Text
|
|
196
153
|
@points = []
|
197
154
|
@paths = []
|
198
155
|
|
199
|
-
# create a matrix from pixels
|
156
|
+
# draw an image of the text and create a matrix from its pixels
|
200
157
|
@matrix = create_image.pixel_matrix
|
201
158
|
|
202
159
|
# go through each point aka pixel to make sure it gets used once
|
160
|
+
# and try to retrace the letters
|
203
161
|
@matrix.each_with_index do |_,x,y|
|
204
162
|
create_pixel_chain(x,y)
|
205
163
|
end
|
206
164
|
|
207
|
-
# align
|
165
|
+
# align them!
|
208
166
|
align_points
|
209
167
|
|
210
168
|
# finished woop woop
|