fix: cadre toujours orange
This commit is contained in:
@@ -162,37 +162,30 @@ class _CaptureScreenState extends State<CaptureScreen>
|
|||||||
|
|
||||||
bool get _objectReady => _primaryObject != null;
|
bool get _objectReady => _primaryObject != null;
|
||||||
|
|
||||||
/// Couleur du cadre selon le parallélisme détecté par l'IMU.
|
/// Couleur du cadre : dépend UNIQUEMENT du parallélisme IMU.
|
||||||
|
/// (La détection d'objet sert seulement à dessiner une boîte, elle ne
|
||||||
|
/// bloque jamais le passage au vert.)
|
||||||
Color get _frameColor {
|
Color get _frameColor {
|
||||||
final bool imuAligned =
|
final bool imuAligned =
|
||||||
_parallelismData == null || _parallelismData!.isAligned;
|
_parallelismData == null || _parallelismData!.isAligned;
|
||||||
// Vert UNIQUEMENT si l'appareil est parallèle ET un objet est bien cadré.
|
return imuAligned ? const Color(0xFF00FF00) : Colors.orange;
|
||||||
if (imuAligned && _objectReady) return const Color(0xFF00FF00);
|
|
||||||
return Colors.orange;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Message d'aide selon le parallélisme + détection d'objet.
|
/// Message d'aide selon le parallélisme IMU.
|
||||||
String get _alignmentMessage {
|
String get _alignmentMessage {
|
||||||
final bool imuAligned =
|
if (_parallelismData == null ||
|
||||||
_parallelismData == null || _parallelismData!.isAligned;
|
_parallelismData!.status == ParallelismStatus.unknown) {
|
||||||
|
|
||||||
// Cas idéal : tout est bon
|
|
||||||
if (imuAligned && _objectReady) {
|
|
||||||
return 'PARALLÈLE OK — PRÊT À PHOTOGRAPHIER';
|
|
||||||
}
|
|
||||||
|
|
||||||
// IMU bon mais pas d'objet correctement cadré
|
|
||||||
if (imuAligned && !_objectReady) {
|
|
||||||
return _detectedObjects.isEmpty
|
|
||||||
? 'AUCUN OBJET DÉTECTÉ — APPROCHEZ-VOUS'
|
|
||||||
: 'CENTREZ L\'OBJET DANS LE CADRE';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_parallelismData == null) {
|
|
||||||
return 'ALIGNEZ LA CIBLE DANS LE CADRE';
|
return 'ALIGNEZ LA CIBLE DANS LE CADRE';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Message directif selon l'axe le plus dévié
|
// Aligné → message de validation (avec bonus si un objet est cadré)
|
||||||
|
if (_parallelismData!.isAligned) {
|
||||||
|
return _objectReady
|
||||||
|
? 'PARFAIT — OBJET CADRÉ, PRÊT'
|
||||||
|
: 'PARALLÈLE OK — PRÊT À PHOTOGRAPHIER';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mal aligné → message directif selon l'axe le plus dévié
|
||||||
final double pitch = _parallelismData!.pitchDegrees;
|
final double pitch = _parallelismData!.pitchDegrees;
|
||||||
final double roll = _parallelismData!.rollDegrees;
|
final double roll = _parallelismData!.rollDegrees;
|
||||||
|
|
||||||
|
|||||||
@@ -122,24 +122,14 @@ class ParallelismService {
|
|||||||
final double ny = gy / magnitude;
|
final double ny = gy / magnitude;
|
||||||
final double nz = gz / magnitude;
|
final double nz = gz / magnitude;
|
||||||
|
|
||||||
// ── Mesure de l'écart par rapport à la VERTICALE (cible sur un mur) ──
|
// Pitch et Roll mesurent l'inclinaison autour de chaque axe.
|
||||||
// Quand le téléphone est vertical face au mur, la gravité est portée par
|
|
||||||
// l'axe -Y (ny ≈ -1) et l'axe Z est proche de 0 (nz ≈ 0).
|
|
||||||
//
|
|
||||||
// Pitch = bascule avant/arrière (le téléphone "se couche") → vient de nz.
|
|
||||||
// Roll = penché à gauche/droite → vient de nx.
|
|
||||||
final double pitchDeg = math.asin(nz.clamp(-1.0, 1.0)) * (180.0 / math.pi);
|
final double pitchDeg = math.asin(nz.clamp(-1.0, 1.0)) * (180.0 / math.pi);
|
||||||
final double rollDeg = math.asin(nx.clamp(-1.0, 1.0)) * (180.0 / math.pi);
|
final double rollDeg = math.asin(nx.clamp(-1.0, 1.0)) * (180.0 / math.pi);
|
||||||
|
|
||||||
// Écart angulaire TOTAL par rapport à la verticale parfaite, calculé en 3D.
|
// Le critère de couleur = le PIRE des deux angles affichés à l'écran.
|
||||||
// C'est l'angle entre l'axe -Y du téléphone et le vecteur gravité réel.
|
// Ainsi ce que voit l'utilisateur (Pitch / Roll) correspond exactement
|
||||||
// -> Vaut 0° quand l'écran est parfaitement parallèle au mur,
|
// à la décision vert/orange : à 2° d'écart, on est largement dans le vert.
|
||||||
// indépendamment d'une rotation autour de l'axe de visée.
|
final double worstAngle = math.max(pitchDeg.abs(), rollDeg.abs());
|
||||||
final double tiltAngle =
|
|
||||||
math.acos((-ny).clamp(-1.0, 1.0)) * (180.0 / math.pi);
|
|
||||||
|
|
||||||
// On utilise l'écart 3D comme critère principal (plus permissif et stable).
|
|
||||||
final double worstAngle = tiltAngle;
|
|
||||||
|
|
||||||
// ── Hystérésis ──────────────────────────────────────────────────────────
|
// ── Hystérésis ──────────────────────────────────────────────────────────
|
||||||
// Premier appel : on décide selon alignThreshold uniquement
|
// Premier appel : on décide selon alignThreshold uniquement
|
||||||
|
|||||||
Reference in New Issue
Block a user