feat: ui rework and gear generator
This commit is contained in:
91
lib/model/gear_configurator.dart
Normal file
91
lib/model/gear_configurator.dart
Normal file
@ -0,0 +1,91 @@
|
||||
import 'package:abawo_bt_app/model/gear_ratio_codec.dart';
|
||||
|
||||
enum GearRetentionMode { keepHighest, keepAll }
|
||||
|
||||
class GearConfiguratorCalculation {
|
||||
const GearConfiguratorCalculation({
|
||||
required this.ratios,
|
||||
required this.discardedBelowRange,
|
||||
required this.discardedAboveRange,
|
||||
required this.duplicateCount,
|
||||
required this.truncatedCount,
|
||||
});
|
||||
|
||||
final List<double> ratios;
|
||||
final int discardedBelowRange;
|
||||
final int discardedAboveRange;
|
||||
final int duplicateCount;
|
||||
final int truncatedCount;
|
||||
}
|
||||
|
||||
GearConfiguratorCalculation calculateGearRatios({
|
||||
required List<int> chainrings,
|
||||
required List<int> sprockets,
|
||||
required GearRetentionMode mode,
|
||||
int maxRatios = 32,
|
||||
}) {
|
||||
final sortedChainrings = List<int>.from(chainrings)..sort();
|
||||
final sortedSprockets = List<int>.from(sprockets)..sort((a, b) => b - a);
|
||||
|
||||
var discardedBelowRange = 0;
|
||||
var discardedAboveRange = 0;
|
||||
var duplicateCount = 0;
|
||||
final encoded = <int>{};
|
||||
final ratios = <double>[];
|
||||
|
||||
void addRatio(double ratio) {
|
||||
if (ratio < gearRatioMin) {
|
||||
discardedBelowRange++;
|
||||
return;
|
||||
}
|
||||
if (ratio > gearRatioMax) {
|
||||
discardedAboveRange++;
|
||||
return;
|
||||
}
|
||||
|
||||
final raw = encodeGearRatioByte(ratio);
|
||||
if (!encoded.add(raw)) {
|
||||
duplicateCount++;
|
||||
return;
|
||||
}
|
||||
ratios.add(decodeGearRatioByte(raw));
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case GearRetentionMode.keepAll:
|
||||
for (final chainring in sortedChainrings) {
|
||||
for (final sprocket in sortedSprockets) {
|
||||
addRatio(chainring / sprocket);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GearRetentionMode.keepHighest:
|
||||
var threshold = double.negativeInfinity;
|
||||
for (final chainring in sortedChainrings) {
|
||||
final beforeLength = ratios.length;
|
||||
for (final sprocket in sortedSprockets) {
|
||||
final ratio = chainring / sprocket;
|
||||
if (ratio >= threshold) {
|
||||
addRatio(ratio);
|
||||
}
|
||||
}
|
||||
if (ratios.length > beforeLength) {
|
||||
threshold = ratios.reduce((a, b) => a > b ? a : b);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ratios.sort();
|
||||
final truncatedCount =
|
||||
ratios.length > maxRatios ? ratios.length - maxRatios : 0;
|
||||
final limited = ratios.take(maxRatios).toList(growable: false);
|
||||
|
||||
return GearConfiguratorCalculation(
|
||||
ratios: limited,
|
||||
discardedBelowRange: discardedBelowRange,
|
||||
discardedAboveRange: discardedAboveRange,
|
||||
duplicateCount: duplicateCount,
|
||||
truncatedCount: truncatedCount,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user