jenncad 1.0.0.pre.alpha8 → 1.0.0.pre.alpha9
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 +4 -4
- data/lib/jenncad/features/aggregation.rb +1 -0
- data/lib/jenncad/features/path.rb +339 -0
- data/lib/jenncad/features.rb +2 -0
- data/lib/jenncad/primitives/subtract_object.rb +0 -1
- data/lib/jenncad/thing.rb +11 -11
- data/lib/jenncad/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93ed5b4cc8c786d306d9fbaa7c0518a607b20c76f08538a0882584ec34955ac4
|
4
|
+
data.tar.gz: 5394a9131feb628a3d8f4a1d099ce75b104d0f0674c4dbb9d57db19fc555486a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29deaf817dfce550a7a3038454ddbca39c520ae1964526f7f7ebcf06edca9dbe056ec13d1f84e4390d3dbe0f043324f48c220e8bcb5a38e201b47853603bcca2
|
7
|
+
data.tar.gz: c4e3a0e515ad6586fbc9919a6f0608375bf4d2babf21b8de202b308227050fae25e3db2d44ca0f4271c67854d9f57508aa5dbf04c576d562b6515ed9da6419d4
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module JennCad
|
2
|
+
class RoundCorner
|
3
|
+
attr_accessor :start_point, :end_point, :input_a, :output_a, :a, :l, :od, :id, :thing, :angle, :current_angle, :direction, :from, :ccw
|
4
|
+
def initialize(args, &thing)
|
5
|
+
@start_point = args[:start_point]
|
6
|
+
@end_point = args[:end_point]
|
7
|
+
@a = args[:a]
|
8
|
+
@ccw = args[:ccw] || false
|
9
|
+
@l = args[:l]
|
10
|
+
@od = args[:od]
|
11
|
+
@id = args[:id]
|
12
|
+
@input_a = args[:input_a] || 0
|
13
|
+
@output_a = args[:output_a] || 0
|
14
|
+
@thing = thing
|
15
|
+
@angle = args[:angle]
|
16
|
+
@current_angle = args[:current_angle]
|
17
|
+
@direction = args[:direction]
|
18
|
+
@to = args[:to]
|
19
|
+
@from = args[:from]
|
20
|
+
|
21
|
+
if @a < 0
|
22
|
+
@from = case @from
|
23
|
+
when :left
|
24
|
+
:right
|
25
|
+
when :right
|
26
|
+
:left
|
27
|
+
when :top, :up
|
28
|
+
:bottom
|
29
|
+
when :down, :bottom
|
30
|
+
:up
|
31
|
+
else
|
32
|
+
# // unimplemented
|
33
|
+
@from
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_angles(cur, total, direction)
|
40
|
+
@current_angle = cur
|
41
|
+
@angle = normalize(total)
|
42
|
+
@direction = direction
|
43
|
+
end
|
44
|
+
|
45
|
+
def normalize(angle)
|
46
|
+
if angle < 0
|
47
|
+
angle += 360
|
48
|
+
end
|
49
|
+
if angle >= 360
|
50
|
+
angle -= 360
|
51
|
+
end
|
52
|
+
angle
|
53
|
+
end
|
54
|
+
|
55
|
+
def margin
|
56
|
+
return @od
|
57
|
+
end
|
58
|
+
|
59
|
+
def positions
|
60
|
+
td = thing.yield.d || thing.yield.y
|
61
|
+
unless td
|
62
|
+
puts "ERROR: cannot find diameter or y of thing #{thing.yield.inspect}"
|
63
|
+
return
|
64
|
+
end
|
65
|
+
l = td + @id
|
66
|
+
l2 = td / 2.0 + @id / 2.0
|
67
|
+
r = 0
|
68
|
+
ox = 0
|
69
|
+
oy = 0
|
70
|
+
cr = 180
|
71
|
+
case @from
|
72
|
+
when :left
|
73
|
+
r = 0
|
74
|
+
oy = -l
|
75
|
+
when :top, :up
|
76
|
+
r = -90
|
77
|
+
ox = -l
|
78
|
+
cr = 0
|
79
|
+
when :right
|
80
|
+
r = 180
|
81
|
+
oy = l
|
82
|
+
when :bottom, :down
|
83
|
+
cr = 0
|
84
|
+
r = 90
|
85
|
+
ox = l
|
86
|
+
# TODO: so this doesn't work yet,
|
87
|
+
# need to figure out the maths to translate this
|
88
|
+
when 0..360
|
89
|
+
r = 180-@from
|
90
|
+
cr = @a
|
91
|
+
end
|
92
|
+
|
93
|
+
r2 = cr + r + @a # 180+@a
|
94
|
+
x = - l2 * Math::sin((r2/180.0)*Math::PI)
|
95
|
+
y = - l2 * Math::cos((r2/180.0)*Math::PI)
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
return r, ox/2.0, oy/2.0, x, y
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def part
|
104
|
+
d = thing.yield.d
|
105
|
+
len = d * 2 + @id
|
106
|
+
x = Math::sin((@a/180.0)*Math::PI)*len
|
107
|
+
y = Math::cos((@a/180.0)*Math::PI)*len
|
108
|
+
|
109
|
+
res = circle(d: len)
|
110
|
+
res -= circle(d: @id)
|
111
|
+
points = [[0,0]]
|
112
|
+
points << [0, len]
|
113
|
+
points << [x, y]
|
114
|
+
|
115
|
+
res *= polygon(points:points)
|
116
|
+
|
117
|
+
r, ox, oy, x, y = positions
|
118
|
+
res = res.rotate(z: r).move(x: ox, y: oy)
|
119
|
+
res = res.auto_extrude#.color("red")
|
120
|
+
|
121
|
+
#res += slot(d: 1.2, y: len/2.0, h: 10).rotate(z: r_midpoint).color("red")
|
122
|
+
#res += cylinder(d: 1, h: 10).move(x: x+ox,y: y+oy)
|
123
|
+
|
124
|
+
#res.moveh(x: thing.yield.d, y: -thing.yield.d)
|
125
|
+
res.move(x: @start_point[:x], y: @start_point[:y])
|
126
|
+
|
127
|
+
#res += cylinder(d: 1, h: 15).color("red").move(x: @start_point[:x], y: @start_point[:y]).move(z:-1)
|
128
|
+
|
129
|
+
|
130
|
+
res
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
class Line
|
137
|
+
attr_accessor :start_point, :end_point, :l, :thing, :angle, :current_angle, :direction
|
138
|
+
def initialize(args, &thing)
|
139
|
+
@start_point = args[:start_point]
|
140
|
+
@end_point = args[:end_point]
|
141
|
+
@angle = args[:angle]
|
142
|
+
@current_angle = args[:current_angle]
|
143
|
+
@direction = args[:direction]
|
144
|
+
@l = args[:l]
|
145
|
+
@thing = thing
|
146
|
+
end
|
147
|
+
|
148
|
+
def sp_margin(margin)
|
149
|
+
@start_point[:x] -= margin[:x]
|
150
|
+
@start_point[:y] -= margin[:y]
|
151
|
+
end
|
152
|
+
|
153
|
+
def ep_margin(margin)
|
154
|
+
@end_point[:x] -= margin[:x]
|
155
|
+
@end_point[:y] -= margin[:y]
|
156
|
+
end
|
157
|
+
|
158
|
+
def shrink_ep(len)
|
159
|
+
sx, sy = @start_point[:x], @start_point[:y]
|
160
|
+
ex, ey = @end_point[:x], @end_point[:y]
|
161
|
+
vx = ex-sx
|
162
|
+
vy = ey-sy
|
163
|
+
l = Math::sqrt(vx**2 + vy**2)
|
164
|
+
factor = len / l
|
165
|
+
@end_point[:x] -= vx * factor
|
166
|
+
@end_point[:y] -= vy * factor
|
167
|
+
#puts "#{sx} x #{sy} => #{ex} x #{ey} , shrink #{factor} "
|
168
|
+
end
|
169
|
+
|
170
|
+
def shrink_sp(len)
|
171
|
+
sx, sy = @start_point[:x], @start_point[:y]
|
172
|
+
ex, ey = @end_point[:x], @end_point[:y]
|
173
|
+
vx = ex-sx
|
174
|
+
vy = ey-sy
|
175
|
+
l = Math::sqrt(vx**2 + vy**2)
|
176
|
+
factor = len / l
|
177
|
+
@start_point[:x] -= vx * factor
|
178
|
+
@start_point[:y] -= vy * factor
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
def part
|
183
|
+
hull(
|
184
|
+
@thing.yield.move(x: @start_point[:x], y: @start_point[:y]),
|
185
|
+
@thing.yield.move(x: @end_point[:x], y: @end_point[:y])
|
186
|
+
)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class Path < Thing
|
191
|
+
|
192
|
+
attr_accessor :elements, :lpos, :thing, :angle, :current_angle, :direction
|
193
|
+
def initialize(args)
|
194
|
+
@thing = args[:part] #// cylinder(d: @d, z: @z)
|
195
|
+
@part = new_thing
|
196
|
+
@angle = args[:a] || 0
|
197
|
+
@current_angle = args[:a] || 0
|
198
|
+
@direction = 0
|
199
|
+
@name = args[:name] || "Path"
|
200
|
+
@calc_h = @part.z
|
201
|
+
@dir = 0
|
202
|
+
@lpos = {x: 0, y: 0, l: 0, a: 0}
|
203
|
+
@coords = []
|
204
|
+
@steps = []
|
205
|
+
@parts = [new_thing]
|
206
|
+
|
207
|
+
super(args)
|
208
|
+
end
|
209
|
+
|
210
|
+
def new_thing
|
211
|
+
r = @thing.clone
|
212
|
+
r.transformations = []
|
213
|
+
r
|
214
|
+
end
|
215
|
+
|
216
|
+
def corner(args)
|
217
|
+
od = args[:od]
|
218
|
+
id = args[:id]
|
219
|
+
if id.nil? && od
|
220
|
+
id = new_thing.d
|
221
|
+
#puts "od: #{od} , thing d #{new_thing.d} new id #{id}"
|
222
|
+
end
|
223
|
+
if od.nil? && id
|
224
|
+
od = id + new_thing.d
|
225
|
+
end
|
226
|
+
rc = RoundCorner.new(
|
227
|
+
start_point: { x: @lpos[:x], y: @lpos[:y] },
|
228
|
+
end_point: { x: @lpos[:x], y: @lpos[:y] },
|
229
|
+
od: od,
|
230
|
+
id: id,
|
231
|
+
ccw: args[:ccw],
|
232
|
+
from: args[:from],
|
233
|
+
to: args[:to],
|
234
|
+
a: args[:a],
|
235
|
+
direction: @direction
|
236
|
+
){ new_thing }
|
237
|
+
|
238
|
+
_, ox, oy, x, y = rc.positions
|
239
|
+
@lpos[:x] += x + ox
|
240
|
+
@lpos[:y] += y + oy
|
241
|
+
|
242
|
+
@steps << rc
|
243
|
+
end
|
244
|
+
|
245
|
+
def line(args)
|
246
|
+
if args[:l]
|
247
|
+
args[:a] ||= 0
|
248
|
+
if args[:a] > 0
|
249
|
+
@direction = 1
|
250
|
+
elsif args[:a] < 0
|
251
|
+
@direction = -1
|
252
|
+
else
|
253
|
+
@direction = 0
|
254
|
+
end
|
255
|
+
|
256
|
+
@angle += args[:a]
|
257
|
+
@current_angle = args[:a]
|
258
|
+
|
259
|
+
l = args[:l]
|
260
|
+
gamma = 90
|
261
|
+
alpha = @angle
|
262
|
+
beta = gamma - alpha
|
263
|
+
|
264
|
+
case
|
265
|
+
when alpha == 90, alpha == -270
|
266
|
+
x = l
|
267
|
+
y = 0
|
268
|
+
when alpha == 180, alpha == -180
|
269
|
+
x = 0
|
270
|
+
y = -l
|
271
|
+
when alpha == 270, alpha == -90
|
272
|
+
x = -l
|
273
|
+
y = 0
|
274
|
+
when alpha == 360, alpha == 0
|
275
|
+
x = 0
|
276
|
+
y = l
|
277
|
+
else
|
278
|
+
y = l/Math::sin(radians(gamma)) * Math::sin(radians(beta))
|
279
|
+
x = y/Math::sin(radians(beta)) * Math::sin(radians(alpha))
|
280
|
+
end
|
281
|
+
elsif args[:x] || args[:y]
|
282
|
+
x = args[:x] || 0
|
283
|
+
y = args[:y] || 0
|
284
|
+
|
285
|
+
dx = @lpos[:x] - x
|
286
|
+
dy = @lpos[:y] - y
|
287
|
+
|
288
|
+
l = Math::sqrt(dx*dx + dy*dy)
|
289
|
+
alpha = Math::atan2(x, y)*180/Math::PI
|
290
|
+
else
|
291
|
+
puts "Error in line(): Please specify either :l, :x or :y"
|
292
|
+
return
|
293
|
+
end
|
294
|
+
|
295
|
+
@steps << Line.new(start_point: { x: @lpos[:x], y: @lpos[:y] }, end_point: { x: @lpos[:x] + x, y: @lpos[:y] + y }, angle: @angle, current_angle: @current_angle, direction: @direction, l: l){ new_thing }
|
296
|
+
|
297
|
+
add_lpos({x: x, y: y})
|
298
|
+
end
|
299
|
+
|
300
|
+
def add_lpos(lpos)
|
301
|
+
#puts "x: #{lpos[:x]}, y: #{lpos[:y]}"
|
302
|
+
[:x, :y].each do |key|
|
303
|
+
@lpos[key] += lpos[key]
|
304
|
+
end
|
305
|
+
@coords << lpos
|
306
|
+
end
|
307
|
+
|
308
|
+
def pos
|
309
|
+
[@lpos[:x], @lpos[:y]]
|
310
|
+
end
|
311
|
+
|
312
|
+
def center
|
313
|
+
@steps << Move.new(x: @lpos[:x] * -1, y: @lpos[:y] * -1)
|
314
|
+
self
|
315
|
+
end
|
316
|
+
|
317
|
+
def assemble
|
318
|
+
@steps.each_with_index do |step, i|
|
319
|
+
if @steps[i+1] && @steps[i+1].class == Line && step.class == RoundCorner
|
320
|
+
step.set_angles(@steps[i+1].current_angle, @steps[i+1].angle, @steps[i+1].direction)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
res = nil
|
324
|
+
@steps.each do |step|
|
325
|
+
if step.kind_of? Transformation
|
326
|
+
res.transformations << step
|
327
|
+
else
|
328
|
+
res += step.part
|
329
|
+
end
|
330
|
+
end
|
331
|
+
set_heights_for_auto_extrude([res], self)
|
332
|
+
res.transformations << @transformations
|
333
|
+
Aggregation.new(@name, res)
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
|
data/lib/jenncad/features.rb
CHANGED
data/lib/jenncad/thing.rb
CHANGED
@@ -47,7 +47,7 @@ module JennCad
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def movei(args)
|
50
|
+
def movei(args={})
|
51
51
|
to = {}
|
52
52
|
[:x, :y, :z].each do |key|
|
53
53
|
if args[key]
|
@@ -162,7 +162,7 @@ module JennCad
|
|
162
162
|
return args
|
163
163
|
end
|
164
164
|
|
165
|
-
def move(args)
|
165
|
+
def move(args={})
|
166
166
|
if args.kind_of? Array
|
167
167
|
x,y,z = args
|
168
168
|
return move(x:x, y:y, z:z)
|
@@ -183,20 +183,20 @@ module JennCad
|
|
183
183
|
alias :translate :move
|
184
184
|
alias :m :move
|
185
185
|
|
186
|
-
def mx(v)
|
186
|
+
def mx(v=0)
|
187
187
|
move(x:v)
|
188
188
|
end
|
189
189
|
|
190
|
-
def my(v)
|
190
|
+
def my(v=0)
|
191
191
|
move(y:v)
|
192
192
|
end
|
193
193
|
|
194
|
-
def mz(v)
|
194
|
+
def mz(v=0)
|
195
195
|
move(z:v)
|
196
196
|
end
|
197
197
|
|
198
198
|
# move half
|
199
|
-
def moveh(args)
|
199
|
+
def moveh(args={})
|
200
200
|
if args.kind_of? Array
|
201
201
|
x,y,z = args
|
202
202
|
args = {x: x, y: y, z: z}
|
@@ -209,26 +209,26 @@ module JennCad
|
|
209
209
|
end
|
210
210
|
alias :mh :moveh
|
211
211
|
|
212
|
-
def mhx(v)
|
212
|
+
def mhx(v=0)
|
213
213
|
moveh(x:v)
|
214
214
|
end
|
215
215
|
|
216
|
-
def mhy(v)
|
216
|
+
def mhy(v=0)
|
217
217
|
moveh(y:v)
|
218
218
|
end
|
219
219
|
|
220
|
-
def mhz(v)
|
220
|
+
def mhz(v=0)
|
221
221
|
moveh(z:v)
|
222
222
|
end
|
223
223
|
|
224
|
-
def mirror(args)
|
224
|
+
def mirror(args={})
|
225
225
|
@transformations ||= []
|
226
226
|
@transformations << Mirror.new(args)
|
227
227
|
self
|
228
228
|
end
|
229
229
|
alias :mi :mirror
|
230
230
|
|
231
|
-
def scale(args)
|
231
|
+
def scale(args={})
|
232
232
|
if args.kind_of? Numeric or args.kind_of? Array
|
233
233
|
args = {v:args}
|
234
234
|
end
|
data/lib/jenncad/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jenncad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.alpha9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jennifer Glauche
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: geo3d
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/jenncad/features/cuttable.rb
|
116
116
|
- lib/jenncad/features/feature.rb
|
117
117
|
- lib/jenncad/features/openscad_include.rb
|
118
|
+
- lib/jenncad/features/path.rb
|
118
119
|
- lib/jenncad/features/stl_import.rb
|
119
120
|
- lib/jenncad/part.rb
|
120
121
|
- lib/jenncad/patches/array.rb
|