Planetary Aspect Calculation for Developers: Orbs and Edge Cases

10 min read
Torsten Brinkmann
astrologyPlanetary AspectsOrb CalculationBirth ChartAspect Algorithm

How to calculate planetary aspects correctly. Covers orb systems, the 360 degree wrap-around bug, applying vs separating detection, and a working API example.

TL;DR

  • A planetary aspect is an angular relationship between two planets along the ecliptic. The five major aspects are conjunction (0), sextile (60), square (90), trine (120), and opposition (180).
  • The most common bug in aspect code is the 360-degree wrap-around: naive subtraction says 355 and 5 are 350 degrees apart when the real distance is 10.
  • Orbs define how far from exact an aspect can be and still count. Tighter orb means stronger influence. The Roxy API uses 8 degrees for conjunction/opposition/trine, 7 for square, 6 for sextile, and 2 to 3 for minor aspects.
  • Build a full aspect table with Roxy Astrology API in one POST request.

About the author: Torsten Brinkmann is an Astrologer and Developer Advocate with 16 years of experience in Western astrology and software engineering. He holds an M.Sc. in Computer Science from TU Munich and has contributed to open-source ephemeris and chart rendering libraries. His writing addresses both the astronomical mathematics behind natal charts and the developer integration patterns for astrology APIs.

If you are building an astrology app, a compatibility feature, or an AI agent that interprets birth charts, you will eventually need to implement planetary aspect calculation. Aspects are the relationships between planets that drive most of the interpretive content in a chart reading. They sound simple. Two planets, one angle, check if it matches. But the implementation has edge cases that silently produce wrong results. This post walks through the geometry, the math, the orb systems, and the wrap-around bug that catches every developer at least once.

What planetary aspects are and why they matter

An aspect is an angular relationship between two planets measured along the ecliptic, the circular path the Sun appears to trace across the sky. When two planets are separated by a specific angle, astrologers consider them linked by an energetic relationship. The nature of that relationship depends on the angle.

The five major aspects form the foundation of chart interpretation. A conjunction (0 degrees) places two planets at the same ecliptic position, fusing their energies. A sextile (60 degrees) indicates a harmonious, moderate connection. A square (90 degrees) signals tension and challenge. A trine (120 degrees) creates a flowing, supportive link. An opposition (180 degrees) establishes polarity and mutual awareness between the two bodies.

Four minor aspects add nuance: semi-sextile (30 degrees), semi-square (45 degrees), sesquiquadrate (135 degrees), and quincunx (150 degrees). Minor aspects carry subtler influence but become significant when other chart factors reinforce them.

Ready to build this? Roxy Astrology API calculates all nine aspect types with orb, strength score, and applying/separating status in a single POST request. See pricing.

How the orb system determines which aspects count

Exact aspects are rare. Two planets separated by precisely 120.000 degrees happens for only a moment. In practice, astrologers use orbs: tolerance ranges around the exact angle. If the angular distance between two planets falls within the orb of an aspect, that aspect is active.

Two orb systems dominate professional software. The fixed orb system assigns a constant tolerance per aspect type regardless of which planets are involved. Typical values: 8 degrees for conjunction and opposition, 7 for square, 6 for trine and sextile, 2 to 3 for minor aspects. The proportional orb system varies the tolerance by planet. Luminaries (Sun and Moon) receive wider orbs of around 10 degrees because their symbolic weight is greater. Outer planets (Uranus, Neptune, Pluto) receive tighter orbs of around 4 degrees because their effects are generational rather than personal.

Aspect strength maps directly to orb tightness. A trine with an orb of 0.5 degrees is far more potent than one at 7.8 degrees. A simple linear formula works well: strength = (1 - orb / maxOrb) * 100. This produces a 0 to 100 score where 100 means exact.

How to solve the 360-degree wrap-around edge case

This is the bug that ships in almost every first implementation of planetary aspect calculation. Two planets sit at ecliptic longitudes 355 degrees and 5 degrees. The naive calculation, abs(355 - 5), returns 350 degrees. The correct answer is 10 degrees. Those planets are in a conjunction, not unrelated.

The ecliptic is a circle. Longitude wraps from 360 back to 0. The shortest arc between two points on a circle is never greater than 180 degrees. The correct formula computes both possible arcs and takes the smaller one:

function angularDistance(lon1, lon2) {
  let diff = Math.abs(lon1 - lon2);
  if (diff > 180) {
    diff = 360 - diff;
  }
  return diff;
}

This three-line function is the foundation of all aspect detection. Without it, your code misses every aspect that straddles the 0/360 boundary, which is roughly where Aries begins in the tropical zodiac. Planets transiting through late Pisces and early Aries will produce phantom gaps in your aspect tables. The fix is small but the consequences of skipping it are chart-breaking.

How applying and separating aspects work

Once you know an aspect exists, the next question is whether it is applying or separating. An applying aspect means the two planets are moving closer to exact alignment. A separating aspect means they have already passed exact and are drifting apart. Applying aspects are traditionally considered stronger because the energy is building rather than fading.

Determining direction requires planet speeds. Each planet moves along the ecliptic at a known daily rate (available from the ephemeris). Project both positions forward by one day using their speeds, then recalculate the orb. If the future orb is smaller than the current orb, the aspect is applying. If larger, it is separating.

Retrograde planets add complexity. When a planet appears to move backward along the ecliptic, its speed is negative. The projection formula handles this naturally because you add the speed (which is negative) to the current longitude. A retrograde planet moving toward exact aspect from the opposite direction still produces a shrinking orb, correctly flagged as applying.

How to check all planet pairs efficiently

A birth chart typically includes 10 planets (Sun through Pluto) plus optional points like the Lunar Nodes and Chiron. For 10 bodies, you need to check 10 * 9 / 2 = 45 unique pairs. For each pair, you compare the angular distance against all 9 aspect angles. That is 405 comparisons per chart.

The algorithm is straightforward. Loop through all pairs using two nested loops where the inner loop starts at i + 1 to avoid duplicates and self-comparisons. For each pair, compute the angular distance once, then check it against every aspect angle plus its orb. Return the first match (aspects cannot overlap when orbs are standard sizes).

for (let i = 0; i < planets.length; i++) {
  for (let j = i + 1; j < planets.length; j++) {
    const distance = angularDistance(planets[i].longitude, planets[j].longitude);
    // Check distance against each aspect angle and orb
  }
}

Performance is never a concern. Even with 13 bodies and 9 aspect types, you run 702 simple comparisons. This finishes in microseconds. Sort the results by strength (tightest orb first) so the most significant aspects appear at the top of your output.

How to get a complete aspect table from a single API call

The Roxy Astrology API runs the full aspect detection pipeline described in this post: angular distance with wrap-around handling, fixed orb thresholds, strength scoring, and applying/separating detection via planet speed projection. All planetary positions are verified against NASA JPL Horizons. Here is a working curl example using the aspects endpoint:

curl -X POST https://roxyapi.com/api/v2/astrology/aspects \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "date": "1990-07-15",
    "time": "14:30:00",
    "timezone": -5
  }'

The response includes every detected aspect with all the fields covered in this post:

{
  "date": "1990-07-15",
  "time": "14:30:00",
  "timezone": -5,
  "aspectsFound": 12,
  "aspects": [
    {
      "planet1": "Sun",
      "planet2": "Moon",
      "type": "TRINE",
      "angle": 120,
      "orb": 2.5,
      "isApplying": true,
      "strength": 75,
      "interpretation": "harmonious",
      "meaning": {
        "name": "Trine",
        "description": {
          "short": "Flowing harmony between planets",
          "long": "A trine indicates natural talent and ease..."
        },
        "keywords": ["harmony", "flow", "talent"],
        "nature": "harmonious"
      }
    }
  ],
  "summary": {
    "totalAspects": 12,
    "harmonious": 5,
    "challenging": 4,
    "neutral": 3,
    "byType": {
      "CONJUNCTION": 2,
      "TRINE": 3,
      "SQUARE": 2,
      "SEXTILE": 2,
      "OPPOSITION": 1,
      "QUINCUNX": 2
    }
  }
}

You can filter by specific planets using the planets array or by aspect type using the aspectTypes array. The timezone field accepts decimal hours (use 5.5 for India, not "5:30"). The time field requires 24-hour HH:MM:SS format.

Frequently Asked Questions

Q: What orb values does the Roxy Astrology API use for planetary aspect calculation? A: The API uses fixed orbs per aspect type: 8 degrees for conjunction, opposition, and trine. 7 degrees for square. 6 degrees for sextile. 3 degrees for semi-sextile and quincunx. 2 degrees for semi-square and sesquiquadrate. These values follow standard Western astrology conventions used in professional chart software.

Q: How is aspect strength calculated from the orb? A: Strength is a linear scale from 0 to 100 based on how close the aspect is to exact. The formula is strength = (1 - orb / maxOrb) * 100. An exact aspect (orb of 0) scores 100. An aspect at the edge of its orb scores near 0. The API returns this as the strength field on every aspect object.

Q: What is the difference between applying and separating aspects? A: An applying aspect occurs when two planets are moving closer to exact alignment. A separating aspect occurs when they have passed exact and are drifting apart. The API determines this by projecting planet positions forward using their daily speeds and comparing future orb to current orb. The isApplying boolean in the response tells you which state the aspect is in.

Q: Can I filter the aspect results to only show specific aspect types? A: Yes. Pass an aspectTypes array in the request body with the types you want. Valid values include CONJUNCTION, OPPOSITION, TRINE, SQUARE, SEXTILE, SEMI_SEXTILE, QUINCUNX, SEMI_SQUARE, and SESQUIQUADRATE. You can also filter by specific planets using the planets array.

Q: Does the aspect calculation handle retrograde planets correctly? A: Yes. Retrograde planets have negative daily speed values from the ephemeris. The applying/separating detection projects positions using these signed speeds, so a retrograde planet moving toward exact aspect from the opposite direction is correctly flagged as applying.

Conclusion

Planetary aspect calculation requires four things done right: the angular distance formula with wrap-around handling, an orb system that defines valid tolerance ranges, strength scoring based on orb tightness, and applying/separating detection from planet speeds. The wrap-around bug at the 0/360 boundary is the single most common error in aspect code, and it silently drops valid aspects from your output. The Roxy Astrology API handles all of this, including all nine standard Western aspects with strength, orb, interpretation, and speed-based direction detection, verified against NASA JPL Horizons. Get your API key at roxyapi.com/pricing and ship your aspect feature today.