diff --git a/android/.kotlin/sessions/kotlin-compiler-11570733270002131811.salive b/android/.kotlin/sessions/kotlin-compiler-11570733270002131811.salive deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/features/capture/capture_screen.dart b/lib/features/capture/capture_screen.dart index 80bbaa80..5385d0f3 100644 --- a/lib/features/capture/capture_screen.dart +++ b/lib/features/capture/capture_screen.dart @@ -162,37 +162,30 @@ class _CaptureScreenState extends State 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 { final bool imuAligned = _parallelismData == null || _parallelismData!.isAligned; - // Vert UNIQUEMENT si l'appareil est parallèle ET un objet est bien cadré. - if (imuAligned && _objectReady) return const Color(0xFF00FF00); - return Colors.orange; + return imuAligned ? const Color(0xFF00FF00) : Colors.orange; } - /// Message d'aide selon le parallélisme + détection d'objet. + /// Message d'aide selon le parallélisme IMU. String get _alignmentMessage { - final bool imuAligned = - _parallelismData == null || _parallelismData!.isAligned; - - // 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) { + if (_parallelismData == null || + _parallelismData!.status == ParallelismStatus.unknown) { 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 roll = _parallelismData!.rollDegrees; diff --git a/lib/services/parallelism_service.dart b/lib/services/parallelism_service.dart index 67ec69c0..004ea182 100644 --- a/lib/services/parallelism_service.dart +++ b/lib/services/parallelism_service.dart @@ -122,24 +122,14 @@ class ParallelismService { final double ny = gy / magnitude; final double nz = gz / magnitude; - // ── Mesure de l'écart par rapport à la VERTICALE (cible sur un mur) ── - // 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. + // Pitch et Roll mesurent l'inclinaison autour de chaque axe. 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); - // Écart angulaire TOTAL par rapport à la verticale parfaite, calculé en 3D. - // C'est l'angle entre l'axe -Y du téléphone et le vecteur gravité réel. - // -> Vaut 0° quand l'écran est parfaitement parallèle au mur, - // indépendamment d'une rotation autour de l'axe de visée. - 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; + // Le critère de couleur = le PIRE des deux angles affichés à l'écran. + // Ainsi ce que voit l'utilisateur (Pitch / Roll) correspond exactement + // à la décision vert/orange : à 2° d'écart, on est largement dans le vert. + final double worstAngle = math.max(pitchDeg.abs(), rollDeg.abs()); // ── Hystérésis ────────────────────────────────────────────────────────── // Premier appel : on décide selon alignThreshold uniquement