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.



125
126
127
128
129
# File 'lib/fitment/combo.rb', line 125

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

Instance Attribute Details

#modelObject

Returns the value of attribute model.



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

def model
  @model
end

#tireObject

Returns the value of attribute tire.



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

def tire
  @tire
end

#wheelObject

Returns the value of attribute wheel.



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

def wheel
  @wheel
end

Class Method Details

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



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

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

.snap(flt) ⇒ Object

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



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

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



82
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
# File 'lib/fitment/combo.rb', line 82

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



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

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



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/fitment/combo.rb', line 196

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

#report(other) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/fitment/combo.rb', line 220

def report(other)
  increase = self.increase other
  wheel = increase.fetch :wheel
  tire = increase.fetch :tire

  rpt = []
  rpt << "Wheel: %s > %s" % [@wheel, other.wheel]
  rpt << "  Inside extension:   %.1f mm" % wheel[0]
  rpt << "  Outside extension:  %.1f mm" % wheel[1]
  rpt << "  Diameter extension: %.1f mm" % wheel[2]
  rpt << "Tire: %s > %s" % [@tire, other.tire]
  rpt << "  Inside extension:   %.1f mm" % tire[0]
  rpt << "  Outside extension:  %.1f mm" % tire[1]
  rpt << "  Diameter extension: %.1f mm" % tire[2]

  rpt.join "\n"
end

#short_boxObject



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

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

#short_heightObject



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

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

#short_widthObject



164
165
166
# File 'lib/fitment/combo.rb', line 164

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

#tall_boxObject



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

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

#tall_heightObject



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

def tall_height
  @tire.od_mm
end

#tall_widthObject



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

def tall_width
  @tire.width
end

#to_sObject



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

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

#validate!Object



159
160
161
162
# File 'lib/fitment/combo.rb', line 159

def validate!
  validate_diameter!
  validate_width!
end

#validate_diameter!Object

Raises:



135
136
137
138
139
# File 'lib/fitment/combo.rb', line 135

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:



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/fitment/combo.rb', line 141

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 <= 0.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