This is a remake of the project made for a NASA Hackathon....
- Tharakam is an interactive space orrery which is an adaptation of my old project which I made for a 48 hour hackathon conducted by NASA (NASA Space Apss 2024)
- The hackathon version was build using vanilla js and I importd ThreeJs usin cdn.
- This version is built using react for better perfomance and usablility.
- An orrery is a mechanical, usually clockwork-driven, model of the solar system that demonstrates the orbital motions of planets and moons around the Sun
- An Interactive (Digital) Orrery is where we can move around and modify the cellestial bodies to our desired thing.
- No, not per se; The scale of this orrery is very rough and calulalations have an average of ± 0.22% variation.
- I calculate the planet's radius and length bu using their astronaumical unit (AU) multiply them with 149.6 miln (earth's AU or just AU) to in 2 decimal places.
- This is the main cause of the variation and it is there due to simple performance optimisations.
- Another big flaw is that planets have eliptical orbits and move about with different velocities depending on the gravitational forces acting on it
- And they dont revolve around on the same plane angle...
- I made it like this just for refference and to test out threejs functions.
I will make sure to make it more accurate by the end
Documentation pending...
Documentation pending...
I have stored all the data of each planets in the src/constants/planet.js file.
Each planets object is stored in an array named solar planets.
The planet array is mapped from bottom to top to a non-deconstructed object called planet, and contain data within a group to render their Spherical Mesh, Html Label and Orbit component.
I have setup conditional rendering for label and orbit which toggles as the isOrbitVisible and isLabelVisible
react states changes.
[...solarPlanets].reverse().map((planet) => (
<group key={planet.id}>
{isOrbitVisible && <RenderRadialRadialPath rad={planet.au * 14.96} col={planet.col} />}
{isLabelVisible &&
<Html position={[planet.au * 14.96, 0, 0]} zIndexRange={[0, 0]}>
<span className="bg-gray-900 font-mono px-2 text-[0.75rem]" style={{ color: planet.col }}>{planet.name}</span>
</Html>
}
<Sphere args={[planet.rau * 1496, 32, 32]} position={[planet.au * 14.96, 0, 0]}>
<meshStandardMaterial color={planet.col} />
</Sphere>
</group>
)
)
There isn't a single mesh to create a ring or torus like in blender...
So we used the line segments to make circular orbits.
The function takes two arguments:
rad = radius in au
col = colour hex string value
The function returns a threejs drei component <Line />; which is a mesh of a line segment.
const renOrbitPath = ({ rad, col = "#fff" }) => {
const points = []
const nLineSegments = 64
for (let i = 0; i <= nLineSegments; i++) {
const theta = (i / nLineSegments) * Math.PI * 2
points.push([Math.cos(theta) * rad, 0, Math.sin(theta) * rad])
}
return <Line points={points} color={col} lineWidth={0.25} transparent opacity={1} />
}
ThreeJs drei has an <HTML /> component which allows the canvas to render two dimensional html to the canvas.
It's position can be fixed on the 3d canvas and it'll show the HTML's orthographic projection on the screen.
Here, I am multiplying planet au with earth distance from sun, so that I can get the total distance of the planet from the sun Problem: I only use two decimal points so the precision is lower and room for error is more
ie., au of mercury = 0.39 distance of mercury from sun = 57,900,000 distance of earth from sun = 149,600,000 = 1 AU 149,600,000 * 0.39 = 58,344,000
f(x) = modulus of [(meashured - correct ) / correct] * 100 total tolarance of mercury will be = ± 0.77%
similarly, If we take the average of all planets we get ± 0.22% to be the tolerance of this method, which is to be noted for accurate scale...
au arr = []



