Rashi Phal – Ascendant Calculation


Ascendant Calculation

1. Interfaces and Constants

  • We start by defining the necessary constants and the expected structure for the input data.
// - – 1. CONSTANTS AND INTERFACES – -

interface Coordinates {
    latitude: number;
    longitude: number;
}

interface BirthData extends Coordinates {
    year: number;
    month: number;
    day: number;
    hour: number; // Local Time (24-hour)
    minute: number;
    timeZoneOffset: number; // e.g., 5.5 for IST
}

interface LagnaResult {
    siderealAscendant: number;
    jd: number; // Julian Day (for subsequent planet calculations)
    ayanamshaDeg: number;
}

// Lahiri Ayanamsha Constants (Simplified Linear Model for Demonstration)
const AYANAMSHA_CONSTANTS = {
    // Approx Lahiri value on J2000 (JD 2451545.0)
    EPOCH_AYANAMSHA: 23.0 + 15.0 / 60.0 + 32.74 / 3600.0, 
    // Rate of precession (approx. 50.38 seconds per year converted to degrees per day)
    AYANAMSHA_RATE: 50.38 / 3600.0 / 365.25 
};
const J2000_JD = 2451545.0; // JD for January 1, 2000, 12:00 UT

2. Ayanamsha Function

  • This function calculates the Lahiri Ayanamsha for any given Julian Day.
// - – 2. AYANAMSHA CALCULATION – -

/**
 * Calculates the Lahiri Ayanamsha for a given Julian Day (JD) using a linear approximation.
 * @param jd Julian Day
 * @returns The Lahiri Ayanamsha value in degrees.
 */
function calculateAyanamsha(jd: number): number {
    const ayanamsha = AYANAMSHA_CONSTANTS.EPOCH_AYANAMSHA + AYANAMSHA_CONSTANTS.AYANAMSHA_RATE * (jd - J2000_JD);
    return ayanamsha % 360;
}

3. Core Lagna Calculation Function

  • This function handles the time conversion, Julian Day, and the final Tropical-to-Sidereal conversion.
// - – 3. CORE VEDIC ASCENDANT (LAGNA) CALCULATION – -

/**
 * Calculates the Sidereal Ascendant (Lagna) for a Vedic chart.
 *
 * @param data The birth details including date, time, coordinates, and time zone.
 * @returns An object containing the Sidereal Ascendant degree, Julian Day, and Ayanamsha.
 */
function calculateVedicAscendant(data: BirthData): LagnaResult {
    const { year, month, day, hour, minute, latitude, longitude, timeZoneOffset } = data;

    // - – 3a. TIME ZONE CORRECTION & JD CALCULATION – -
    let localTimeHours = hour + minute / 60.0;
    let ut = localTimeHours - timeZoneOffset;

    let y = year;
    let m = month;
    let d = day;
    
    // Adjust date/day if UT pushes time back past midnight
    if (ut < 0) {
        ut += 24.0;
        d -= 1;
        if (d < 1) {
            m -= 1;
            if (m < 1) { m = 12; y -= 1; }
            // Get last day of the new month
            d = new Date(y, m, 0).getDate(); 
        }
    }

    // Standard JD calculation (Handles Gregorian Calendar corrections)
    if (m <= 2) { y -= 1; m += 12; }
    const a = Math.floor(y / 100);
    const b = 2 - a + Math.floor(a / 4);
    
    const jd = Math.floor(365.25 * (y + 4716)) +
               Math.floor(30.6001 * (m + 1)) +
               d + ut / 24.0 + b - 1524.5;
    
    // - – 3b. TROPICAL ASCENDANT CALCULATION – -
    const T = (jd - J2000_JD) / 36525.0; // Time in Julian Centuries

    // Greenwich Sidereal Time (GST)
    let gst = 280.46061837 + 360.98564736629 * (jd - J2000_JD) +
              0.000387933 * T * T - (T * T * T) / 38710000.0;
    gst = gst % 360; if (gst < 0) gst += 360;

    // Local Sidereal Time (LST)
    let lst = gst + longitude;
    lst = lst % 360; if (lst < 0) lst += 360;

    // Obliquity of the Ecliptic (Mean Epsilon)
    const epsilon = 23.439291 - 0.0130042 * T;
    const epsilonRad = epsilon * Math.PI / 180;
    const latRad = latitude * Math.PI / 180;
    const lstRad = lst * Math.PI / 180;

    // Tropical Ascendant Formula (Spherical Trigonometry)
    const y_asc = -Math.cos(lstRad);
    const x_asc = Math.sin(lstRad) * Math.cos(epsilonRad) -
                  Math.tan(latRad) * Math.sin(epsilonRad);

    let tropicalAscendant = Math.atan2(y_asc, x_asc) * 180 / Math.PI;
    if (tropicalAscendant < 0) tropicalAscendant += 360;
    
    // - – 3c. AYANAMSHA CORRECTION (Tropical -> Sidereal) – -
    const ayanamshaDeg = calculateAyanamsha(jd);

    let siderealAscendant = tropicalAscendant - ayanamshaDeg;
    if (siderealAscendant < 0) {
        siderealAscendant += 360;
    }

    return { 
        siderealAscendant, 
        jd, 
        ayanamshaDeg 
    };
}

4. Core Lagna Calculation Function

// - – EXAMPLE USAGE – -

const subratBirthData: BirthData = {
    year: 1991,
    month: 7,
    day: 29,
    hour: 15,
    minute: 30,
    latitude: 20.5000, 
    longitude: 86.42,
    timeZoneOffset: 5.5 // IST is UTC + 5.5
};

const result = calculateVedicAscendant(subratBirthData);

// Helper function to convert degree to Sign Name (Rashi)
function getSignName(longitude: number): string {
    const signs = ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"];
    return signs[Math.floor(longitude / 30)];
}

const lagnaSign = getSignName(result.siderealAscendant);
const lagnaDegree = result.siderealAscendant % 30;

console.log(`\n*** VEDIC LAGNA CALCULATION RESULTS ***`);
console.log(`Date: ${subratBirthData.year}-${subratBirthData.month}-${subratBirthData.day} @ ${subratBirthData.hour}:${subratBirthData.minute} IST`);
console.log(`----------------------------------------`);
console.log(`Julian Day (JD): ${result.jd.toFixed(4)}`);
console.log(`Lahiri Ayanamsha: ${result.ayanamshaDeg.toFixed(3)}°`);
console.log(`\nSIDEREAL ASCENDANT (LAGNA): ${lagnaSign} ${lagnaDegree.toFixed(2)}°`);
// Expected output confirms Sagittarius, matching the earlier assessment:
// Expected: Sagittarius ~22°

Leave a Reply

Your email address will not be published. Required fields are marked *