| 2200 | // eclipses, along with transits and occulations of other bodies. |
| 2201 | |
| 2202 | int NCheckEclipse(int obj1, int obj2, real *prPct) |
| 2203 | { |
| 2204 | real radi0, radi1, radi2, len1, len2, angDiff, ang1, ang2, ang1T, ang2T; |
| 2205 | |
| 2206 | // Objects that aren't actual things in space can't eclipse or be eclipsed. |
| 2207 | if (!FThing(obj1) || !FThing(obj2)) |
| 2208 | return etUndefined; |
| 2209 | |
| 2210 | // Calculate radius of the two objects in km. |
| 2211 | radi1 = RObjDiam(obj1) / 2.0; |
| 2212 | radi2 = RObjDiam(obj2) / 2.0; |
| 2213 | if (radi1 <= 0.0 && radi2 <= 0.0) |
| 2214 | return etNone; |
| 2215 | |
| 2216 | // Special check if solar eclipse allowed to happen anywhere on Earth. |
| 2217 | if (us.fEclipseAny && obj1 == oSun && (obj2 == oMoo || FMoons(obj2)) && |
| 2218 | (us.fMoonMove || ObjOrbit(obj2) == us.objCenter)) |
| 2219 | return NCheckEclipseSolar(us.objCenter, obj2, oSun, prPct); |
| 2220 | |
| 2221 | // Calculate angular distance between center points of the two objects. |
| 2222 | angDiff = SphDistance(planet[obj1], planetalt[obj1], |
| 2223 | planet[obj2], planetalt[obj2]); |
| 2224 | if (us.objCenter == oEar && angDiff > (!us.fEclipseAny ? 0.75 : 1.5)) |
| 2225 | return etNone; |
| 2226 | |
| 2227 | // Calculate angular size in the sky spanned by the two objects. |
| 2228 | len1 = PtLen(space[obj1]) * rAUToKm; |
| 2229 | len2 = PtLen(space[obj2]) * rAUToKm; |
| 2230 | ang1 = RAtnD(radi1 / len1); |
| 2231 | ang2 = RAtnD(radi2 / len2); |
| 2232 | if (us.fEclipseAny) { |
| 2233 | // Shrink angular distance by best case topocentric offset. |
| 2234 | radi0 = RObjDiam(us.objCenter) / 2.0; |
| 2235 | ang1T = RAtnD(radi0 / len1); |
| 2236 | ang2T = RAtnD(radi0 / len2); |
| 2237 | angDiff -= RAbs(ang2T - ang1T); |
| 2238 | if (angDiff < 0.0) |
| 2239 | angDiff = 0.0; |
| 2240 | } |
| 2241 | if (ang1 + ang2 <= angDiff) |
| 2242 | return etNone; |
| 2243 | |
| 2244 | // Compare angular sizes to distance, to see how much overlap there is. |
| 2245 | if (prPct != NULL) |
| 2246 | *prPct = ang1 == ang2 ? 100.0 : |
| 2247 | 100.0 - angDiff / RAbs(ang2 - ang1) * 100.0; |
| 2248 | if (ang1 >= ang2 + angDiff) |
| 2249 | return len1 - radi1 >= len2 + radi2 ? etAnnular : etTotal; |
| 2250 | else if (ang2 >= ang1 + angDiff) |
| 2251 | return len2 - radi2 >= len1 + radi1 ? etAnnular : etTotal; |
| 2252 | if (prPct != NULL) |
| 2253 | *prPct = 100.0 - |
| 2254 | (angDiff - RAbs(ang2 - ang1)) / (Min(ang1, ang2) * 2.0) * 100.0; |
| 2255 | return etPartial; |
| 2256 | } |
| 2257 | |
| 2258 | |
| 2259 | // Check whether a lunar eclipse is taking place as seen from the Earth (or |
no test coverage detected