fiber_pattern 0.3.0 → 0.5.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 +4 -4
- data/lib/fiber_pattern/body_measurements.rb +61 -0
- data/lib/fiber_pattern/ease.rb +74 -0
- data/lib/fiber_pattern/garment_sizing.rb +76 -0
- data/lib/fiber_pattern/size_chart.rb +86 -0
- data/lib/fiber_pattern/sizing.rb +8 -2
- data/lib/fiber_pattern/stitch_pattern.rb +139 -0
- data/lib/fiber_pattern/version.rb +1 -1
- data/lib/fiber_pattern.rb +5 -0
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 86098b154ca5d374ea82112b74c4bcfde885d6da22aa071c4c0f8b87fc2c89bd
|
|
4
|
+
data.tar.gz: 6744cff995e936ff00774ffa69e1829c1992cfe5901d491ba233fcd5e734d5fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c9daa9034c4a2a6b5d46c3e09a999a78c11245424163ac792194d8e9d575c95f7146d4e447de386c642ea51cc17b9a8b7477533a04ba7080fc0c09b4b5df3c49
|
|
7
|
+
data.tar.gz: a7595ab55c4c0fa5861a39af96d373958cc6f39359f1bb2feddfa3b94187e4de7cf81c403cb3b17ac92c0fcdf395a04526507c22a25c91d04c832b182f828c3d
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Value object representing key body dimensions.
|
|
5
|
+
#
|
|
6
|
+
# Accepts any set of named measurements as keyword arguments.
|
|
7
|
+
# Each value should be a FiberUnits::Length.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# body = FiberPattern::BodyMeasurements.new(
|
|
11
|
+
# bust: 36.inches,
|
|
12
|
+
# waist: 30.inches,
|
|
13
|
+
# hip: 38.inches,
|
|
14
|
+
# arm_length: 24.inches
|
|
15
|
+
# )
|
|
16
|
+
# body.bust # => 36.inches
|
|
17
|
+
# body[:waist] # => 30.inches
|
|
18
|
+
# body.measurements # => [:bust, :waist, :hip, :arm_length]
|
|
19
|
+
class BodyMeasurements
|
|
20
|
+
# @return [Hash<Symbol, FiberUnits::Length>] all measurements
|
|
21
|
+
attr_reader :data
|
|
22
|
+
|
|
23
|
+
# @param measurements [Hash<Symbol, FiberUnits::Length>] named body measurements
|
|
24
|
+
def initialize(**measurements)
|
|
25
|
+
raise ArgumentError, "at least one measurement is required" if measurements.empty?
|
|
26
|
+
|
|
27
|
+
@data = measurements.freeze
|
|
28
|
+
define_accessors!
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the measurement names.
|
|
32
|
+
#
|
|
33
|
+
# @return [Array<Symbol>]
|
|
34
|
+
def measurements
|
|
35
|
+
data.keys
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Hash-style access to a measurement.
|
|
39
|
+
#
|
|
40
|
+
# @param name [Symbol]
|
|
41
|
+
# @return [FiberUnits::Length, nil]
|
|
42
|
+
def [](name)
|
|
43
|
+
data[name]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns measurements as a plain hash.
|
|
47
|
+
#
|
|
48
|
+
# @return [Hash<Symbol, FiberUnits::Length>]
|
|
49
|
+
def to_h
|
|
50
|
+
data.dup
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def define_accessors!
|
|
56
|
+
data.each_key do |name|
|
|
57
|
+
define_singleton_method(name) { data[name] }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Value object representing ease preferences per measurement.
|
|
5
|
+
#
|
|
6
|
+
# Ease is the difference between body measurements and finished garment
|
|
7
|
+
# measurements. Positive ease creates a looser fit; negative ease creates
|
|
8
|
+
# a tighter fit.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# ease = FiberPattern::Ease.new(
|
|
12
|
+
# bust: 4.inches,
|
|
13
|
+
# waist: 2.inches,
|
|
14
|
+
# hip: 2.inches
|
|
15
|
+
# )
|
|
16
|
+
# ease.bust # => 4.inches
|
|
17
|
+
# ease[:waist] # => 2.inches
|
|
18
|
+
# ease.for(:bust) # => 4.inches
|
|
19
|
+
class Ease
|
|
20
|
+
# @return [Hash<Symbol, FiberUnits::Length>] all ease values
|
|
21
|
+
attr_reader :data
|
|
22
|
+
|
|
23
|
+
# @param ease_values [Hash<Symbol, FiberUnits::Length>] named ease values
|
|
24
|
+
def initialize(**ease_values)
|
|
25
|
+
raise ArgumentError, "at least one ease value is required" if ease_values.empty?
|
|
26
|
+
|
|
27
|
+
@data = ease_values.freeze
|
|
28
|
+
define_accessors!
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the ease value for a given measurement.
|
|
32
|
+
#
|
|
33
|
+
# @param name [Symbol]
|
|
34
|
+
# @return [FiberUnits::Length]
|
|
35
|
+
# @raise [ArgumentError] if no ease is defined for the measurement
|
|
36
|
+
def for(name)
|
|
37
|
+
raise ArgumentError, "no ease defined for #{name.inspect}" unless data.key?(name)
|
|
38
|
+
|
|
39
|
+
data[name]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Hash-style access to an ease value.
|
|
43
|
+
#
|
|
44
|
+
# @param name [Symbol]
|
|
45
|
+
# @return [FiberUnits::Length, nil]
|
|
46
|
+
def [](name)
|
|
47
|
+
data[name]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Returns all measurement names that have ease defined.
|
|
51
|
+
#
|
|
52
|
+
# @return [Array<Symbol>]
|
|
53
|
+
def measurements
|
|
54
|
+
data.keys
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Returns ease values as a plain hash.
|
|
58
|
+
#
|
|
59
|
+
# @return [Hash<Symbol, FiberUnits::Length>]
|
|
60
|
+
def to_h
|
|
61
|
+
data.dup
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def define_accessors!
|
|
67
|
+
data.each_key do |name|
|
|
68
|
+
next if name == :for # avoid overriding #for
|
|
69
|
+
|
|
70
|
+
define_singleton_method(name) { data[name] }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Combines body measurements with ease to produce finished garment dimensions.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# body = FiberPattern::BodyMeasurements.new(bust: 36.inches, waist: 30.inches)
|
|
8
|
+
# ease = FiberPattern::Ease.new(bust: 4.inches, waist: 2.inches)
|
|
9
|
+
# garment = FiberPattern::GarmentSizing.new(body: body, ease: ease)
|
|
10
|
+
# garment.bust # => 40.inches
|
|
11
|
+
# garment.waist # => 32.inches
|
|
12
|
+
class GarmentSizing
|
|
13
|
+
# @return [FiberPattern::BodyMeasurements]
|
|
14
|
+
attr_reader :body
|
|
15
|
+
|
|
16
|
+
# @return [FiberPattern::Ease]
|
|
17
|
+
attr_reader :ease
|
|
18
|
+
|
|
19
|
+
# @param body [FiberPattern::BodyMeasurements] body measurements
|
|
20
|
+
# @param ease [FiberPattern::Ease] ease preferences
|
|
21
|
+
def initialize(body:, ease:)
|
|
22
|
+
validate!(body, ease)
|
|
23
|
+
@body = body
|
|
24
|
+
@ease = ease
|
|
25
|
+
define_accessors!
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns the finished garment dimension for a given measurement.
|
|
29
|
+
#
|
|
30
|
+
# @param name [Symbol]
|
|
31
|
+
# @return [FiberUnits::Length] body measurement + ease
|
|
32
|
+
# @raise [ArgumentError] if the measurement is not defined
|
|
33
|
+
def dimension(name)
|
|
34
|
+
raise ArgumentError, "unknown measurement #{name.inspect}" unless body.data.key?(name)
|
|
35
|
+
|
|
36
|
+
body[name] + (ease[name] || zero_length(body[name]))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Hash-style access to finished dimensions.
|
|
40
|
+
#
|
|
41
|
+
# @param name [Symbol]
|
|
42
|
+
# @return [FiberUnits::Length]
|
|
43
|
+
def [](name)
|
|
44
|
+
dimension(name)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Returns all finished garment dimensions.
|
|
48
|
+
#
|
|
49
|
+
# @return [Hash<Symbol, FiberUnits::Length>]
|
|
50
|
+
def dimensions
|
|
51
|
+
body.measurements.each_with_object({}) do |name, result|
|
|
52
|
+
result[name] = dimension(name)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def validate!(body, ease)
|
|
59
|
+
ease.measurements.each do |name|
|
|
60
|
+
unless body.measurements.include?(name)
|
|
61
|
+
raise ArgumentError, "ease defines #{name.inspect} but body measurements does not"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def define_accessors!
|
|
67
|
+
body.measurements.each do |name|
|
|
68
|
+
define_singleton_method(name) { dimension(name) }
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def zero_length(reference)
|
|
73
|
+
reference * 0
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Standard size chart based on Craft Yarn Council (CYC) guidelines.
|
|
5
|
+
#
|
|
6
|
+
# Provides lookup of standard body measurements by size, and a closest-size
|
|
7
|
+
# finder that matches body measurements to the nearest standard size.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# chart = FiberPattern::SizeChart.new
|
|
11
|
+
# chart.size(:m) # => { bust: 36.inches, waist: 28.inches, hip: 38.inches }
|
|
12
|
+
# chart.closest_size(bust: 37.inches, waist: 29.inches, hip: 39.inches) # => :m
|
|
13
|
+
class SizeChart
|
|
14
|
+
# CYC standard women's body measurements (inches).
|
|
15
|
+
# Source: Craft Yarn Council Standards & Guidelines
|
|
16
|
+
CYC_WOMEN = {
|
|
17
|
+
xs: {bust: 28, waist: 20, hip: 30},
|
|
18
|
+
s: {bust: 32, waist: 24, hip: 34},
|
|
19
|
+
m: {bust: 36, waist: 28, hip: 38},
|
|
20
|
+
l: {bust: 40, waist: 32, hip: 42},
|
|
21
|
+
xl: {bust: 44, waist: 36, hip: 46},
|
|
22
|
+
xxl: {bust: 48, waist: 40, hip: 50},
|
|
23
|
+
xxxl: {bust: 52, waist: 44, hip: 54},
|
|
24
|
+
xxxxl: {bust: 56, waist: 48, hip: 58},
|
|
25
|
+
xxxxxl: {bust: 60, waist: 52, hip: 62}
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
# @return [Hash<Symbol, Hash<Symbol, FiberUnits::Length>>] size chart data
|
|
29
|
+
attr_reader :chart
|
|
30
|
+
|
|
31
|
+
# @return [Array<Symbol>] ordered size names
|
|
32
|
+
attr_reader :sizes
|
|
33
|
+
|
|
34
|
+
# Creates a new size chart.
|
|
35
|
+
#
|
|
36
|
+
# @param chart [Hash<Symbol, Hash<Symbol, Numeric>>] raw chart data mapping size names
|
|
37
|
+
# to measurement hashes. Values are converted to inches. Defaults to CYC_WOMEN.
|
|
38
|
+
def initialize(chart: CYC_WOMEN)
|
|
39
|
+
@chart = chart.each_with_object({}) do |(size_name, measurements), result|
|
|
40
|
+
result[size_name] = measurements.transform_values { |v| v.is_a?(Numeric) ? v.inches : v }
|
|
41
|
+
end.freeze
|
|
42
|
+
@sizes = @chart.keys.freeze
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns body measurements for a standard size.
|
|
46
|
+
#
|
|
47
|
+
# @param name [Symbol] size name
|
|
48
|
+
# @return [Hash<Symbol, FiberUnits::Length>]
|
|
49
|
+
# @raise [ArgumentError] if the size is not in the chart
|
|
50
|
+
def size(name)
|
|
51
|
+
raise ArgumentError, "unknown size #{name.inspect}" unless chart.key?(name)
|
|
52
|
+
|
|
53
|
+
chart[name]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Finds the closest standard size to the given body measurements.
|
|
57
|
+
#
|
|
58
|
+
# Compares using the sum of squared differences across all provided
|
|
59
|
+
# measurements. Only measurements present in both the query and the
|
|
60
|
+
# chart are compared.
|
|
61
|
+
#
|
|
62
|
+
# @param measurements [Hash<Symbol, FiberUnits::Length>] body measurements to match
|
|
63
|
+
# @return [Symbol] the closest size name
|
|
64
|
+
# @raise [ArgumentError] if no measurements overlap with the chart
|
|
65
|
+
def closest_size(**measurements)
|
|
66
|
+
comparable_keys = measurements.keys & chart.values.first.keys
|
|
67
|
+
raise ArgumentError, "no comparable measurements provided" if comparable_keys.empty?
|
|
68
|
+
|
|
69
|
+
sizes.min_by do |size_name|
|
|
70
|
+
size_data = chart[size_name]
|
|
71
|
+
comparable_keys.sum do |key|
|
|
72
|
+
diff = measurements[key].value - size_data[key].value
|
|
73
|
+
diff * diff
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns a BodyMeasurements object for a standard size.
|
|
79
|
+
#
|
|
80
|
+
# @param name [Symbol] size name
|
|
81
|
+
# @return [FiberPattern::BodyMeasurements]
|
|
82
|
+
def body_measurements_for(name)
|
|
83
|
+
BodyMeasurements.new(**size(name))
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
data/lib/fiber_pattern/sizing.rb
CHANGED
|
@@ -9,11 +9,16 @@ module FiberPattern
|
|
|
9
9
|
# @return [FiberPattern::Repeat, nil] optional stitch repeat to round stitch counts to
|
|
10
10
|
attr_reader :repeat
|
|
11
11
|
|
|
12
|
+
# @return [FiberPattern::StitchPattern, nil] optional stitch pattern for width adjustment
|
|
13
|
+
attr_reader :stitch_pattern
|
|
14
|
+
|
|
12
15
|
# @param gauge [Object] gauge object used to derive stitch counts
|
|
13
16
|
# @param repeat [FiberPattern::Repeat, nil] optional stitch repeat to round stitch counts to
|
|
14
|
-
|
|
17
|
+
# @param stitch_pattern [FiberPattern::StitchPattern, nil] optional stitch pattern for width adjustment
|
|
18
|
+
def initialize(gauge:, repeat: nil, stitch_pattern: nil)
|
|
15
19
|
@gauge = gauge
|
|
16
20
|
@repeat = repeat
|
|
21
|
+
@stitch_pattern = stitch_pattern
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
# Calculates the number of stitches required to reach a given width, based on the provided gauge.
|
|
@@ -21,7 +26,8 @@ module FiberPattern
|
|
|
21
26
|
# @param width [Object] desired finished width in units accepted by the gauge
|
|
22
27
|
# @return [Integer] number of stitches required to reach the requested width
|
|
23
28
|
def cast_on_for(width)
|
|
24
|
-
|
|
29
|
+
adjusted_width = stitch_pattern ? stitch_pattern.adjust_width(width) : width
|
|
30
|
+
stitches = gauge.required_stitches(adjusted_width)
|
|
25
31
|
|
|
26
32
|
return stitches unless repeat
|
|
27
33
|
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module FiberPattern
|
|
4
|
+
# Models how a stitch pattern affects fabric dimensions and yarn consumption
|
|
5
|
+
# relative to stockinette. Cables compress width and consume more yarn;
|
|
6
|
+
# lace opens up fabric and uses less yarn per area.
|
|
7
|
+
class StitchPattern
|
|
8
|
+
# @return [String] human-readable name of the stitch pattern
|
|
9
|
+
attr_reader :name
|
|
10
|
+
|
|
11
|
+
# @return [FiberPattern::Repeat, nil] optional stitch repeat for this pattern
|
|
12
|
+
attr_reader :repeat
|
|
13
|
+
|
|
14
|
+
# @return [Float] multiplier vs stockinette for fabric width (< 1 = pulls in)
|
|
15
|
+
attr_reader :width_factor
|
|
16
|
+
|
|
17
|
+
# @return [Float] multiplier vs stockinette for yarn consumption (> 1 = uses more)
|
|
18
|
+
attr_reader :yarn_factor
|
|
19
|
+
|
|
20
|
+
# @param name [String] human-readable name of the stitch pattern
|
|
21
|
+
# @param repeat [FiberPattern::Repeat, nil] optional stitch repeat
|
|
22
|
+
# @param width_factor [Float] width multiplier vs stockinette (default: 1.0)
|
|
23
|
+
# @param yarn_factor [Float] yarn consumption multiplier vs stockinette (default: 1.0)
|
|
24
|
+
def initialize(name:, repeat: nil, width_factor: 1.0, yarn_factor: 1.0)
|
|
25
|
+
@name = name.freeze
|
|
26
|
+
@repeat = repeat
|
|
27
|
+
@width_factor = width_factor.to_f
|
|
28
|
+
@yarn_factor = yarn_factor.to_f
|
|
29
|
+
validate!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Returns the stockinette-equivalent width needed to achieve the desired
|
|
33
|
+
# finished width in this stitch pattern.
|
|
34
|
+
#
|
|
35
|
+
# @param width [FiberUnits::Length] desired finished width
|
|
36
|
+
# @return [FiberUnits::Length] stockinette-equivalent width to knit
|
|
37
|
+
def adjust_width(width)
|
|
38
|
+
(width.value / width_factor).round(2).public_send(width.unit)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Adjusts a base yardage estimate to account for this pattern's yarn consumption.
|
|
42
|
+
#
|
|
43
|
+
# @param yardage [FiberUnits::Length] base yardage assuming stockinette
|
|
44
|
+
# @return [FiberUnits::Length] adjusted yardage for this stitch pattern
|
|
45
|
+
def adjust_yardage(yardage)
|
|
46
|
+
(yardage.value * yarn_factor).round(2).public_send(yardage.unit)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Preset definitions for common stitch patterns.
|
|
50
|
+
|
|
51
|
+
def self.stockinette
|
|
52
|
+
new(name: "Stockinette", width_factor: 1.0, yarn_factor: 1.0)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def self.garter
|
|
56
|
+
new(name: "Garter", width_factor: 1.0, yarn_factor: 1.05)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.rib_1x1
|
|
60
|
+
new(
|
|
61
|
+
name: "1x1 Rib",
|
|
62
|
+
repeat: Repeat.new(multiple: 2.stitches),
|
|
63
|
+
width_factor: 0.90,
|
|
64
|
+
yarn_factor: 1.10
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.rib_2x2
|
|
69
|
+
new(
|
|
70
|
+
name: "2x2 Rib",
|
|
71
|
+
repeat: Repeat.new(multiple: 4.stitches),
|
|
72
|
+
width_factor: 0.85,
|
|
73
|
+
yarn_factor: 1.12
|
|
74
|
+
)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.seed
|
|
78
|
+
new(
|
|
79
|
+
name: "Seed Stitch",
|
|
80
|
+
repeat: Repeat.new(multiple: 2.stitches),
|
|
81
|
+
width_factor: 0.95,
|
|
82
|
+
yarn_factor: 1.05
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Crochet preset definitions.
|
|
87
|
+
|
|
88
|
+
def self.single_crochet
|
|
89
|
+
new(name: "Single Crochet", width_factor: 1.0, yarn_factor: 1.0)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def self.half_double_crochet
|
|
93
|
+
new(name: "Half Double Crochet", width_factor: 1.05, yarn_factor: 1.15)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.double_crochet
|
|
97
|
+
new(name: "Double Crochet", width_factor: 1.10, yarn_factor: 1.25)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.treble_crochet
|
|
101
|
+
new(name: "Treble Crochet", width_factor: 1.15, yarn_factor: 1.35)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def self.moss_stitch
|
|
105
|
+
new(
|
|
106
|
+
name: "Moss Stitch",
|
|
107
|
+
repeat: Repeat.new(multiple: 2.stitches),
|
|
108
|
+
width_factor: 1.05,
|
|
109
|
+
yarn_factor: 1.10
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def self.shell_stitch
|
|
114
|
+
new(
|
|
115
|
+
name: "Shell Stitch",
|
|
116
|
+
repeat: Repeat.new(multiple: 6.stitches, offset: 1.stitches),
|
|
117
|
+
width_factor: 1.15,
|
|
118
|
+
yarn_factor: 1.30
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.v_stitch
|
|
123
|
+
new(
|
|
124
|
+
name: "V-Stitch",
|
|
125
|
+
repeat: Repeat.new(multiple: 2.stitches),
|
|
126
|
+
width_factor: 1.10,
|
|
127
|
+
yarn_factor: 0.90
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
def validate!
|
|
134
|
+
raise ArgumentError, "name must be a non-empty string" if name.nil? || name.empty?
|
|
135
|
+
raise ArgumentError, "width_factor must be positive" unless width_factor.positive?
|
|
136
|
+
raise ArgumentError, "yarn_factor must be positive" unless yarn_factor.positive?
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
data/lib/fiber_pattern.rb
CHANGED
|
@@ -5,10 +5,15 @@ require "fiber_gauge"
|
|
|
5
5
|
require_relative "fiber_pattern/version"
|
|
6
6
|
require_relative "fiber_pattern/sizing"
|
|
7
7
|
require_relative "fiber_pattern/repeat"
|
|
8
|
+
require_relative "fiber_pattern/stitch_pattern"
|
|
8
9
|
require_relative "fiber_pattern/scaling"
|
|
9
10
|
require_relative "fiber_pattern/shaping"
|
|
10
11
|
require_relative "fiber_pattern/grade_rules"
|
|
11
12
|
require_relative "fiber_pattern/grader"
|
|
13
|
+
require_relative "fiber_pattern/body_measurements"
|
|
14
|
+
require_relative "fiber_pattern/ease"
|
|
15
|
+
require_relative "fiber_pattern/garment_sizing"
|
|
16
|
+
require_relative "fiber_pattern/size_chart"
|
|
12
17
|
|
|
13
18
|
# Utilities for generating fiber pattern measurements from gauge data.
|
|
14
19
|
module FiberPattern
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fiber_pattern
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Meagan Waller
|
|
@@ -76,12 +76,17 @@ files:
|
|
|
76
76
|
- LICENSE.txt
|
|
77
77
|
- README.md
|
|
78
78
|
- lib/fiber_pattern.rb
|
|
79
|
+
- lib/fiber_pattern/body_measurements.rb
|
|
80
|
+
- lib/fiber_pattern/ease.rb
|
|
81
|
+
- lib/fiber_pattern/garment_sizing.rb
|
|
79
82
|
- lib/fiber_pattern/grade_rules.rb
|
|
80
83
|
- lib/fiber_pattern/grader.rb
|
|
81
84
|
- lib/fiber_pattern/repeat.rb
|
|
82
85
|
- lib/fiber_pattern/scaling.rb
|
|
83
86
|
- lib/fiber_pattern/shaping.rb
|
|
87
|
+
- lib/fiber_pattern/size_chart.rb
|
|
84
88
|
- lib/fiber_pattern/sizing.rb
|
|
89
|
+
- lib/fiber_pattern/stitch_pattern.rb
|
|
85
90
|
- lib/fiber_pattern/version.rb
|
|
86
91
|
- sig/fiber_pattern.rbs
|
|
87
92
|
homepage: https://github.com/meaganewaller/craftos/tree/main/gems/fiber_pattern
|