ThumbWorks / AugmentedSolarSystem

An Augmented reality experience to explore planets in our Solar System
71 stars 25 forks source link

Enhancement - more accurate Elliptical Orbits #48

Closed johndpope closed 4 years ago

johndpope commented 6 years ago

Apparently - not all planets fly along same Elliptical Orbital as per app. https://www.youtube.com/watch?v=nrP4a4MCo8A

ecliptic

will dig into this further and update when I found out more info.

johndpope commented 6 years ago

found this http://mgvez.github.io/jsorrery/

screen shot 2017-11-23 at 2 47 08 pm
johndpope commented 6 years ago
screen shot 2017-11-23 at 2 48 25 pm
rodericj commented 6 years ago

The way I envisioned this was by using the heliocentric position rather than rotating around the sun with the SceneKit rotation methods. The issue here would be that we would likely need to calculate the entire orbit if we want to still display the orbit trail. That's not something I know how to do effectively. Something similar to a bezier path, but in 3d space in SceneKit APIs ¯_(ツ)_/¯

johndpope commented 6 years ago

@mgvez - we're marveling at your implementation of jsorrery. did you ever get your hands dirty with scenekit?

digging around github - found this - which may help

https://github.com/younata/Swift-Crossing/blob/cc4a29c843d79a648e42ae96ec4762a64e5c2fc8/Swift-Crossing/Weed.swift

class Weed: SCNNode {
    override init() {
        super.init()

        let path = NSBezierPath()
        path.moveToPoint(NSMakePoint(0.45, 0))
        path.lineToPoint(NSMakePoint(0.4, 0.25))
        path.lineToPoint(NSMakePoint(0.55, 0.5))
        path.lineToPoint(NSMakePoint(0.5, 0.25))
        path.lineToPoint(NSMakePoint(0.5, 0))
        path.closePath()

        let geom = SCNShape(path: path, extrusionDepth: 0.01)
        geom.firstMaterial?.diffuse.contents = NSColor.greenColor()

        geometry = geom

        physicsBody = nil
    }

    required init(coder: NSCoder) {
        fatalError("")
    }
}

we'd need to maybe hook to increment lineToPoint for each orbit on each frame. could be a challenge. this ticket was to simply illustrate / bend the orbit to angle of orbit. as in pluto in first photo. seems like neptune has different angle too.

screen shot 2017-12-02 at 6 33 04 pm
johndpope commented 6 years ago

this protocol in swiftAA may or may not be useful.

What I'm reading here is that for each step / the julian date - the solar system engine would ask - where should the planets be given this date.

phase_angle_3

https://en.wikipedia.org/wiki/Phase_angle_(astronomy)

/// The EllipticalPlanetaryDetails encompasses various elliptical details of solar-system planets.
public protocol EllipticalPlanetaryDetails: PlanetaryBase {
    /// The details of the planet configuration
    var planetaryDetails: KPCAAEllipticalPlanetaryDetails { get }

    /// The details of the object configuration
    var ellipticalObjectDetails: KPCAAEllipticalObjectDetails { get }

    /// The apparent geocentric distance
    var apparentGeocentricDistance: AstronomicalUnit { get }

    /// The true geocentric distance of the planet
    var trueGeocentricDistance: AstronomicalUnit { get }

    /// The phase angle, that is the angle (Sun-planet-Earth).
    var phaseAngle: Degree { get }

    /// The apparent equatorial coordinates of the planet. That is, its apparent position on the celestial sphere, as
    /// it is actually seen from the center of the moving Earth, and referred to the instantaneous equator, ecliptic
    /// and equinox.
    /// It accounts for 1) the effect of light-time and 2) the effect of the Earth motion. See AA p224.
    var apparentGeocentricEquatorialCoordinates: EquatorialCoordinates { get }
}

public extension EllipticalPlanetaryDetails {

    var apparentGeocentricDistance: AstronomicalUnit {
        get { return AstronomicalUnit(self.planetaryDetails.ApparentGeocentricDistance) }
    }

    var trueGeocentricDistance: AstronomicalUnit {
        get { return AstronomicalUnit(self.ellipticalObjectDetails.TrueGeocentricDistance) }
    }

    /// The phase angle, that is the angle (Sun-planet-Earth).
    var phaseAngle: Degree {
        get { return Degree(KPCAAIlluminatedFraction_PhaseAngle(self.radiusVector.value,
                                                                Earth(julianDay: self.julianDay).radiusVector.value,
                                                                self.apparentGeocentricDistance.value)) }
    }

    /// The apparent equatorial coordinates of the planet. That is, its apparent position on the celestial sphere, as
    /// it is actually seen from the center of the moving Earth, and referred to the instantaneous equator, ecliptic
    /// and equinox.
    /// It accounts for 1) the effect of light-time and 2) the effect of the Earth motion. See AA p224.
    public var apparentGeocentricEquatorialCoordinates: EquatorialCoordinates {
        get {
            let ra = Hour(self.planetaryDetails.ApparentGeocentricRA)
            let dec = Degree(self.planetaryDetails.ApparentGeocentricDeclination)
            return EquatorialCoordinates(alpha: ra,
                                         delta: dec,
                                         epoch: .epochOfTheDate(self.julianDay),
                                         equinox: .meanEquinoxOfTheDate(self.julianDay))
        }
    }
}
mgvez commented 6 years ago

Hi, not sure I understand your problem exactly, as I haven't read your code, but I can tell you how I drew the paths for each planet in jsOrrery.

I don't know if the most efficient way, and perhaps not, but it's the way I came up... I am not an expert, and I came up with this because I did not find relevant examples. What I do is compute vertices for the path of each planet, based on the orbital elements, and then join these vertices with straight lines. There are no beziers in 3.js. I compute vertices so that I have a few hundreds for each path.

I always start from the current planet's position at given date, and I compute a position not too far in the future. If this new position is too far (let's say it advanced the planet's angular position to the sun by more than 1 degree) I recompute a position a bit earlier. If the angle is too small, I recompute a bit in the future. I have a treshold of whatever values for angle, I don't remember exactly, lets say between 0.5 and 1.5, so that the min/max angluar distance between vertices in my path is in that treshold. So when a vertices falls in this treshold, I push it in the array, and begin again from that vertice. Until I have a full 360.

You cannot assume that a planet's path is where you expect to find it. They are not exactly in the same plane, and they change slightly from year to year (though the orbital elements you have might not specify these changes). That's why I always start from the planet's current position, and not an absolute value. In the simulation I recompute paths when the user manually changes the date (i.e. not when the simulation is animated, as the changes are too subtle from year to year), though for some bodies you HAVE to recompute path at each revolution (for example the Moon's path changes dramatically at each revolution)

Hope this helps

rodericj commented 6 years ago

I agree with @mgvez here. The current implementation on this repo is an SCNTorus geometry which is perfectly round. It's not perfectly ideal since the orbits are not actually circles. A Bezier in SceneKit estimating 1 rotation seems like it could be a thing, but I've not looked into how to do the equivalent of a BezierPath in SceneKit.