diff options
Diffstat (limited to 'android-app/app/src/main/kotlin/org')
| -rw-r--r-- | android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt | 2 | ||||
| -rw-r--r-- | android-app/app/src/main/kotlin/org/terst/nav/ui/map/ParticleWindView.kt | 20 |
2 files changed, 18 insertions, 4 deletions
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index 996892e..e6355bd 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -296,6 +296,8 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { private fun hideOverlays() { fragmentContainer.visibility = View.GONE fabRecordTrack.visibility = View.VISIBLE + // Re-apply cached conditions in case they arrived while the overlay was covering the sheet + lastConditions?.let { applyConditions(it) } } override fun onQuitRequested() { diff --git a/android-app/app/src/main/kotlin/org/terst/nav/ui/map/ParticleWindView.kt b/android-app/app/src/main/kotlin/org/terst/nav/ui/map/ParticleWindView.kt index 24b25db..26d9ea2 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/ui/map/ParticleWindView.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/ui/map/ParticleWindView.kt @@ -8,6 +8,7 @@ import android.util.AttributeSet import android.view.View import org.maplibre.android.geometry.LatLng import org.maplibre.android.maps.MapLibreMap +import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin import kotlin.random.Random @@ -38,10 +39,12 @@ class ParticleWindView @JvmOverloads constructor( private var windSpeedKt = 0.0 private val N = 300 + private var activeN = 150 // wind-speed-dependent; updated in setWind() private val particleLat = FloatArray(N) private val particleLon = FloatArray(N) private val particleAge = FloatArray(N) - private val MAX_AGE = 8f // seconds before forced respawn + private val MAX_AGE = 25f // seconds before forced respawn + private var lastLatRange = 0f // for zoom-out scatter detection private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply { strokeWidth = 3.5f @@ -62,6 +65,8 @@ class ParticleWindView @JvmOverloads constructor( fun setWind(dirFromDeg: Double, speedKt: Double) { windDirFromDeg = dirFromDeg windSpeedKt = speedKt + // Scale particle count: 60 at calm → 300 at 25+ kt + activeN = (60 + (speedKt.coerceIn(0.0, 25.0) / 25.0 * 240)).toInt() } // ── Rendering ──────────────────────────────────────────────────────────── @@ -86,6 +91,11 @@ class ParticleWindView @JvmOverloads constructor( val latNorth = maxOf(nL.latitude, nR.latitude, fL.latitude, fR.latitude).toFloat() val latRange = latNorth - latSouth + // If the user zoomed out significantly, immediately redistribute particles + // across the new viewport rather than waiting for them to drift to the edges. + if (lastLatRange > 0f && latRange > lastLatRange * 1.8f) scatter(m) + lastLatRange = latRange + // West edge = left screen side; east edge = right screen side. // Using screen-ordered corners handles antimeridian crossing correctly. val lonWest = minOf(nL.longitude, fL.longitude).toFloat() @@ -109,7 +119,7 @@ class ParticleWindView @JvmOverloads constructor( val tailDx = sin(screenRad).toFloat() * TAIL_PX val tailDy = (-cos(screenRad)).toFloat() * TAIL_PX - for (i in 0 until N) { + for (i in 0 until activeN) { particleLat[i] += dlat particleLon[i] += dlon // Wrap longitude into [-180, 180] after movement @@ -137,7 +147,9 @@ class ParticleWindView @JvmOverloads constructor( LatLng(particleLat[i].toDouble(), particleLon[i].toDouble()) ) - val alpha = ((1f - particleAge[i] / MAX_AGE) * 220).toInt().coerceIn(40, 220) + // Sine curve: smooth fade-in from birth, peak at mid-life, smooth fade-out. + // No bright birth flash — particles ease in and ease out. + val alpha = (sin(PI * particleAge[i] / MAX_AGE) * 200).toInt().coerceIn(15, 200) paint.color = Color.argb(alpha, 30, 100, 255) canvas.drawLine(pt.x - tailDx, pt.y - tailDy, pt.x, pt.y, paint) @@ -170,7 +182,7 @@ class ParticleWindView @JvmOverloads constructor( val lonEast = maxOf(nR.longitude, fR.longitude).toFloat() val lonSpan = if (lonEast >= lonWest) lonEast - lonWest else lonEast - lonWest + 360f - for (i in 0 until N) { + for (i in 0 until activeN) { particleLat[i] = latSouth + Random.nextFloat() * latRange var newLon = lonWest + Random.nextFloat() * lonSpan if (newLon > 180f) newLon -= 360f |
