scad-btw 0.1.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/Rakefile +12 -0
- data/exe/scad-btw +6 -0
- data/flake.lock +306 -0
- data/flake.nix +63 -0
- data/lib/extensions/jenncad.rb +91 -0
- data/lib/extensions/kernel.rb +17 -0
- data/lib/extensions/thor.rb +11 -0
- data/lib/scad/btw/base.rb +224 -0
- data/lib/scad/btw/cli/base.rb +31 -0
- data/lib/scad/btw/cli/concerns/export_formats.rb +43 -0
- data/lib/scad/btw/cli/concerns/export_options.rb +62 -0
- data/lib/scad/btw/cli/presets.rb +66 -0
- data/lib/scad/btw/cli/solid.rb +33 -0
- data/lib/scad/btw/cli/spoked.rb +33 -0
- data/lib/scad/btw/component/axle_hole.rb +53 -0
- data/lib/scad/btw/component/center.rb +58 -0
- data/lib/scad/btw/component/counterweight.rb +117 -0
- data/lib/scad/btw/component/flange.rb +96 -0
- data/lib/scad/btw/component/joint.rb +57 -0
- data/lib/scad/btw/component/joint_base.rb +34 -0
- data/lib/scad/btw/component/o_ring_groove.rb +95 -0
- data/lib/scad/btw/component/solid.rb +67 -0
- data/lib/scad/btw/component/spokes.rb +118 -0
- data/lib/scad/btw/component/tread.rb +109 -0
- data/lib/scad/btw/concerns/component_args.rb +26 -0
- data/lib/scad/btw/concerns/flange_heights.rb +24 -0
- data/lib/scad/btw/concerns/joint_args.rb +58 -0
- data/lib/scad/btw/concerns/part_commons.rb +29 -0
- data/lib/scad/btw/concerns/tread_width.rb +21 -0
- data/lib/scad/btw/converters/openscad_2_ascii_stl.rb +39 -0
- data/lib/scad/btw/presets/scale_1_38/cargo_wheel_thin_36_inch.rb +21 -0
- data/lib/scad/btw/presets/scale_1_38/v20.rb +83 -0
- data/lib/scad/btw/solid.rb +13 -0
- data/lib/scad/btw/spoked.rb +13 -0
- data/lib/scad/btw/version.rb +7 -0
- data/lib/scad/btw.rb +29 -0
- data/sig/scad/btw.rbs +6 -0
- metadata +150 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
require 'scad/btw/concerns/tread_width'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class Counterweight < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::TreadWidth
|
14
|
+
|
15
|
+
TYPE = :addition
|
16
|
+
DEFAULT_DEVIATION = 0
|
17
|
+
|
18
|
+
ARGS = {
|
19
|
+
prefix: :counterweight,
|
20
|
+
args: {
|
21
|
+
height: {
|
22
|
+
description: 'Counterweight height. Defaults to: Height of ' \
|
23
|
+
'spokes or web defined be `wheel_inner_height` ' \
|
24
|
+
'option.',
|
25
|
+
type: :numeric
|
26
|
+
},
|
27
|
+
diameter: {
|
28
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
29
|
+
'defined by `wheel_size` option.',
|
30
|
+
type: :numeric,
|
31
|
+
hide: true
|
32
|
+
},
|
33
|
+
tread_width: {
|
34
|
+
description: "Tread width. Minimum width of #{MIN_TREAD_WIDTH} " \
|
35
|
+
'will be used if provided/default value is ' \
|
36
|
+
'smaller. Defaults to: Diameter * 0.06',
|
37
|
+
type: :numeric,
|
38
|
+
hide: true
|
39
|
+
},
|
40
|
+
deviation: {
|
41
|
+
description: 'Defines convexity of the counterweight top.',
|
42
|
+
default: DEFAULT_DEVIATION,
|
43
|
+
type: :numeric
|
44
|
+
},
|
45
|
+
width: {
|
46
|
+
description: 'Distance from tread to counterweight top. ' \
|
47
|
+
'Defaults to: Diameter / 4',
|
48
|
+
type: :numeric
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}.freeze
|
52
|
+
|
53
|
+
def initialize(args = {})
|
54
|
+
super
|
55
|
+
|
56
|
+
@height = args.fetch(:height)
|
57
|
+
@diameter = args.fetch(:diameter)
|
58
|
+
@tread_width = args[:tread_width]
|
59
|
+
@deviation = args[:deviation] || DEFAULT_DEVIATION
|
60
|
+
@width = args[:width]
|
61
|
+
end
|
62
|
+
|
63
|
+
def part
|
64
|
+
cylinder(d: calculated_diameter, h: height) - substraction
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
attr_reader :width, :height, :deviation, :diameter, :tread_width
|
70
|
+
|
71
|
+
# components
|
72
|
+
|
73
|
+
def substraction
|
74
|
+
deviation.positive? ? deviation_substraction : straight_substraction
|
75
|
+
end
|
76
|
+
|
77
|
+
def deviation_substraction
|
78
|
+
x = calculated_width - deviation + deviation_diff_radius -
|
79
|
+
(calculated_diameter / 2)
|
80
|
+
cylinder(r: deviation_diff_radius, h: height + 1)
|
81
|
+
.move(x: x, y: 0, z: -0.5)
|
82
|
+
end
|
83
|
+
|
84
|
+
def straight_substraction
|
85
|
+
cube(x: calculated_diameter, y: calculated_diameter, z: height + 1,
|
86
|
+
center: true)
|
87
|
+
.move(x: calculated_width, y: 0, z: -0.5)
|
88
|
+
end
|
89
|
+
|
90
|
+
# functions
|
91
|
+
|
92
|
+
def calculated_width
|
93
|
+
width || (calculated_diameter / 4)
|
94
|
+
end
|
95
|
+
|
96
|
+
def calculated_diameter
|
97
|
+
calc_width = calculated_tread_width(width: tread_width,
|
98
|
+
diameter: diameter)
|
99
|
+
|
100
|
+
diameter - calc_width + (2 * overlap)
|
101
|
+
end
|
102
|
+
|
103
|
+
def half_upper_counterweight_length
|
104
|
+
Math.sqrt(
|
105
|
+
((calculated_diameter / 2)**2) -
|
106
|
+
(((calculated_diameter / 2) - calculated_width)**2)
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
def deviation_diff_radius
|
111
|
+
((half_upper_counterweight_length**2) + (deviation**2)) /
|
112
|
+
(2 * deviation)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/flange_heights'
|
5
|
+
require 'scad/btw/concerns/part_commons'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class Flange < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::FlangeHeights
|
14
|
+
|
15
|
+
TYPE = :addition
|
16
|
+
WIDTH = 2
|
17
|
+
BOTTOM_Z_OFFSET = 1
|
18
|
+
|
19
|
+
ARGS = {
|
20
|
+
prefix: :flange,
|
21
|
+
args: {
|
22
|
+
diameter: {
|
23
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
24
|
+
'defined by `wheel_size` option.',
|
25
|
+
type: :numeric,
|
26
|
+
hide: true
|
27
|
+
},
|
28
|
+
inner_height: {
|
29
|
+
description: 'Flange height on tread.',
|
30
|
+
default: FLANGE_INNER_HEIGHT,
|
31
|
+
type: :numeric
|
32
|
+
},
|
33
|
+
outer_height: {
|
34
|
+
description: 'Flange height on edge.',
|
35
|
+
default: FLANGE_OUTER_HEIGHT,
|
36
|
+
type: :numeric
|
37
|
+
},
|
38
|
+
width: {
|
39
|
+
description: 'Flange width.',
|
40
|
+
default: WIDTH,
|
41
|
+
type: :numeric
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}.freeze
|
45
|
+
|
46
|
+
def initialize(args = {})
|
47
|
+
super
|
48
|
+
|
49
|
+
@diameter = args.fetch(:diameter)
|
50
|
+
@width = args[:width] || WIDTH
|
51
|
+
@inner_height = args[:inner_height]
|
52
|
+
@outer_height = args[:outer_height]
|
53
|
+
end
|
54
|
+
|
55
|
+
def part
|
56
|
+
lower_part + upper_part - inner_space
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :diameter, :width, :inner_height, :outer_height
|
62
|
+
|
63
|
+
# components
|
64
|
+
|
65
|
+
def lower_part
|
66
|
+
cylinder(d1: outer_diameter + 0.5, d2: outer_diameter,
|
67
|
+
h: calc_outer_height).mz(BOTTOM_Z_OFFSET)
|
68
|
+
end
|
69
|
+
|
70
|
+
def upper_part
|
71
|
+
cylinder(d1: outer_diameter - 1, d2: diameter - overlap,
|
72
|
+
h: calc_inner_height - calc_outer_height - BOTTOM_Z_OFFSET)
|
73
|
+
.mz(calc_outer_height + BOTTOM_Z_OFFSET - overlap)
|
74
|
+
end
|
75
|
+
|
76
|
+
def inner_space
|
77
|
+
cylinder(d: diameter - (2 * overlap), h: calc_inner_height + 2).mz(-1)
|
78
|
+
end
|
79
|
+
|
80
|
+
# functions
|
81
|
+
|
82
|
+
def calc_inner_height
|
83
|
+
calculated_inner_flange_height(inner_height)
|
84
|
+
end
|
85
|
+
|
86
|
+
def calc_outer_height
|
87
|
+
calculated_outer_flange_height(outer_height)
|
88
|
+
end
|
89
|
+
|
90
|
+
def outer_diameter
|
91
|
+
diameter + (2 * width)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
require 'scad/btw/concerns/joint_args'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class Joint < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::JointArgs
|
14
|
+
|
15
|
+
TYPE = :substraction
|
16
|
+
HOLE_BEVEL_DIAMETER = 6.2
|
17
|
+
HOLE_BEVEL_HEIGHT = 0.9
|
18
|
+
|
19
|
+
def part
|
20
|
+
(hole + lower_bevel + upper_bevel).mx(calculated_dist_from_center)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :height, :dist_from_center
|
26
|
+
|
27
|
+
# components
|
28
|
+
|
29
|
+
def hole
|
30
|
+
cylinder(d: HOLE_DIAMETER, h: height + 1).mz(-0.5)
|
31
|
+
end
|
32
|
+
|
33
|
+
def lower_bevel
|
34
|
+
bevel.mz(lower_bevel_z_offset)
|
35
|
+
end
|
36
|
+
|
37
|
+
def upper_bevel
|
38
|
+
bevel.mz(upper_bevel_z_offset)
|
39
|
+
end
|
40
|
+
|
41
|
+
def bevel
|
42
|
+
cylinder(d: HOLE_BEVEL_DIAMETER, h: HOLE_BEVEL_HEIGHT + 0.1)
|
43
|
+
end
|
44
|
+
|
45
|
+
# functions
|
46
|
+
|
47
|
+
def lower_bevel_z_offset
|
48
|
+
-0.1
|
49
|
+
end
|
50
|
+
|
51
|
+
def upper_bevel_z_offset
|
52
|
+
height - HOLE_BEVEL_HEIGHT
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
require 'scad/btw/concerns/joint_args'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class JointBase < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::JointArgs
|
14
|
+
|
15
|
+
TYPE = :addition
|
16
|
+
|
17
|
+
def part
|
18
|
+
cylinder(d: calculated_diameter, h: height)
|
19
|
+
.mx(calculated_dist_from_center)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :height, :dist_from_center, :diameter
|
25
|
+
|
26
|
+
def calculated_diameter
|
27
|
+
min_diameter = HOLE_DIAMETER + (2 * MIN_HOLE_WALL_THICKNESS)
|
28
|
+
|
29
|
+
[diameter || min_diameter, min_diameter].max
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/flange_heights'
|
5
|
+
require 'scad/btw/concerns/part_commons'
|
6
|
+
require_relative 'flange'
|
7
|
+
|
8
|
+
module Scad
|
9
|
+
module Btw
|
10
|
+
module Component
|
11
|
+
class ORingGroove < JennCad::Part
|
12
|
+
include Scad::Btw::Concerns::PartCommons
|
13
|
+
include Scad::Btw::Concerns::ComponentArgs
|
14
|
+
include Scad::Btw::Concerns::FlangeHeights
|
15
|
+
|
16
|
+
TYPE = :substraction
|
17
|
+
GROOVE_DIAMETER = 1.5
|
18
|
+
THIN_GROOVE_DIAMETER = 1
|
19
|
+
THIN_GROOVE = false
|
20
|
+
|
21
|
+
ARGS = {
|
22
|
+
prefix: :o_ring_groove,
|
23
|
+
args: {
|
24
|
+
diameter: {
|
25
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
26
|
+
'defined by `wheel_size` option.',
|
27
|
+
type: :numeric,
|
28
|
+
hide: true
|
29
|
+
},
|
30
|
+
flange_height: {
|
31
|
+
description: 'Flange height on tread.',
|
32
|
+
default: FLANGE_INNER_HEIGHT,
|
33
|
+
type: :numeric,
|
34
|
+
hide: true
|
35
|
+
},
|
36
|
+
thin: {
|
37
|
+
description: 'Whether groove is thin (1 mm) or not (1.5 mm). ' \
|
38
|
+
'Defaults to: true if wheel is thin, false ' \
|
39
|
+
'otherwise.',
|
40
|
+
type: :boolean
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}.freeze
|
44
|
+
|
45
|
+
def initialize(args = {})
|
46
|
+
super
|
47
|
+
|
48
|
+
@diameter = args.fetch(:diameter)
|
49
|
+
@flange_height = args[:flange_height]
|
50
|
+
@thin = args[:thin] || THIN_GROOVE
|
51
|
+
end
|
52
|
+
|
53
|
+
def part
|
54
|
+
res = cross_section.rotate_extrude
|
55
|
+
|
56
|
+
res.mz(z_offset)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :diameter, :flange_height, :thin
|
62
|
+
|
63
|
+
# components
|
64
|
+
|
65
|
+
def cross_section
|
66
|
+
(cs_circle + cs_square).mx((diameter - (groove_diameter * 4 / 5)) / 2)
|
67
|
+
end
|
68
|
+
|
69
|
+
def cs_circle
|
70
|
+
circle(d: groove_diameter)
|
71
|
+
end
|
72
|
+
|
73
|
+
def cs_square
|
74
|
+
square(x: groove_diameter, y: groove_diameter, center: true)
|
75
|
+
.mx(groove_diameter / 2)
|
76
|
+
end
|
77
|
+
|
78
|
+
# functions
|
79
|
+
|
80
|
+
def groove_diameter
|
81
|
+
(thin ? GROOVE_DIAMETER : THIN_GROOVE_DIAMETER) * 4 / 5
|
82
|
+
end
|
83
|
+
|
84
|
+
def z_offset
|
85
|
+
(calc_flange_height + (groove_diameter / 2)) -
|
86
|
+
0.1 + (thin ? 0.15 : 1)
|
87
|
+
end
|
88
|
+
|
89
|
+
def calc_flange_height
|
90
|
+
calculated_inner_flange_height(flange_height)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
require 'scad/btw/concerns/tread_width'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class Solid < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::TreadWidth
|
14
|
+
|
15
|
+
TYPE = :addition
|
16
|
+
|
17
|
+
ARGS = {
|
18
|
+
prefix: :solid,
|
19
|
+
args: {
|
20
|
+
height: {
|
21
|
+
description: 'Web height. Defaults to: Value/default of ' \
|
22
|
+
'`wheel_inner_height` option.',
|
23
|
+
type: :numeric,
|
24
|
+
hide: true
|
25
|
+
},
|
26
|
+
diameter: {
|
27
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
28
|
+
'defined by `wheel_size` option.',
|
29
|
+
type: :numeric,
|
30
|
+
hide: true
|
31
|
+
},
|
32
|
+
tread_width: {
|
33
|
+
description: "Tread width. Minimum width of #{MIN_TREAD_WIDTH} " \
|
34
|
+
'will be used if provided/default value is ' \
|
35
|
+
'smaller. Defaults to: Diameter * 0.06',
|
36
|
+
type: :numeric,
|
37
|
+
hide: true
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}.freeze
|
41
|
+
|
42
|
+
def initialize(args = {})
|
43
|
+
super
|
44
|
+
|
45
|
+
@height = args.fetch(:height)
|
46
|
+
@diameter = args.fetch(:diameter)
|
47
|
+
@tread_width = args[:tread_width]
|
48
|
+
end
|
49
|
+
|
50
|
+
def part
|
51
|
+
cylinder(d: calculated_diameter, h: height)
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
attr_reader :height, :diameter, :tread_width
|
57
|
+
|
58
|
+
def calculated_diameter
|
59
|
+
calc_width = calculated_tread_width(width: tread_width,
|
60
|
+
diameter: diameter)
|
61
|
+
|
62
|
+
diameter - calc_width + (2 * overlap)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
require 'scad/btw/concerns/tread_width'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Component
|
10
|
+
class Spokes < JennCad::Part
|
11
|
+
include Scad::Btw::Concerns::PartCommons
|
12
|
+
include Scad::Btw::Concerns::ComponentArgs
|
13
|
+
include Scad::Btw::Concerns::TreadWidth
|
14
|
+
|
15
|
+
TYPE = :addition
|
16
|
+
ROTATE_180_DEGREE = false
|
17
|
+
WIDTH = 1
|
18
|
+
|
19
|
+
ARGS = {
|
20
|
+
prefix: :spokes,
|
21
|
+
args: {
|
22
|
+
count: {
|
23
|
+
description: 'Spokes count.',
|
24
|
+
required: true,
|
25
|
+
type: :numeric
|
26
|
+
},
|
27
|
+
width: {
|
28
|
+
description: 'Spokes width.',
|
29
|
+
default: WIDTH,
|
30
|
+
type: :numeric
|
31
|
+
},
|
32
|
+
height: {
|
33
|
+
description: 'Spokes height. Defaults to: Value/default of ' \
|
34
|
+
'`wheel_inner_height` option.',
|
35
|
+
type: :numeric,
|
36
|
+
hide: true
|
37
|
+
},
|
38
|
+
diameter: {
|
39
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
40
|
+
'defined by `wheel_size` option.',
|
41
|
+
type: :numeric,
|
42
|
+
hide: true
|
43
|
+
},
|
44
|
+
tread_width: {
|
45
|
+
description: "Tread width. Minimum width of #{MIN_TREAD_WIDTH} " \
|
46
|
+
'will be used if provided/default value is ' \
|
47
|
+
'smaller. Defaults to: Diameter * 0.06',
|
48
|
+
type: :numeric,
|
49
|
+
hide: true
|
50
|
+
},
|
51
|
+
rotate_180_degree: {
|
52
|
+
description: 'Whether to start at 180 degree instead of 0 ' \
|
53
|
+
'degree when having an odd spokes count.',
|
54
|
+
default: ROTATE_180_DEGREE,
|
55
|
+
type: :boolean
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}.freeze
|
59
|
+
|
60
|
+
def initialize(args = {})
|
61
|
+
super
|
62
|
+
|
63
|
+
@count = args.fetch(:count)
|
64
|
+
@width = args[:width] || WIDTH
|
65
|
+
@height = args.fetch(:height)
|
66
|
+
@diameter = args.fetch(:diameter)
|
67
|
+
@tread_width = args[:tread_width]
|
68
|
+
@rotate_180_degree = args[:rotate_180_degree] || ROTATE_180_DEGREE
|
69
|
+
end
|
70
|
+
|
71
|
+
def part
|
72
|
+
res = nil
|
73
|
+
start.step(by: step, to: stop) do |degree|
|
74
|
+
step_spoke = spoke.rz(degree)
|
75
|
+
if degree == start
|
76
|
+
res = step_spoke
|
77
|
+
else
|
78
|
+
res += step_spoke
|
79
|
+
end
|
80
|
+
end
|
81
|
+
res
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
attr_reader :count, :width, :height, :diameter, :tread_width,
|
87
|
+
:rotate_180_degree
|
88
|
+
|
89
|
+
# components
|
90
|
+
|
91
|
+
def spoke
|
92
|
+
cube(x: length, y: width, z: height).mx(length / 2)
|
93
|
+
end
|
94
|
+
|
95
|
+
# functions
|
96
|
+
|
97
|
+
def length
|
98
|
+
calc_width = calculated_tread_width(width: tread_width,
|
99
|
+
diameter: diameter)
|
100
|
+
|
101
|
+
(diameter - calc_width + (2 * overlap)) / 2
|
102
|
+
end
|
103
|
+
|
104
|
+
def start
|
105
|
+
rotate_180_degree ? 180 : 0
|
106
|
+
end
|
107
|
+
|
108
|
+
def stop
|
109
|
+
(rotate_180_degree ? 540 : 360) - step
|
110
|
+
end
|
111
|
+
|
112
|
+
def step
|
113
|
+
360.to_f / count
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/flange_heights'
|
5
|
+
require 'scad/btw/concerns/part_commons'
|
6
|
+
require 'scad/btw/concerns/tread_width'
|
7
|
+
require_relative 'flange'
|
8
|
+
|
9
|
+
module Scad
|
10
|
+
module Btw
|
11
|
+
module Component
|
12
|
+
class Tread < JennCad::Part
|
13
|
+
include Scad::Btw::Concerns::PartCommons
|
14
|
+
include Scad::Btw::Concerns::ComponentArgs
|
15
|
+
include Scad::Btw::Concerns::TreadWidth
|
16
|
+
include Scad::Btw::Concerns::FlangeHeights
|
17
|
+
|
18
|
+
TYPE = :addition
|
19
|
+
UPPER_LOWER_DIAMETER_DIFF = 0.2
|
20
|
+
|
21
|
+
ARGS = {
|
22
|
+
prefix: :tread,
|
23
|
+
args: {
|
24
|
+
diameter: {
|
25
|
+
description: 'Wheel diameter. Defaults to: Wheel diameter ' \
|
26
|
+
'defined by `wheel_size` option.',
|
27
|
+
type: :numeric,
|
28
|
+
hide: true
|
29
|
+
},
|
30
|
+
height: {
|
31
|
+
description: 'Tread height. Defaults to: Wheel height defined ' \
|
32
|
+
'by wheel thickness (`wheel_is_thin` flag).',
|
33
|
+
type: :numeric,
|
34
|
+
hide: true
|
35
|
+
},
|
36
|
+
width: {
|
37
|
+
description: "Tread width. Minimum width of #{MIN_TREAD_WIDTH} " \
|
38
|
+
'will be used if provided/default value is ' \
|
39
|
+
'smaller. Defaults to: Diameter * 0.06',
|
40
|
+
type: :numeric,
|
41
|
+
hide: true
|
42
|
+
},
|
43
|
+
flange_height: {
|
44
|
+
description: 'Flange height on tread.',
|
45
|
+
default: FLANGE_INNER_HEIGHT,
|
46
|
+
type: :numeric,
|
47
|
+
hide: true
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
def initialize(args = {})
|
53
|
+
super
|
54
|
+
|
55
|
+
@diameter = args.fetch(:diameter)
|
56
|
+
@height = args.fetch(:height)
|
57
|
+
@width = args[:width]
|
58
|
+
@flange_height = args[:flange_height]
|
59
|
+
@upper_lower_diameter_diff = args[:upper_lower_diameter_diff] ||
|
60
|
+
UPPER_LOWER_DIAMETER_DIFF
|
61
|
+
end
|
62
|
+
|
63
|
+
def part
|
64
|
+
upper_part + lower_part - inner_space
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
attr_reader :diameter, :height, :width, :flange_height,
|
70
|
+
:upper_lower_diameter_diff
|
71
|
+
|
72
|
+
# components
|
73
|
+
|
74
|
+
def upper_part
|
75
|
+
cylinder(d: diameter, h: calc_flange_height)
|
76
|
+
end
|
77
|
+
|
78
|
+
def lower_part
|
79
|
+
cylinder(d1: diameter, d2: upper_diameter, h: tread_height)
|
80
|
+
.mz(calc_flange_height - overlap)
|
81
|
+
end
|
82
|
+
|
83
|
+
def inner_space
|
84
|
+
cylinder(d: inner_diameter - (2 * overlap), h: height + 2).mz(-1)
|
85
|
+
end
|
86
|
+
|
87
|
+
# functions
|
88
|
+
|
89
|
+
def upper_diameter
|
90
|
+
diameter - upper_lower_diameter_diff
|
91
|
+
end
|
92
|
+
|
93
|
+
def tread_height
|
94
|
+
height - calc_flange_height + overlap
|
95
|
+
end
|
96
|
+
|
97
|
+
def inner_diameter
|
98
|
+
calc_width = calculated_tread_width(width: width, diameter: diameter)
|
99
|
+
|
100
|
+
diameter - upper_lower_diameter_diff - (2 * calc_width)
|
101
|
+
end
|
102
|
+
|
103
|
+
def calc_flange_height
|
104
|
+
calculated_inner_flange_height(flange_height)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|