This Stellarium script will find the next time two celestial objects are closest together. It is useful for finding when two planets conjunct or when a planet is close to a celestial object. If two planets are selected, and one of them starts retrograding before their conjunction, that will be the point of closest separation.
// ****************************************************************************************** // Stellarium script to find the next nearest time two objects are closest to each other. // The time can be in the past or future, depending on whether they are initially moving // away from each other. // // Created by David O'Neil, Aug, 2019. Released to the public domain, for anyone interested. // Just leave this 'created by' (or 'originally created by') verbage in the derived work. // // To use: // * Set the 'obj1' and 'obj2' variables to whatever you want. // * Set the date via Stellarium's user interface close to a time you are looking for them // to come together. // (The date must be 1/2 year or so of a conjunction, to overcome the difficulty of // taking retrograde motions into account.) // * Run the script. It will find the next point of nearness that is closest to that date, // whether that is in the future or the past. // ****************************************************************************************** pi = Math.PI; degToRad = pi/180; obj1 = "Jupiter"; obj2 = "Saturn"; core.selectObjectByName(obj1, true); StelMovementMgr.setFlagTracking(true); justFindSeparation = false; if (justFindSeparation) { d = getRadiansBetweenObjects(); d = d/degToRad; core.debug(d); degrees = Math.floor(d); minutes = d - degrees; minutes = minutes * 60; seconds = minutes - Math.floor(minutes); core.debug(degrees + " " + Math.floor(minutes) + " " + seconds*60); } else findClosestConjunction(); core.debug(d / degToRad); function findClosestConjunction() { core.selectObjectByName("obj1", true); core.setTimeRate(0); //Lock the sky in place, so we can see it unmoving! //Get the initial 2 points: a1 = getRadiansBetweenObjects(); //Do initial iteration in 1-day increment: a2 = getTheAngleAfter("+1 days"); direction = "+"; if (a2 < a1) { direction = "+"; } else { direction = "-"; a2 = getTheAngleAfter("-1 days"); a2 = getTheAngleAfter("-1 days"); //Don't know why can't use "-2 days" reliably! } timeStepString = direction + "1 days"; //Iterate: while (a2 < a1) { a1 = a2; a2 = getTheAngleAfter(timeStepString); } //Assume we've gone through several days, and have passed the last good one, //so step back (or forward) a day to fix the overstep: if (direction == "+") { a1 = getTheAngleAfter("-1 days"); } else { a1 = getTheAngleAfter("+1 days"); } //Now we are doing it by the hours. As before, we must check whether we need to //go back or forward. //Now determine whether to go forward or back: a2 = getTheAngleAfter("+1 hour"); if (a2 < a1) { direction = "+"; } else { direction = "-"; a2 = getTheAngleAfter("-1 hours"); a2 = getTheAngleAfter("-1 hours"); //As before, don't know why can't just -2 this. } timeStepString = direction + "1 hour"; while (a2 < a1) { a1 = a2; a2 = getTheAngleAfter(timeStepString); } //Assume we've gone through several hours, and have passed the last good one, //so step back (or forward) an hour to fix the overstep: if (direction == "+") { a1 = getTheAngleAfter("-1 hours"); } else { a1 = getTheAngleAfter("+1 hours"); } //And finally, for the minutes: //First, set a1 to a2, as a2 was last measurement taken at current time: a1 = a2; a2 = getTheAngleAfter("+1 minute"); if (a2 < a1) { direction = "+"; } else { direction = "-"; a2 = getTheAngleAfter("-1 minutes"); a2 = getTheAngleAfter("-1 minutes"); } timeStepString = direction + "1 minute"; while (a2 < a1) { a1 = a2; a2 = getTheAngleAfter(timeStepString); } core.debug("Finished! Separation = " + a1 + ", " + a2); core.setTimeRate(0); //Lock the sky in place, so we can see it unmoving! } function getTheAngleAfter(timeStep) { obj2Azi = core.getObjectInfo(obj2).azimuth; core.setDate(timeStep); //The following was an attempt to leave the wait time at 0.01, and loop wait until //Stellarium got things caught up, but it never worked, and I had to change the //wait time to 0.05 many times, instead of 0.03. while (core.getObjectInfo(obj2).azimuth == obj2Azi) { core.wait(0.01); } angleDiff = getRadiansBetweenObjects(); return angleDiff; } function getRadiansBetweenObjects() { obj2Azi = core.getObjectInfo(obj2).elong; obj2Azi = obj2Azi * degToRad; obj2Alt = core.getObjectInfo(obj2).elat; obj2Alt = obj2Alt * degToRad; obj1Azi = core.getObjectInfo(obj1).elong; obj1Azi = obj1Azi * degToRad; obj1Alt = core.getObjectInfo(obj1).elat; obj1Alt = obj1Alt * degToRad; d = Math.acos(Math.sin(obj2Alt)*Math.sin(obj1Alt)+Math.cos(obj2Alt)*Math.cos(obj1Alt)*Math.cos(obj2Azi-obj1Azi)); //The following formula is for when the objects are very close together, or very close to 180 degrees apart: //I may have Azi and Alt mixed up. // delAzi = obj1Azi - obj2Azi; // delAlt = obj1Alt - obj2Alt; //d = sqrt ( (cos(aziA-aziB) * (altA-altB)) ^2 + (aziA-aziB)^2 ) //d = Math.sqrt ( Math.cos(delAzi)*(delAlt) * Math.cos(delAzi)*(delAlt) + (delAzi)*(delAzi) ); return d; //In radians }