crystalscad 0.3.7 → 0.3.8
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.
- data/examples/openscad_examples/example001.rb +45 -0
- data/examples/openscad_examples/example002.rb +51 -0
- data/examples/openscad_examples/example003.rb +42 -0
- data/examples/openscad_examples/example004.rb +29 -0
- data/examples/openscad_examples/example005.rb +58 -0
- data/examples/printed_gear.rb +14 -0
- data/examples/threads2.rb +102 -0
- data/lib/crystalscad/Assembly.rb +18 -0
- data/lib/crystalscad/CrystalScad.rb +23 -3
- data/lib/crystalscad/Gears.rb +78 -2
- data/lib/crystalscad/ScrewThreads.rb +49 -4
- data/lib/crystalscad/version.rb +1 -1
- metadata +11 -4
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
size=50
|
7
|
+
hole=25
|
8
|
+
h = size * 2.5
|
9
|
+
|
10
|
+
res = sphere(d:size)
|
11
|
+
res -= cylinder(d:hole,h:h,center:true)
|
12
|
+
res -= cylinder(d:hole,h:h,center:true).rotate(x:90)
|
13
|
+
res -= cylinder(d:hole,h:h,center:true).rotate(y:90)
|
14
|
+
|
15
|
+
res.save("example001.scad")
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
=begin
|
20
|
+
module example001()
|
21
|
+
{
|
22
|
+
function r_from_dia(d) = d / 2;
|
23
|
+
|
24
|
+
module rotcy(rot, r, h) {
|
25
|
+
rotate(90, rot)
|
26
|
+
cylinder(r = r, h = h, center = true);
|
27
|
+
}
|
28
|
+
|
29
|
+
difference() {
|
30
|
+
sphere(r = r_from_dia(size));
|
31
|
+
rotcy([0, 0, 0], cy_r, cy_h);
|
32
|
+
rotcy([1, 0, 0], cy_r, cy_h);
|
33
|
+
rotcy([0, 1, 0], cy_r, cy_h);
|
34
|
+
}
|
35
|
+
|
36
|
+
size = 50;
|
37
|
+
hole = 25;
|
38
|
+
|
39
|
+
cy_r = r_from_dia(hole);
|
40
|
+
cy_h = r_from_dia(size * 2.5);
|
41
|
+
}
|
42
|
+
|
43
|
+
example001();
|
44
|
+
=end
|
45
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
# note that center:true doesn't work with cube
|
7
|
+
# however, there are convenience methods like
|
8
|
+
# center, center_x, center_y, center_xy, center_z available.
|
9
|
+
# As rule of thumb, avoid center if possible.
|
10
|
+
|
11
|
+
res1 = cube([30,30,30]).center
|
12
|
+
res1+= cube([15,15,50]).center.translate(z:-25)
|
13
|
+
|
14
|
+
res2 = cube([50,10,10]).center
|
15
|
+
res2+= cube([10,50,10]).center
|
16
|
+
res2+= cube([10,10,50]).center
|
17
|
+
|
18
|
+
res = res1-res2
|
19
|
+
res*=cylinder(r1:20,r2:5,h:50,center:true).translate(z:5)
|
20
|
+
|
21
|
+
res.save("example002.scad")
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
=begin
|
28
|
+
module example002()
|
29
|
+
{
|
30
|
+
intersection() {
|
31
|
+
difference() {
|
32
|
+
union() {
|
33
|
+
cube([30, 30, 30], center = true);
|
34
|
+
translate([0, 0, -25])
|
35
|
+
cube([15, 15, 50], center = true);
|
36
|
+
}
|
37
|
+
union() {
|
38
|
+
cube([50, 10, 10], center = true);
|
39
|
+
cube([10, 50, 10], center = true);
|
40
|
+
cube([10, 10, 50], center = true);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
translate([0, 0, 5])
|
44
|
+
cylinder(h = 50, r1 = 20, r2 = 5, center = true);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
example002();
|
49
|
+
=end
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
def example003
|
8
|
+
res1 = cube([30,30,30]).center
|
9
|
+
res2 = nil # either initialize it with a CrystalScadObject or nil as we do a += on it later on
|
10
|
+
[[1,0,0],[0,1,0],[0,0,1]].each do |x,y,z|
|
11
|
+
res1+= cube([15+x*25,15+y*25,15+z*25]).center
|
12
|
+
res2+= cube([10+x*40,10+y*40,+10+z*40]).center
|
13
|
+
end
|
14
|
+
res1-res2
|
15
|
+
end
|
16
|
+
|
17
|
+
example003.save("example003.scad")
|
18
|
+
|
19
|
+
|
20
|
+
=begin
|
21
|
+
|
22
|
+
module example003()
|
23
|
+
{
|
24
|
+
difference() {
|
25
|
+
union() {
|
26
|
+
cube([30, 30, 30], center = true);
|
27
|
+
cube([40, 15, 15], center = true);
|
28
|
+
cube([15, 40, 15], center = true);
|
29
|
+
cube([15, 15, 40], center = true);
|
30
|
+
}
|
31
|
+
union() {
|
32
|
+
cube([50, 10, 10], center = true);
|
33
|
+
cube([10, 50, 10], center = true);
|
34
|
+
cube([10, 10, 50], center = true);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
example003();
|
40
|
+
|
41
|
+
=end
|
42
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
def example004
|
8
|
+
cube([30,30,30]).center-sphere(d:40)
|
9
|
+
end
|
10
|
+
|
11
|
+
example004.save("example004.scad")
|
12
|
+
|
13
|
+
|
14
|
+
=begin
|
15
|
+
|
16
|
+
|
17
|
+
module example004()
|
18
|
+
{
|
19
|
+
difference() {
|
20
|
+
cube(30, center = true);
|
21
|
+
sphere(20);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
example004();
|
26
|
+
|
27
|
+
|
28
|
+
=end
|
29
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
# note that openscad works with radians automatically and ruby doesn't.
|
8
|
+
def radians(a)
|
9
|
+
a/180.0 * Math::PI
|
10
|
+
end
|
11
|
+
|
12
|
+
def example005
|
13
|
+
# base
|
14
|
+
res = cylinder(d:200,h:50)
|
15
|
+
res -= cylinder(d:160,h:50).translate(z:10)
|
16
|
+
res -= cube([50,50,50]).center.translate(x:100,z:35)
|
17
|
+
|
18
|
+
# pylons
|
19
|
+
(0..5).each do |i|
|
20
|
+
res+= cylinder(d:20,h:200).translate(x:Math::sin(radians(360*i/6))*80,y:Math::cos(radians(360*i/6))*80)
|
21
|
+
end
|
22
|
+
|
23
|
+
# roof
|
24
|
+
res += cylinder(d1:240,d2:0,h:80).translate(z:200)
|
25
|
+
|
26
|
+
res.translate(z:-120)
|
27
|
+
end
|
28
|
+
|
29
|
+
example005.save("example005.scad")
|
30
|
+
|
31
|
+
|
32
|
+
=begin
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
module example005()
|
37
|
+
{
|
38
|
+
translate([0, 0, -120]) {
|
39
|
+
difference() {
|
40
|
+
cylinder(h = 50, r = 100);
|
41
|
+
translate([0, 0, 10]) cylinder(h = 50, r = 80);
|
42
|
+
translate([100, 0, 35]) cube(50, center = true);
|
43
|
+
}
|
44
|
+
for (i = [0:5]) {
|
45
|
+
echo(360*i/6, sin(360*i/6)*80, cos(360*i/6)*80);
|
46
|
+
translate([sin(360*i/6)*80, cos(360*i/6)*80, 0 ])
|
47
|
+
cylinder(h = 200, r=10);
|
48
|
+
}
|
49
|
+
translate([0, 0, 200])
|
50
|
+
cylinder(h = 80, r1 = 120, r2 = 0);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
example005();
|
55
|
+
|
56
|
+
|
57
|
+
=end
|
58
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
g1 = PrintedGear.new(module:2.0,teeth:40,bore:5,height:4)
|
8
|
+
g2 = PrintedGear.new(module:2.0,teeth:20,bore:5,height:4,rotation:0.5) # rotation in number of teeth
|
9
|
+
|
10
|
+
res = g1.show.color("red").rotate(z:"$t*360")
|
11
|
+
res += g2.show.rotate(z:"-$t*360*#{g1.ratio(g2)}").translate(x:g1.distance_to(g2))
|
12
|
+
|
13
|
+
res.save("printed_gear.scad")
|
14
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
# This example shows the use of ScrewThreads in CrystalScad.
|
7
|
+
|
8
|
+
class CustomPartWithFemaleThread < CrystalScad::Assembly
|
9
|
+
# this could be something like a tslot-nut
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@x=8
|
13
|
+
@y=20
|
14
|
+
@z=8
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
res = cube([@x,@y,@z]).color(r:180,b:180,g:180)
|
19
|
+
res -= threads_top.map(&:show) # - tries output normally, we want show here
|
20
|
+
end
|
21
|
+
|
22
|
+
def threads_top
|
23
|
+
holes =*ScrewThread.new(x:@x/2,y:@y/2+3,size:4,depth:@z)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class CustomPartWithMaleThread < CrystalScad::Assembly
|
30
|
+
def initialize
|
31
|
+
@x=50
|
32
|
+
@y=50
|
33
|
+
@z=15
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
res = cube([@x,@y,@z]).color(r:200,b:200,g:200,a:100)
|
38
|
+
res += threads
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def threads_top
|
43
|
+
holes =*ScrewThread.new(x:@x/2+2,y:@y/2+2,z:@z,size:4,depth:@z)
|
44
|
+
end
|
45
|
+
|
46
|
+
def threads_bottom
|
47
|
+
holes =*ScrewThread.new(x:@x/2+2,y:@y/2+2,z:0,size:4,depth:@z,face:"bottom")
|
48
|
+
end
|
49
|
+
|
50
|
+
def threads_left
|
51
|
+
holes =*ScrewThread.new(x:0,y:10,z:8,size:4,depth:10,face:"left")
|
52
|
+
end
|
53
|
+
|
54
|
+
def threads_right
|
55
|
+
holes =*ScrewThread.new(x:@x,y:15,z:3,size:4,depth:10,face:"right")
|
56
|
+
end
|
57
|
+
|
58
|
+
def threads_front
|
59
|
+
holes =*ScrewThread.new(x:25,y:0,z:11,size:4,depth:10,face:"front")
|
60
|
+
end
|
61
|
+
|
62
|
+
def threads_back
|
63
|
+
holes =*ScrewThread.new(x:25,y:@y,z:11,size:4,depth:10,face:"back")
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
female=CustomPartWithFemaleThread.new
|
70
|
+
male =CustomPartWithMaleThread.new
|
71
|
+
|
72
|
+
pos = male.threads_top.first.position_on(female.threads_top.first)
|
73
|
+
|
74
|
+
res = male.show
|
75
|
+
res += female.show.translate(pos)
|
76
|
+
|
77
|
+
rotation = {}
|
78
|
+
pos = male.threads_bottom.first.position_on(female.threads_top.first,rotation)
|
79
|
+
res += female.show.rotate(rotation).mirror(z:1).translate(pos)
|
80
|
+
|
81
|
+
|
82
|
+
rotation = {y:-90}
|
83
|
+
pos = male.threads_left.first.position_on(female.threads_top.first,rotation)
|
84
|
+
res += female.show.rotate(rotation).translate(pos)
|
85
|
+
|
86
|
+
rotation = {y:90}
|
87
|
+
pos = male.threads_right.first.position_on(female.threads_top.first,rotation)
|
88
|
+
res += female.show.rotate(rotation).translate(pos)
|
89
|
+
|
90
|
+
|
91
|
+
rotation = {x:90}
|
92
|
+
pos = male.threads_front.first.position_on(female.threads_top.first,rotation)
|
93
|
+
# testing rotate_around here
|
94
|
+
res += female.show.rotate_around(female.threads_top.first,z:90).rotate(rotation).translate(pos)
|
95
|
+
|
96
|
+
|
97
|
+
rotation = {x:-90}
|
98
|
+
pos = male.threads_back.first.position_on(female.threads_top.first,rotation)
|
99
|
+
res += female.show.rotate(rotation).translate(pos)
|
100
|
+
|
101
|
+
|
102
|
+
res.save("threads2.scad")
|
data/lib/crystalscad/Assembly.rb
CHANGED
@@ -76,6 +76,24 @@ module CrystalScad
|
|
76
76
|
def scad_output()
|
77
77
|
return self.output.scad_output
|
78
78
|
end
|
79
|
+
|
80
|
+
def threads
|
81
|
+
a = []
|
82
|
+
[:threads_top,:threads_bottom,:threads_left,:threads_right,:threads_front,:threads_back].each do |m|
|
83
|
+
if self.respond_to? m
|
84
|
+
ret = self.send m
|
85
|
+
unless ret == nil
|
86
|
+
if ret.kind_of? Array
|
87
|
+
a+= ret
|
88
|
+
else
|
89
|
+
a << ret
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
return a
|
96
|
+
end
|
79
97
|
|
80
98
|
end
|
81
99
|
|
@@ -75,6 +75,11 @@ module CrystalScad
|
|
75
75
|
self
|
76
76
|
end
|
77
77
|
|
78
|
+
def rotate_around(point,args)
|
79
|
+
x,y,z= point.x, point.y, point.z
|
80
|
+
self.translate(x:-x,y:-y,z:-z).rotate(args).translate(x:x,y:y,z:z)
|
81
|
+
end
|
82
|
+
|
78
83
|
def translate(args)
|
79
84
|
@transformations << Translate.new(args)
|
80
85
|
self
|
@@ -97,13 +102,13 @@ module CrystalScad
|
|
97
102
|
|
98
103
|
class Rotate < Transformation
|
99
104
|
def to_rubyscad
|
100
|
-
return RubyScadBridge.new.rotate(@args)
|
105
|
+
return RubyScadBridge.new.rotate(@args).gsub('"','')
|
101
106
|
end
|
102
107
|
end
|
103
108
|
|
104
109
|
class Translate < Transformation
|
105
110
|
def to_rubyscad
|
106
|
-
return RubyScadBridge.new.translate(@args)
|
111
|
+
return RubyScadBridge.new.translate(@args).gsub('"','')
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
@@ -152,6 +157,10 @@ module CrystalScad
|
|
152
157
|
self
|
153
158
|
end
|
154
159
|
|
160
|
+
def center
|
161
|
+
@transformations << Translate.new({x:-@x/2,y:-@y/2,z:-@z/2})
|
162
|
+
self
|
163
|
+
end
|
155
164
|
|
156
165
|
def to_rubyscad
|
157
166
|
return RubyScadBridge.new.cube(@args)
|
@@ -169,6 +178,17 @@ module CrystalScad
|
|
169
178
|
end
|
170
179
|
Cube.new(args)
|
171
180
|
end
|
181
|
+
|
182
|
+
class Sphere < Primitive
|
183
|
+
def to_rubyscad
|
184
|
+
return RubyScadBridge.new.sphere(@args)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def sphere(args)
|
189
|
+
Sphere.new(args)
|
190
|
+
end
|
191
|
+
|
172
192
|
|
173
193
|
# 2d primitives
|
174
194
|
class Square < Primitive
|
@@ -297,7 +317,7 @@ module CrystalScad
|
|
297
317
|
args.each do |a|
|
298
318
|
if a.respond_to? :output
|
299
319
|
r = Difference.new(r,a.output)
|
300
|
-
else
|
320
|
+
else
|
301
321
|
r = Difference.new(r,a)
|
302
322
|
end
|
303
323
|
end
|
data/lib/crystalscad/Gears.rb
CHANGED
@@ -18,7 +18,6 @@ module CrystalScad::Gears
|
|
18
18
|
|
19
19
|
class Gear < CrystalScad::Assembly
|
20
20
|
# this library is to be used to easily work with gears and their distances to each other
|
21
|
-
# TODO: maybe at some point port the publicDomainGear.scad into it?
|
22
21
|
|
23
22
|
attr_reader :module, :teeth, :height, :hub_dia, :hub_height
|
24
23
|
|
@@ -60,10 +59,87 @@ module CrystalScad::Gears
|
|
60
59
|
raise "You cannot use two gears with different gear modules."
|
61
60
|
return
|
62
61
|
end
|
63
|
-
return (@module * (@teeth + other_gear.teeth))/2.0
|
62
|
+
return (@module.to_f * (@teeth.to_f + other_gear.teeth.to_f))/2.0
|
63
|
+
end
|
64
|
+
|
65
|
+
def ratio(other_gear)
|
66
|
+
@teeth.to_f / other_gear.teeth.to_f
|
64
67
|
end
|
65
68
|
|
66
69
|
end
|
70
|
+
|
71
|
+
# Acts the same as Gear, but does produce printable output
|
72
|
+
class PrintedGear < Gear
|
73
|
+
|
74
|
+
def initialize(args={})
|
75
|
+
super
|
76
|
+
@pressure_angle = args[:pressure_angle] || 20
|
77
|
+
@clearance = args[:clearance] || 0.0
|
78
|
+
@backlash = args[:backlash] || 0.0
|
79
|
+
@twist = args[:twist] || 0.0
|
80
|
+
@teeth_to_hide = args[:teeth_to_hide] || 0.0
|
81
|
+
|
82
|
+
@rotation = args[:rotation] || 0.0 # rotation in teeth
|
83
|
+
end
|
84
|
+
|
85
|
+
def show
|
86
|
+
output
|
87
|
+
end
|
88
|
+
|
89
|
+
# ported from publicDomainGearV1.1.scad
|
90
|
+
def output
|
91
|
+
p = @module * @teeth / 2.0
|
92
|
+
c = p + @module - @clearance # radius of pitch circle
|
93
|
+
b = p*Math::cos(radians(@pressure_angle)) # radius of base circle
|
94
|
+
r = p-(c-p)-@clearance # radius of root circle
|
95
|
+
t = (@module*Math::PI)/2.0-@backlash/2.0 # tooth thickness at pitch circle
|
96
|
+
k = -iang(b, p) - t/2.0/p/Math::PI*180 # angle to where involute meets base circle on each side of tooth
|
97
|
+
|
98
|
+
points=[
|
99
|
+
[0, -@hub_dia/10.0],
|
100
|
+
polar(r, -181/@teeth.to_f),
|
101
|
+
polar(r, r<b ? k : -180/@teeth.to_f),
|
102
|
+
q7(0/5,r,b,c,k, 1),q7(1/5,r,b,c,k, 1),q7(2/5,r,b,c,k, 1),q7(3/5,r,b,c,k, 1),q7(4/5,r,b,c,k, 1),q7(5/5,r,b,c,k, 1),
|
103
|
+
q7(5/5,r,b,c,k,-1),q7(4/5,r,b,c,k,-1),q7(3/5,r,b,c,k,-1),q7(2/5,r,b,c,k,-1),q7(1/5,r,b,c,k,-1),q7(0/5,r,b,c,k,-1),
|
104
|
+
polar(r, r<b ? -k : 180/@teeth.to_f),
|
105
|
+
polar(r, 181/@teeth.to_f)
|
106
|
+
]
|
107
|
+
paths=[(0..16).to_a]
|
108
|
+
|
109
|
+
res = CrystalScadObject.new
|
110
|
+
(0..@teeth-@teeth_to_hide-1).each do |i|
|
111
|
+
res+= polygon(points:points,paths:paths).linear_extrude(h:@height,convexity:10,center:false,twist:@twist).rotate(z:i*360/@teeth.to_f)
|
112
|
+
end
|
113
|
+
|
114
|
+
res-= cylinder(h:@height+0.2,d:@bore).translate(z:-0.1)
|
115
|
+
res.rotate(z:@rotation*360.0/@teeth)
|
116
|
+
end
|
117
|
+
|
118
|
+
def radians(a)
|
119
|
+
a/180.0 * Math::PI
|
120
|
+
end
|
121
|
+
|
122
|
+
def degrees(a)
|
123
|
+
a*180 / Math::PI
|
124
|
+
end
|
125
|
+
|
126
|
+
def polar(r,theta)
|
127
|
+
[r*Math::sin(radians(theta)), r*Math::cos(radians(theta))] #convert polar to cartesian coordinates
|
128
|
+
end
|
129
|
+
|
130
|
+
def iang(r1,r2)
|
131
|
+
Math::sqrt((r2/r1)*(r2/r1) - 1)/Math::PI*180 - degrees(Math::acos(r1/r2)) #//unwind a string this many degrees to go from radius r1 to radius r2
|
132
|
+
end
|
133
|
+
|
134
|
+
def q7(f,r,b,r2,t,s)
|
135
|
+
q6(b,s,t,(1-f)*[b,r].max+f*r2) #radius a fraction f up the curved side of the tooth
|
136
|
+
end
|
137
|
+
|
138
|
+
def q6(b,s,t,d)
|
139
|
+
polar(d,s*(iang(b,d)+t)) # point at radius d on the involute curve
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
67
143
|
|
68
144
|
end
|
69
145
|
|
@@ -17,7 +17,7 @@ module CrystalScad::ScrewThreads
|
|
17
17
|
class ScrewThread
|
18
18
|
# I would name this Thread but that's already taken by something else
|
19
19
|
|
20
|
-
attr_accessor :x,:y,:z,:size, :depth
|
20
|
+
attr_accessor :x,:y,:z,:size, :depth, :face
|
21
21
|
|
22
22
|
def initialize(args={})
|
23
23
|
@x = args[:x] || 0
|
@@ -25,6 +25,52 @@ module CrystalScad::ScrewThreads
|
|
25
25
|
@z = args[:z] || 0
|
26
26
|
@depth = args[:depth]
|
27
27
|
@size = args[:size]
|
28
|
+
@face = args[:face] || :top
|
29
|
+
end
|
30
|
+
|
31
|
+
def rotation
|
32
|
+
case @face.to_s
|
33
|
+
when "top"
|
34
|
+
return {}
|
35
|
+
when "bottom"
|
36
|
+
return {y:180}
|
37
|
+
when "left"
|
38
|
+
return {y:-90}
|
39
|
+
when "right"
|
40
|
+
return {y:90}
|
41
|
+
when "front" # checkme
|
42
|
+
return {x:90}
|
43
|
+
when "back"
|
44
|
+
return {x:-90}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def show
|
49
|
+
cylinder(d:@size,h:@depth).rotate(rotation).translate(x:@x,y:@y,z:@z).color(r:130,g:130,b:130)
|
50
|
+
end
|
51
|
+
|
52
|
+
def orientation_swap_to(coords,rotation)
|
53
|
+
if rotation[:x].to_i == -90
|
54
|
+
return [coords[0],coords[2],-coords[1]]
|
55
|
+
end
|
56
|
+
if rotation[:x].to_i == 90
|
57
|
+
return [coords[0],-coords[2],coords[1]]
|
58
|
+
end
|
59
|
+
if rotation[:y].to_i == -90
|
60
|
+
return [coords[2],coords[1],coords[0]]
|
61
|
+
end
|
62
|
+
if rotation[:y].to_i == 90
|
63
|
+
return [-coords[2],coords[1],-coords[0]]
|
64
|
+
end
|
65
|
+
|
66
|
+
return coords
|
67
|
+
end
|
68
|
+
|
69
|
+
def position_on(other_thread,rotation={})
|
70
|
+
oc = other_thread.x, other_thread.y, other_thread.z
|
71
|
+
oc = orientation_swap_to(oc,rotation)
|
72
|
+
|
73
|
+
return {x:@x-oc[0],y:@y-oc[1],z:@z-oc[2]}
|
28
74
|
end
|
29
75
|
|
30
76
|
end
|
@@ -39,7 +85,7 @@ module CrystalScad::ScrewThreads
|
|
39
85
|
|
40
86
|
# we need to know obj1 height (if not supplied by user)
|
41
87
|
height ||= args[:height]
|
42
|
-
case face
|
88
|
+
case face.to_s
|
43
89
|
when "top"
|
44
90
|
height ||= obj1.z rescue nil
|
45
91
|
when "bottom"
|
@@ -92,7 +138,6 @@ module CrystalScad::ScrewThreads
|
|
92
138
|
ret = []
|
93
139
|
holes.each_with_index do |hole,i|
|
94
140
|
bolt = Bolt.new(hole.size,bolt_heights[i])
|
95
|
-
puts bolt_heights[i]
|
96
141
|
case face
|
97
142
|
when "top"
|
98
143
|
bolt.transformations << Rotate.new(x:180)
|
@@ -117,6 +162,6 @@ module CrystalScad::ScrewThreads
|
|
117
162
|
end
|
118
163
|
|
119
164
|
ret
|
120
|
-
end
|
165
|
+
end
|
121
166
|
|
122
167
|
end
|
data/lib/crystalscad/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalscad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 8
|
10
|
+
version: 0.3.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joachim Glauche
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2014-01-05 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rubyscad
|
@@ -63,8 +63,15 @@ files:
|
|
63
63
|
- Rakefile
|
64
64
|
- crystalscad.gemspec
|
65
65
|
- examples/gear.rb
|
66
|
+
- examples/openscad_examples/example001.rb
|
67
|
+
- examples/openscad_examples/example002.rb
|
68
|
+
- examples/openscad_examples/example003.rb
|
69
|
+
- examples/openscad_examples/example004.rb
|
70
|
+
- examples/openscad_examples/example005.rb
|
71
|
+
- examples/printed_gear.rb
|
66
72
|
- examples/stack.rb
|
67
73
|
- examples/threads.rb
|
74
|
+
- examples/threads2.rb
|
68
75
|
- lib/crystalscad.rb
|
69
76
|
- lib/crystalscad/Assembly.rb
|
70
77
|
- lib/crystalscad/BillOfMaterial.rb
|