Class: Fitment::Combo

Inherits:
Object
  • Object
show all
Defined in:
lib/fitment/combo.rb

Defined Under Namespace

Classes: DiameterMismatch, Max45Error, MaxError, MinError, ValidationError, WidthMismatch

Constant Summary collapse

BY_RIM_WIDTH =

we’ll go from 6“ to 10” rim width, with emphasis on 7“ to 9” a set of 3 tire widths for each rim width: min, max45, max max45 is the maximum width listed at 45% aspect ratio (no higher) data below is from www.tyresizecalculator.com path: /charts/tire-width-for-a-wheel-rim-size-chart

[[6.0, 175, 185, 225],
[6.5, 195, 195, 235],
[7.0, 195, 215, 255],
[7.5, 205, 225, 265],
[8.0, 225, 245, 275],
[8.5, 235, 255, 295],
[9.0, 255, 275, 305],
[9.5, 255, 285, 315],
[10.0, 275, 295, 295]]
BELOW_6 =
[[3.5, 125, nil, 135],
[4.0, 135, nil, 145],
[4.5, 145, nil, 165],
[5.0, 155, nil, 185],
[5.5, 165, 165, 205]]
ABOVE_10 =
[[10.5, 285, 315, 315],
[11.0, 305, 315, 345],
[11.5, 315, 335, 345],
[12.0, 325, 345, 345],
[12.5, 345, 345, 345],
[13.0, 355, 355, 355]]
MODELS =

Now, let’s model the above table with equations For every x (rim width inches), we have 3 ys (tire width millimeters) min, max45, max

{
  # Linear: y = a + bx (or: mx + b)
  simple: [20, 40, 75],            # assume 25.4 slope
  basic: [20.689, 38.467, 74.022], # assume 25.4 slope
  linear: [[13.222, 26.333],       # r2 = 0.9917
           [12.333, 28.667],       # r2 = 0.9941
           [71.889, 25.667]],      # r2 = 0.9926
}
TIRE_EXCESS =

extra rubber material near the bead relevant to fitment

15

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tire:, wheel:, model: :actual) ⇒ Combo

Returns a new instance of Combo.



132
133
134
135
136
# File 'lib/fitment/combo.rb', line 132

def initialize(tire:, wheel:, model: :actual)
  @tire = tire
  @wheel = wheel
  @model = model
end

Instance Attribute Details

#modelObject

Returns the value of attribute model.



130
131
132
# File 'lib/fitment/combo.rb', line 130

def model
  @model
end

#tireObject

Returns the value of attribute tire.



130
131
132
# File 'lib/fitment/combo.rb', line 130

def tire
  @tire
end

#wheelObject

Returns the value of attribute wheel.



130
131
132
# File 'lib/fitment/combo.rb', line 130

def wheel
  @wheel
end

Class Method Details

.new_with_offset(t, r, d, w, o) ⇒ Object



124
125
126
# File 'lib/fitment/combo.rb', line 124

def self.new_with_offset(t, r, d, w, o)
  self.new_with_params(t, r, d, w, o, et: false)
end

.new_with_params(tread_with, ratio, diameter, width, offset, et: true) ⇒ Object



115
116
117
118
119
120
121
122
# File 'lib/fitment/combo.rb', line 115

def self.new_with_params(tread_with, ratio, diameter, width, offset,
                         et: true)
  tire = Tire.new(tread_with, ratio, diameter)
  wheel = et ?
            Wheel.new(diameter, width, offset) :
            OffsetWheel.new(diameter, width, offset)
  Combo.new(wheel: wheel, tire: tire)
end

.snap(flt) ⇒ Object

rounds to e.g. 235, 245, 255, etc. (per industry convention)



74
75
76
# File 'lib/fitment/combo.rb', line 74

def self.snap(flt)
  ((flt - 5) / 10.0).round * 10 + 5
end

.tire_widths(rim_width_in, model = :actual) ⇒ Object

linear model, given a rim width in inches, determine:

  • minimum tire width in mm

  • maximum tire width limited to 45% aspect ratio

  • maximum tire width above 45% aspect ratio (big truck tires)

  • models: :actual, :simple, :basic, :linear, :best, :extended



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/fitment/combo.rb', line 83

def self.tire_widths(rim_width_in, model = :actual)
  if model == :actual
    (BY_RIM_WIDTH + BELOW_6 + ABOVE_10).each { |row|
      return row[1..3] if rim_width_in == row[0]
    }
    raise("no match for model :actual, width #{rim_width_in}")
  end
  params = MODELS.fetch(model)
  case model
  when :simple, :basic
    b = MM_PER_INCH
    params.map { |a| snap(a + b * rim_width_in) }
  when :linear
    params.map { |(a, b)| snap(a + b * rim_width_in) }
  when :best, :extended
    params.map { |(model, a, b)|
      snap(case model
           when :logarithmic
             a + b * Math.log(rim_width_in)
           when :linear
             a + b * rim_width_in
           when :power
             a * rim_width_in ** b
           else
             raise("unknown model: #{model}")
           end)
    }
  else
    raise("unknown model: #{model}")
  end
end

Instance Method Details

#bounding_boxObject



195
196
197
198
# File 'lib/fitment/combo.rb', line 195

def bounding_box
  [[short_width, tall_width].max,
   [short_height, tall_height].max,]
end

#increase(other) ⇒ Object Also known as: clearance

returns [inside increase, outside increase, diameter increase] for each of :wheel and :tire



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/fitment/combo.rb', line 203

def increase(other)
  short_width_increase = other.short_width - self.short_width
  short_height_increase = other.short_height - self.short_height
  tall_width_increase = other.tall_width - self.tall_width
  tall_height_increase = other.tall_height - self.tall_height

  # smaller et on other wheel moves it outside; more inside clearance
  et_decrease = self.wheel.et - other.wheel.et

  halfwidth = short_width_increase * 0.5
  wheel = [halfwidth - et_decrease, # inner expansion
           halfwidth + et_decrease, # outer expansion
           short_height_increase]   # height increase

  halfwidth = tall_width_increase * 0.5
  tire = [halfwidth - et_decrease,  # inside expansion
          halfwidth + et_decrease,  # outside expansion
          tall_height_increase]     # height increase

  { wheel: wheel.map { |flt| flt.round(2) },
    tire: tire.map { |flt| flt.round(2) }, }
end

#short_boxObject



179
180
181
# File 'lib/fitment/combo.rb', line 179

def short_box
  [short_width.round(2), short_height.round(2)]
end

#short_heightObject



175
176
177
# File 'lib/fitment/combo.rb', line 175

def short_height
  Fitment.mm(@wheel.diameter) + TIRE_EXCESS * 2
end

#short_widthObject



171
172
173
# File 'lib/fitment/combo.rb', line 171

def short_width
  Fitment.mm(@wheel.width) + TIRE_EXCESS * 2
end

#tall_boxObject



191
192
193
# File 'lib/fitment/combo.rb', line 191

def tall_box
  [tall_width.round(2), tall_height.round(2)]
end

#tall_heightObject



187
188
189
# File 'lib/fitment/combo.rb', line 187

def tall_height
  @tire.od_mm
end

#tall_widthObject



183
184
185
# File 'lib/fitment/combo.rb', line 183

def tall_width
  @tire.width
end

#to_sObject



138
139
140
# File 'lib/fitment/combo.rb', line 138

def to_s
  [@tire, @wheel].join(' ')
end

#validate!Object



166
167
168
169
# File 'lib/fitment/combo.rb', line 166

def validate!
  validate_diameter!
  validate_width!
end

#validate_diameter!Object

Raises:



142
143
144
145
146
# File 'lib/fitment/combo.rb', line 142

def validate_diameter!
  wd, twd = @wheel.diameter, @tire.wheel_diameter
  raise(DiameterMismatch, "wheel: %i; tire: %i" % [wd, twd]) if wd != twd
  true
end

#validate_width!Object

Raises:



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/fitment/combo.rb', line 148

def validate_width!
  msg = "tire width %i %s %s %i for wheel width %i"

  min, max45, max = self.class.tire_widths(@wheel.width, @model)
  raise(MinError, "no min available for width %i" % @wheel.width) if !min
  if @tire.width < min
    raise(MinError, msg % [@tire.width, '<', 'min', min, @wheel.width])
  end
  if max45 and @tire.ratio <= 45 and @tire.width > max45
    raise(Max45Error, msg % [@tire.width, '>', 'max45', max45, @wheel.width])
  end
  raise(MaxError, "no max available for width %i" % @wheel.width) if !max
  if @tire.width > max
    raise(MaxError, msg % [@tire.width, '>', 'max', max, @wheel.width])
  end
  true
end