Welcome to an in-depth exploration of creating a dynamic 3D planetary battle system using p5.js! Whether you’re a budding game developer or a curious enthusiast eager to understand the blend of mathematics and graphics in game design, this guide will illuminate how to craft a visually captivating planet with latitude and longitude lines, render satellites orbiting in three-dimensional space, and visualize their attack ranges—all through the magic of two-dimensional projection.
Table of Contents
- Table of Contents
- Introduction
- Creating the Planet with Latitude and Longitude Lines
- Projecting 3D Space onto a 2D Canvas
- Drawing Satellite Orbits with Occlusion and Perspective
- Calculating and Displaying Satellite Attack Ranges
- Conclusion
Introduction
In the realm of game development, creating immersive and visually appealing environments is paramount. One fascinating aspect is the simulation of three-dimensional (3D) spaces within a two-dimensional (2D) canvas—a technique widely used in game engines and graphics programming. This blog delves into a p5.js implementation that brings to life a planet adorned with latitude and longitude lines, satellites orbiting it, and dynamic attack ranges—all rendered seamlessly on a 2D screen.
By leveraging mathematical concepts like quaternions for rotation and vector projections for depth perception, we can achieve a realistic and interactive 3D experience. Let’s embark on this journey to unravel the intricacies behind each component.
Creating the Planet with Latitude and Longitude Lines
At the heart of our visualization lies the planet, a sphere defined by its radius and mass. To enhance realism, we overlay it with latitude and longitude lines, mimicking Earth’s geographical framework.
Defining the Planet
The planet is characterized by several parameters:
- Radius (
radius
): Determines the size of the planet on the canvas. - Mass (
planetMass
): Influences gravitational calculations, essential for satellite orbits. - Rotation (
rotationAngle
): Simulates the planet’s spin, adding dynamism to the scene.
Drawing the Sphere
In p5.js, a sphere can be represented by drawing multiple circles (latitude) and lines (longitude). Here’s how the code accomplishes this:
|
Latitude and Longitude Lines
Latitude lines are horizontal circles that run parallel to the equator, while longitude lines are vertical lines that converge at the poles. To simulate these:
- Latitude Lines: Loop through various latitudes (e.g., every 20 degrees) and draw ellipses adjusted for the planet’s rotation.
- Longitude Lines: Loop through various longitudes (e.g., every 20 degrees) and draw lines that bend according to the planet’s spherical shape.
The rotation of the planet is handled using quaternions (discussed later), ensuring smooth and realistic spinning.
|
Key Concepts:
- 3D Coordinates: Each point on the sphere is calculated using spherical coordinates, transformed into Cartesian coordinates (
x0
,y0
,z0
). - Rotation: The planet’s rotation is applied to these points using quaternions, allowing for smooth and continuous spinning without the pitfalls of Euler angles (like gimbal lock).
- Projection: The rotated 3D points are projected onto the 2D canvas by mapping the
z-axis
to the horizontalx-axis
and they-axis
to the verticaly-axis
. - Transparency: Points further from the viewer (based on the
x
value) appear darker, enhancing the depth perception.
Projecting 3D Space onto a 2D Canvas
Rendering 3D objects on a 2D screen involves projecting their spatial coordinates onto a flat plane. This process is pivotal for creating the illusion of depth and perspective.
Understanding Projection
Projection transforms 3D coordinates (x, y, z)
into 2D coordinates (screenX, screenY)
. In our implementation:
- Orthographic Projection: A simple form where depth (
z
) affects thex
coordinate’s placement, but there’s no scaling based on distance (i.e., objects don’t appear smaller as they move away).
The formula used:
|
Here, the z-axis
directly influences the horizontal placement (screenX
), while the y-axis
affects the vertical placement (screenY
). This mapping ensures that objects with higher z
values appear further to the right, simulating depth.
Applying Quaternions for Rotation
Quaternions are mathematical constructs that represent rotations in 3D space without suffering from gimbal lock—a common issue with Euler angles where rotational axes can become misaligned.
Quaternion Rotation Process:
- Define Rotation Axis and Angle: Specify the axis around which to rotate and the angle of rotation.
- Create Rotation Quaternion: Construct a quaternion representing this rotation.
- Apply Rotation: Multiply the point’s vector by the rotation quaternion to obtain the rotated vector.
Code Snippet:
|
Benefits of Using Quaternions:
- Smooth Rotations: Enables continuous and fluid spinning of the planet.
- Avoids Gimbal Lock: Maintains consistent rotational axes, crucial for multi-axis rotations.
Drawing Satellite Orbits with Occlusion and Perspective
Satellites orbiting the planet add layers of complexity and interactivity. Visualizing their paths involves not just drawing circles but accounting for their three-dimensional trajectories and interactions with the planet’s surface.
Defining Satellite Orbits
Each satellite has:
- Orbit Radius (
orbitRadius
): Distance from the planet’s center. - Orbit Quaternion (
orbitQuat
): Represents the orientation of the orbit in 3D space. - Satellite Angle (
satelliteAngle
): Current position along the orbit. - Orbital Speed (
orbitalSpeed
): Determines how fast the satellite moves.
Rendering Orbits
To depict satellite orbits:
- Calculate Orbit Path: Use the orbit’s quaternion to determine its orientation in space.
- Draw the Path: Iterate through angles (0° to 360°) to plot the orbit’s trajectory, adjusting for occlusion.
- Handle Occlusion: Determine if parts of the orbit are behind the planet, rendering them invisible or with reduced opacity.
Code Snippet:
|
Occlusion and Visibility
Occlusion ensures that satellites behind the planet are not fully visible, maintaining realism. The logic determines whether a satellite or a point on its orbit is obscured by the planet’s sphere based on their spatial coordinates.
Steps:
- Calculate Position: Determine the satellite’s position in 3D space.
- Determine Visibility: If a satellite’s position intersects with the planet’s sphere (i.e., it’s behind), adjust its rendering style (e.g., dashed outline).
- Render Accordingly: Visible satellites are drawn normally, while occluded ones have a distinct appearance.
Perspective and Depth
By mapping the z-axis
to the horizontal x-axis
and adjusting transparency based on the x
value, satellites appear to move towards or away from the viewer, enhancing the depth perception.
Calculating and Displaying Satellite Attack Ranges
Visualizing attack ranges adds strategic depth to the battle system, allowing players to understand the influence areas of their satellites.
Defining Attack Range
Each satellite possesses an attack range (shootingRange
) determining how far its influence extends. This range is visualized as a circular area around the satellite’s current position.
Calculating the Range
The attack range is calculated based on the satellite’s position relative to the planet. It involves determining whether the range intersects with the planet’s surface and rendering the overlapping areas appropriately.
Mathematical Concepts:
- Circle Intersection: Determines if the attack range circle intersects with the planet’s sphere.
- Orthogonal Projection: Projects the 3D range onto the 2D canvas, considering the planet’s rotation.
Rendering the Attack Range
The attack range is depicted as a shaded area around each satellite. If the range overlaps with the planet, it appears partially obscured to maintain realism.
Code Snippet:
|
Key Steps:
- Intersection Calculation: Determines where the attack range intersects with the planet’s surface, ensuring that overlapping areas are handled correctly.
- Orthogonal Basis Construction: Constructs an orthogonal basis (
u
,v
) for the intersection circle, facilitating the sampling of points around it. - Projection and Rendering: Projects the 3D intersection points onto the 2D canvas, distinguishing between front and back areas to handle visibility and shading.
Conclusion
Creating a 3D planetary battle system within a 2D canvas using p5.js is a harmonious blend of mathematics and graphics programming. By leveraging concepts like quaternions for smooth rotations, vector projections for depth perception, and geometric intersections for realistic attack range visualization, developers can craft immersive and interactive environments.
This exploration showcased how to:
- Render a rotating planet with latitude and longitude lines using quaternion-based rotations.
- Project 3D space onto a 2D canvas to simulate depth and perspective.
- Visualize satellite orbits with occlusion handling to enhance realism.
- Calculate and display attack ranges dynamically, accounting for intersections with the planet.
For beginners, integrating these concepts can seem daunting, but breaking them down into manageable components—as demonstrated—makes the process approachable. As you continue to experiment and refine these techniques, you’ll unlock the potential to create even more sophisticated and engaging visualizations in your projects.
Happy coding, and may your virtual universes shine brilliantly!
About this Post
This post is written by FFFeiya, licensed under CC BY-NC 4.0.