Integration Guide
Transit Search
Vedākṣha includes a transit search engine that finds the exact moment of any planetary event — aspects to natal positions, solar and lunar returns, or user-defined celestial conditions — using an adaptive step and bisection algorithm.
How the Search Engine Works
Brute-force transit finding is slow: computing a full chart for every minute of a year requires ~525,000 ephemeris calls. Vedākṣha uses a two-phase approach that is both fast and accurate.
Adaptive Step Scan
The engine starts with a coarse step (default: 1 day) and monitors the sign of the separation between the transiting planet and the target. When the sign changes, a transit has occurred somewhere in that interval.
Bisection Refinement
Once a bracket is found, bisection narrows the exact crossing to within a configurable tolerance (default: 1 second of time). The algorithm converges in ~17 iterations regardless of the initial step size.
Setting Up a Transit Search
Construct a TransitSearch with the natal chart, date range, and which transiting bodies and aspect types to look for. The result is an iterator of TransitEvent values in chronological order.
use vedaksha::prelude::*;
let birth_jd = calendar_to_jd(1990, 6, 15, 6.0);
let natal = compute_chart(birth_jd, 28.6139, 77.2090, &ChartConfig::tropical())?;
// Search window: 2024 calendar year
let start_jd = calendar_to_jd(2024, 1, 1, 0.0);
let end_jd = calendar_to_jd(2024, 12, 31, 23.99);
let search = TransitSearch::new(&natal)
.date_range(start_jd, end_jd)
.bodies(&[Body::Jupiter, Body::Saturn, Body::Uranus])
.aspects(&[AspectType::Conjunction, AspectType::Opposition, AspectType::Trine])
.orb(1.0)
.build();
for event in search.find()? {
let date = jd_to_calendar(event.exact_jd);
println!(
"{}-{:02}-{:02}: transiting {} {} natal {}",
date.year, date.month, date.day,
event.transiting_body,
event.aspect_type,
event.natal_body,
);
}TransitEvent Fields
.exact_jdf64Julian Day of the exact aspect moment, accurate to within the configured tolerance.
.transiting_bodyBodyThe transiting planet — the one moving through the natal chart.
.natal_bodyBodyThe natal planet being aspected.
.aspect_typeAspectTypeThe aspect type formed (Conjunction, Trine, etc.).
.applyingboolTrue if this event represents the ingress into orb (applying); false for the exit (separating).
.transiting_longitudef64Ecliptic longitude of the transiting planet at the exact moment.
Solar and Lunar Returns
A solar return is the moment the Sun returns to its exact natal longitude. A lunar return is the equivalent for the Moon, occurring approximately once per month. Both use the same bisection engine internally.
// Solar return — Sun back to natal longitude
let sr = solar_return(&natal, 2024)?;
let sr_date = jd_to_calendar(sr.exact_jd);
println!("Solar return: {}-{:02}-{:02} {:05.2}h UT",
sr_date.year, sr_date.month, sr_date.day, sr_date.hour_ut);
// Full solar return chart at the exact moment
let sr_chart = compute_chart(
sr.exact_jd,
sr_location_lat, // location at time of return, if relocating
sr_location_lon,
&ChartConfig::tropical()
)?;
// Lunar return — Moon back to natal longitude
// Returns the next one after start_jd
let lr = lunar_return(&natal, start_jd)?;Synastry (Inter-Chart Aspects)
Synastry compares two natal charts and finds all aspects formed between their planets. Each aspect in the result identifies which person's planet is aspecting the other.
let chart_a = compute_chart(jd_a, lat_a, lon_a, &config)?;
let chart_b = compute_chart(jd_b, lat_b, lon_b, &config)?;
let synastry = find_synastry_aspects(
&chart_a,
&chart_b,
&AspectConfig::default(),
)?;
for asp in &synastry.aspects {
println!(
"A's {} {} B's {} (orb {:.2}°)",
asp.body_a, asp.aspect_type, asp.body_b, asp.orb
);
}Composite Chart (Midpoint Method)
A composite chart is constructed by taking the midpoint of each pair of corresponding planets from two natal charts. The result is a single synthetic chart representing the relationship itself. Vedākṣha uses the near-midpoint method (selecting the midpoint that produces a coherent chart rather than its opposite).
let composite = compute_composite_chart(&chart_a, &chart_b)?;
// composite.planets[i].longitude is the near-midpoint
// of chart_a.planets[i] and chart_b.planets[i]
for planet in &composite.planets {
println!("{}: {:.4}°", planet.body, planet.longitude);
}Muhurta Search
Muhurta is the Vedic practice of selecting an auspicious moment for an activity. Vedākṣha's muhurta engine searches a date range for windows that satisfy a set of configurable criteria drawn from classical Jyotish.
let criteria = MuhurtaCriteria {
avoid_nakshatras: vec![Nakshatra::Bharani, Nakshatra::Krittika],
require_weekdays: vec![Weekday::Monday, Weekday::Wednesday, Weekday::Thursday],
avoid_tithis: vec![Tithi::Amavasya, Tithi::Chaturdashi],
require_moon_sign: Some(Sign::Taurus),
min_score: 0.7,
};
let windows = find_muhurta(start_jd, end_jd, lat, lon, &criteria)?;
for window in windows.iter().take(5) {
let start = jd_to_calendar(window.start_jd);
let end = jd_to_calendar(window.end_jd);
println!(
"{}-{:02}-{:02} {:04.1}h – {:04.1}h UT score: {:.2}",
start.year, start.month, start.day,
start.hour_ut, end.hour_ut,
window.score,
);
}avoid_nakshatrasExclude specific lunar mansions.
require_weekdaysOnly return results on specified weekdays.
avoid_tithisExclude specific lunar days (1–30).
require_moon_signMoon must be in a specified sign.
planetary_horaMatch a specific planetary hora (hourly ruler).
min_scoreThreshold for the overall auspiciousness score.