From 998c98267bde11679bc5ebb2c0dfab390d29a265 Mon Sep 17 00:00:00 2001 From: atsunatsu Date: Mon, 3 Aug 2026 01:29:17 +0800 Subject: [PATCH] fix: draw full station-B track on main radar, live dot on top Track line is no longer time-limited (always shows the whole mutual arc). The station-B live position is drawn separately on the line using the same pulsing-dot mode as the local station. --- .../look4sat/feature/radar/RadarScreen.kt | 24 +++++++++++++++---- .../look4sat/feature/radar/RadarView.kt | 13 +++++----- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt index 102149f1..ca49af7d 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarScreen.kt @@ -45,6 +45,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -117,11 +118,22 @@ private fun RadarScreen( val addToCalendar: () -> Unit = { uiState.currentPass?.let { onAction(RadarAction.AddToCalendar(it.name, it.aosTime, it.losTime)) } } - // Live station-B track overlay: samples up to "now" (recomposed each second tick) + // Station-B overlay: full track line (not time-limited) + live position dot + // at the current moment, same display mode as the local station. + val trackB = remember(mutualData.trackSamples) { + mutualData.trackSamples.map { + OrbitalPos( + azimuth = it.azimuthB * PI / 180.0, + elevation = it.elevationB * PI / 180.0, + time = it.time + ) + } + } val timeNow = System.currentTimeMillis() - val trackB = mutualData.trackSamples + val trackBPosition = mutualData.trackSamples .filter { it.time <= timeNow } - .map { + .lastOrNull() + ?.let { OrbitalPos( azimuth = it.azimuthB * PI / 180.0, elevation = it.elevationB * PI / 180.0, @@ -151,11 +163,11 @@ private fun RadarScreen( } } if (isVertical) { - RadarCard(uiState, trackB, Modifier.weight(1f)) + RadarCard(uiState, trackB, trackBPosition, Modifier.weight(1f)) PagerCard(uiState, onAction, requestMicPermission, Modifier.weight(1f)) } else { Row(horizontalArrangement = Arrangement.spacedBy(6.dp)) { - RadarCard(uiState, trackB, Modifier.weight(1f)) + RadarCard(uiState, trackB, trackBPosition, Modifier.weight(1f)) PagerCard(uiState, onAction, requestMicPermission, Modifier.weight(1f)) } } @@ -214,6 +226,7 @@ private fun PagerCard( private fun RadarCard( uiState: RadarState, trackB: List = emptyList(), + trackBPosition: OrbitalPos? = null, modifier: Modifier = Modifier ) { val satellitePos = uiState.orbitalPos @@ -249,6 +262,7 @@ private fun RadarCard( item = position, items = uiState.satTrack, trackB = trackB.takeIf { it.isNotEmpty() }, + trackBPosition = trackBPosition, azimElev = uiState.orientationValues, shouldShowSweep = uiState.shouldShowSweep, shouldUseCompass = uiState.shouldUseCompass, diff --git a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt index 8a5d034c..cf5b3dcd 100644 --- a/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt +++ b/feature/radar/src/main/java/com/rtbishop/look4sat/feature/radar/RadarView.kt @@ -73,6 +73,7 @@ fun RadarViewCompose( items: List, trackB: List? = null, trackBColor: Color = MaterialTheme.colorScheme.tertiary, + trackBPosition: OrbitalPos? = null, azimElev: Pair, shouldShowSweep: Boolean, shouldUseCompass: Boolean, @@ -138,17 +139,17 @@ fun RadarViewCompose( drawElevationLabels(radius, primaryColor, measurer) translate(center.x, center.y) { drawTrack(trackPath, trackEffect, aimColor, primaryColor) - // Station-B overlay: dashed track + current position dot + // Station-B overlay: full dashed track + live position dot + // (same display mode as the local station: track line + pulsing dot) if (trackB != null && trackB.isNotEmpty() && !trackBPath.isEmpty) { drawPath( trackBPath, trackBColor, style = Stroke(STROKE_WIDTH, pathEffect = PathEffect.dashPathEffect(floatArrayOf(18f, 12f))) ) - val lastB = trackB.last() - if (lastB.elevation > 0) { - val posB = sph2Cart(lastB.azimuth, lastB.elevation, radius.toDouble()) - drawCircle(trackBColor, 26f, posB, style = Stroke(2f)) - drawCircle(trackBColor, 12f, posB) + } + trackBPosition?.let { posB -> + if (posB.elevation > 0) { + drawPosition(posB, radius, animScale, trackBColor) } } if (item.elevation > 0) {