krz/moonrise

Night-sky companion for iPhone, Apple Watch and Vision Pro: what's up tonight, the Moon, planets, launches and missions, and a Library of the solar system. SwiftUI app with a Cloudflare Workers backend. astronomy cloudflare-workers ios night-sky space swiftui visionos watchos

Packages/MoonriseKit/Sources/SkyRenderer/HitTest.swift

34 lines · 1289 bytes

 1import CoreGraphics
 2import SkyEngine
 3
 4public enum SkyObject: Sendable, Equatable {
 5    case body(Body)
 6    /// IAU abbreviation.
 7    case constellation(String)
 8}
 9
10extension SkyScene {
11    /// The object under a tap: the nearest visible sun, moon or planet within
12    /// `radius` points, else the constellation whose figure has a star nearest the tap.
13    public func object(at point: CGPoint, projection p: Projection, radius: CGFloat = 28) -> SkyObject? {
14        func distance(_ h: Horizontal) -> CGFloat? {
15            guard h.altitude > 0, let q = p.point(h) else { return nil }
16            return hypot(q.x - point.x, q.y - point.y)
17        }
18        let bodyHit = bodies
19            .filter { $0.magnitude <= 6 }
20            .compactMap { b in distance(b.position).map { (b.body, $0) } }
21            .filter { $0.1 <= radius }
22            .min { $0.1 < $1.1 }
23        if let bodyHit { return .body(bodyHit.0) }
24
25        var best: (String, CGFloat)?
26        for c in Catalog.constellations {
27            for hr in c.lines.joined() {
28                guard let h = starsByHR[hr], let d = distance(h), d <= radius * 1.5 else { continue }
29                if best == nil || d < best!.1 { best = (c.id, d) }
30            }
31        }
32        return best.map { .constellation($0.0) }
33    }
34}