Skip to content

Commit 7eae139

Browse files
committed
Update SolarSystem Example
1 parent d740c43 commit 7eae139

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3663
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* Quaternion minimal para rotações 3D e SLERP.
3+
*/
4+
class Quaternion {
5+
float w, x, y, z;
6+
7+
Quaternion(float w_, float x_, float y_, float z_) {
8+
w = w_; x = x_; y = y_; z = z_;
9+
}
10+
11+
// constrói a partir de eixo (unitário) e ângulo (rad)
12+
Quaternion fromAxisAngle(PVector axis, float angle) {
13+
float half = angle * 0.5f;
14+
float s = sin(half);
15+
return new Quaternion(
16+
cos(half),
17+
axis.x * s,
18+
axis.y * s,
19+
axis.z * s
20+
).normalize();
21+
}
22+
23+
// normaliza
24+
Quaternion normalize() {
25+
float m = sqrt(w*w + x*x + y*y + z*z);
26+
w /= m; x /= m; y /= m; z /= m;
27+
return this;
28+
}
29+
30+
// compõe rotações
31+
Quaternion multiply(Quaternion q) {
32+
return new Quaternion(
33+
w*q.w - x*q.x - y*q.y - z*q.z,
34+
w*q.x + x*q.w + y*q.z - z*q.y,
35+
w*q.y - x*q.z + y*q.w + z*q.x,
36+
w*q.z + x*q.y - y*q.x + z*q.w
37+
);
38+
}
39+
40+
// converte para matriz col-major 4×4
41+
float[] toMatrix() {
42+
float[] m = new float[16];
43+
m[0] = 1 - 2*(y*y + z*z);
44+
m[1] = 2*(x*y + z*w);
45+
m[2] = 2*(x*z - y*w);
46+
m[3] = 0;
47+
48+
m[4] = 2*(x*y - z*w);
49+
m[5] = 1 - 2*(x*x + z*z);
50+
m[6] = 2*(y*z + x*w);
51+
m[7] = 0;
52+
53+
m[8] = 2*(x*z + y*w);
54+
m[9] = 2*(y*z - x*w);
55+
m[10] = 1 - 2*(x*x + y*y);
56+
m[11] = 0;
57+
58+
m[12] = m[13] = m[14] = 0;
59+
m[15] = 1;
60+
return m;
61+
}
62+
63+
// SLERP entre this e q2
64+
Quaternion slerp(Quaternion q2, float t) {
65+
float dot = w*q2.w + x*q2.x + y*q2.y + z*q2.z;
66+
dot = constrain(dot, -1, 1);
67+
float theta = acos(dot);
68+
if (theta < 1e-6) return this;
69+
float sinT = sin(theta);
70+
float w1 = sin((1 - t) * theta) / sinT;
71+
float w2 = sin(t * theta) / sinT;
72+
return new Quaternion(
73+
w1*w + w2*q2.w,
74+
w1*x + w2*q2.x,
75+
w1*y + w2*q2.y,
76+
w1*z + w2*q2.z
77+
).normalize();
78+
}
79+
}
80+
81+
82+
/**
83+
* Controlador de câmera com quaternion para rotações estáveis
84+
* e interpolação suave entre posições e orientações.
85+
*/
86+
class CameraController {
87+
PVector target; // ponto que a câmera olha
88+
float distance; // distância ao target
89+
Quaternion orientation; // orientação atual
90+
91+
PVector goalTarget;
92+
Quaternion goalOrientation;
93+
float goalDistance;
94+
float lerpFactor = 0.1f; // suavização
95+
96+
CameraController(PVector initialTarget, float initialDistance) {
97+
target = initialTarget.copy();
98+
goalTarget = initialTarget.copy();
99+
distance = initialDistance;
100+
goalDistance = initialDistance;
101+
orientation = new Quaternion(1, 0, 0, 0);
102+
goalOrientation = orientation;
103+
}
104+
105+
// aplica no PGraphicsOpenGL
106+
void apply(PGraphicsOpenGL pg) {
107+
pg.translate(0, 0, -distance);
108+
float[] M = orientation.toMatrix();
109+
pg.applyMatrix(
110+
M[0], M[4], M[8], M[12],
111+
M[1], M[5], M[9], M[13],
112+
M[2], M[6], M[10], M[14],
113+
M[3], M[7], M[11], M[15]
114+
);
115+
pg.translate(-target.x, -target.y, -target.z);
116+
}
117+
118+
// atualiza cada frame (SLERP/LERP)
119+
void update() {
120+
orientation = orientation.slerp(goalOrientation, lerpFactor);
121+
target = PVector.lerp(target, goalTarget, lerpFactor);
122+
distance = lerp(distance, goalDistance, lerpFactor);
123+
}
124+
125+
// define nova meta (alvo, orientação, distância)
126+
void goTo(PVector t, Quaternion o, float d) {
127+
goalTarget = t.copy();
128+
goalOrientation = o.normalize();
129+
goalDistance = d;
130+
}
131+
132+
// rotaciona em torno de um eixo do mundo
133+
void rotateAround(PVector axis, float angle) {
134+
Quaternion delta = new Quaternion(1,0,0,0).fromAxisAngle(axis, angle);
135+
orientation = delta.multiply(orientation).normalize();
136+
goalOrientation = orientation;
137+
}
138+
139+
// setters diretos (sem suavização)
140+
void setTarget(PVector t) { target = goalTarget = t.copy(); }
141+
void setOrientation(Quaternion q) {
142+
orientation = goalOrientation = q.normalize();
143+
}
144+
void setDistance(float d) { distance = goalDistance = d; }
145+
146+
// getters
147+
PVector getTarget() { return target.copy(); }
148+
float getDistance() { return distance; }
149+
Quaternion getOrientation() { return orientation; }
150+
151+
// utilitário lerp
152+
float lerp(float a, float b, float f) {
153+
return a + (b - a) * f;
154+
}
155+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Corpo celeste genérico (Sol, planeta ou lua) – unidades:
3+
* • posição-velocidade: AU | • tempo: dias | • massa: M☉
4+
*/
5+
public interface CelestialBody {
6+
7+
// ───────────────────────────── Estado dinâmico ────────────────────────────
8+
/** Posição heliocêntrica (ou planetocêntrica, para luas) em AU. */
9+
PVector getPositionAU();
10+
11+
/** Velocidade em AU/dia. */
12+
PVector getVelocityAU();
13+
14+
/** Massa em massas solares (M☉). */
15+
float getMassSolar();
16+
17+
/** Corpo-foco (Sol → planetas, planeta → luas). */
18+
CelestialBody getCentralBody();
19+
void setCentralBody(CelestialBody c);
20+
21+
/** Propaga a órbita por <code>dtDays</code> usando o solver Kepleriano. */
22+
void propagateKepler(float dtDays);
23+
24+
// ───────────────────────────── Elementos orbitais ─────────────────────────
25+
/** Semi-eixo maior <i>a</i> em AU. */ // ★ novo
26+
float getSemiMajorAxisAU();
27+
28+
/** Distância de periélio (q = a·(1-e)) em AU. */
29+
float getPerihelionAU();
30+
31+
/** Distância de afélio (Q = a·(1+e)) em AU. */
32+
float getAphelionAU();
33+
34+
/** Excentricidade e. */
35+
float getEccentricity();
36+
37+
/** Inclinação orbital <i>i</i> (rad). */
38+
float getOrbitInclinationRad();
39+
40+
/** Longitude do nó ascendente Ω (rad). */ // ★ novo
41+
float getLongitudeAscendingNodeRad();
42+
43+
/** Argumento do periastro ω (rad). */
44+
float getArgumentOfPeriapsisRad();
45+
46+
/** Anomalia média <i>M</i> no epoch J2000 (rad). */ // ★ novo
47+
float getMeanAnomalyRad();
48+
49+
// ───────────────────────────── Auxiliares de render ───────────────────────
50+
/** Raio físico (AU). */
51+
float getRadiusAU();
52+
53+
/** Período de rotação sideral (dias). */
54+
float getRotationPeriodDays();
55+
}

0 commit comments

Comments
 (0)