| 2136 | // of distance overlap. Detects partial, annular, and total solar eclipses. |
| 2137 | |
| 2138 | int NCheckEclipseSolar(int iEar, int iMoo, int iSun, real *prPct) |
| 2139 | { |
| 2140 | PT3R pSun, pMoo, pEar, pNear, pUmb, vS2M, vS2E, vE2U, vS2Mu, vS2N; |
| 2141 | real radiS, radiE, radiM, radiU, radiP, lNear, lSM, lSU, lSE, lSN, lEU, dot; |
| 2142 | |
| 2143 | // Objects must be different. |
| 2144 | if (iEar == iSun || iEar == iMoo || iMoo == iSun) |
| 2145 | return etUndefined; |
| 2146 | |
| 2147 | // Calculate radius and coordinates of the objects in km. |
| 2148 | radiS = rObjDiam[iSun] / 2.0; |
| 2149 | radiE = rObjDiam[iEar] / 2.0; |
| 2150 | radiM = rObjDiam[iMoo] / 2.0; |
| 2151 | |
| 2152 | pSun = space[iSun]; pMoo = space[iMoo]; pEar = space[iEar]; |
| 2153 | PtMul(pSun, rAUToKm); |
| 2154 | PtMul(pMoo, rAUToKm); |
| 2155 | PtMul(pEar, rAUToKm); |
| 2156 | |
| 2157 | // Determine point along Sun/Moon ray nearest the center of Earth. |
| 2158 | PtVec(vS2M, pSun, pMoo); |
| 2159 | PtVec(vS2E, pSun, pEar); |
| 2160 | dot = PtDot(vS2E, vS2M) / PtDot(vS2M, vS2M); |
| 2161 | vS2N = vS2M; PtMul(vS2N, dot); |
| 2162 | pNear = pSun; PtAdd2(pNear, vS2N); |
| 2163 | PtSub2(pNear, pEar); lNear = PtLen(pNear); |
| 2164 | |
| 2165 | // Determine point of maximum extent of Moon's umbra shadow. |
| 2166 | lSM = PtLen(vS2M); |
| 2167 | lSU = lSM * radiS / (radiS - radiM); |
| 2168 | vS2Mu = vS2M; PtDiv(vS2Mu, lSM); |
| 2169 | pUmb = vS2Mu; PtMul(pUmb, lSU); PtAdd2(pUmb, pSun); |
| 2170 | PtVec(vE2U, pEar, pUmb); |
| 2171 | lSE = PtLen(vS2E); |
| 2172 | lEU = PtLen(vE2U); |
| 2173 | lSN = PtLen(vS2N); |
| 2174 | radiU = radiS * (lSU - lSN) / lSU; |
| 2175 | if (radiU < 0.0) |
| 2176 | radiU = 0.0; |
| 2177 | |
| 2178 | // If Sun/Moon ray intersects Earth, must be an annular or total eclipse. |
| 2179 | if (lNear - radiU < radiE) { |
| 2180 | if (prPct != NULL) |
| 2181 | *prPct = 100.0; |
| 2182 | if (lSU < lSE && lEU > radiE) |
| 2183 | return etAnnular; |
| 2184 | return etTotal; |
| 2185 | } |
| 2186 | |
| 2187 | // Check if Earth intersects penumbra shadow, for a partial solar eclipse. |
| 2188 | radiP = (radiS + radiM) / lSM * lSN - radiS; |
| 2189 | if (lNear - radiE < radiP && radiM > 0.0) { |
| 2190 | if (prPct != NULL) |
| 2191 | *prPct = 100.0 - (lNear - radiE) / radiP * 100.0; |
| 2192 | return etPartial; |
| 2193 | } |
| 2194 | return etNone; |
| 2195 | } |
no outgoing calls
no test coverage detected