Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_3d.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
28#include "nilorea/n_3d.h"
29#include "math.h"
30
37double distance(VECTOR3D* p1, VECTOR3D* p2) {
38 return sqrt(((*p1)[0] - (*p2)[0]) * ((*p1)[0] - (*p2)[0]) +
39 ((*p1)[1] - (*p2)[1]) * ((*p1)[1] - (*p2)[1]) +
40 ((*p1)[2] - (*p2)[2]) * ((*p1)[2] - (*p2)[2]));
41} /* distance(...) */
42
50int update_physics_position_nb(PHYSICS* object, int it, double delta_t) {
51 __n_assert(object, return FALSE);
52
53 object->speed[it] = object->speed[it] + (object->acceleration[it] * delta_t) / 1000000.0;
54 object->position[it] = object->position[it] + (object->speed[it] * delta_t) / 1000000.0 + (object->acceleration[it] * (delta_t / 1000000.0) * (delta_t / 1000000.0)) / 2.0;
55 object->angular_speed[it] = object->angular_speed[it] + (object->angular_acceleration[it] * delta_t) / 1000000.0;
56 object->speed[it] = object->speed[it] + (object->gravity[it] * delta_t) / 1000000.0;
57
58 return TRUE;
59} /* update_physics_position_nb(...) */
60
68int update_physics_position_reverse_nb(PHYSICS* object, int it, double delta_t) {
69 __n_assert(object, return FALSE);
70
71 object->position[it] = object->position[it] - ((object->speed[it] * delta_t) / 1000000.0 + (object->acceleration[it] * (delta_t / 1000000.0) * (delta_t / 1000000.0)) / 2.0);
72 object->speed[it] = object->speed[it] - (object->acceleration[it] * delta_t) / 1000000.0;
73 object->angular_speed[it] = object->angular_speed[it] - (object->angular_acceleration[it] * delta_t) / 1000000.0;
74
75 return TRUE;
76} /* update_physics_position_reverse_nb */
77
84int update_physics_position_reverse(PHYSICS* object, double delta_t) {
85 __n_assert(object, return FALSE);
86 for (int it = 0; it < 3; it++) {
87 object->speed[it] = -object->speed[it];
88 object->acceleration[it] = -object->acceleration[it];
89 object->angular_speed[it] = -object->angular_speed[it];
90
91 update_physics_position_nb(object, it, delta_t);
92
93 object->speed[it] = -object->speed[it];
94 object->acceleration[it] = -object->acceleration[it];
95 object->angular_speed[it] = -object->angular_speed[it];
96 }
97 return TRUE;
98} /* update_physics_position_reverse(...) */
99
106int update_physics_position(PHYSICS* object, double delta_t) {
107 __n_assert(object, return FALSE);
108 object->delta_t = (time_t)delta_t;
109 for (int it = 0; it < 3; it++) {
110 update_physics_position_nb(object, it, delta_t);
111 }
112 return TRUE;
113}
114
121static int same_sign(double a, double b) {
122 return ((a * b) >= 0);
123} /* same_sign(...) */
124
135 double a1 = 0, a2 = 0, b1 = 0, b2 = 0, c1 = 0, c2 = 0,
136 r1 = 0, r2 = 0, r3 = 0, r4 = 0,
137 denom = 0, offset = 0, num = 0;
138
139 /* Compute a1, b1, c1, where line joining points 1 and 2 is
140 "a1 x + b1 y + c1 = 0". */
141 a1 = (*p2)[1] - (*p1)[1];
142 b1 = (*p1)[0] - (*p2)[0];
143 c1 = ((*p2)[0] * (*p1)[1]) - ((*p1)[0] * (*p2)[1]);
144
145 /* Compute r3 and r4. */
146 r3 = ((a1 * (*p3)[0]) + (b1 * (*p3)[1]) + c1);
147 r4 = ((a1 * (*p4)[0]) + (b1 * (*p4)[1]) + c1);
148
149 /* Check signs of r3 and r4. If both point 3 and point 4 lie on
150 same side of line 1, the line segments do not intersect. */
151 if ((r3 != 0) && (r4 != 0) && same_sign(r3, r4)) {
153 }
154
155 /* Compute a2, b2, c2 */
156 a2 = (*p4)[1] - (*p3)[1];
157 b2 = (*p3)[0] - (*p4)[0];
158 c2 = ((*p4)[0] * (*p3)[1]) - ((*p3)[0] * (*p4)[1]);
159
160 /* Compute r1 and r2 */
161 r1 = (a2 * (*p1)[0]) + (b2 * (*p1)[1]) + c2;
162 r2 = (a2 * (*p2)[0]) + (b2 * (*p2)[1]) + c2;
163
164 /* Check signs of r1 and r2. If both point 1 and point 2 lie
165 on same side of second line segment, the line segments do
166 not intersect. */
167 if ((r1 != 0) && (r2 != 0) && same_sign(r1, r2)) {
169 }
170
171 /* Line segments intersect: compute intersection point. */
172 denom = (a1 * b2) - (a2 * b1);
173
174 if (denom == 0) {
175 return VECTOR3D_COLLINEAR;
176 }
177
178 if (denom < 0) {
179 offset = -denom / 2;
180 } else {
181 offset = denom / 2;
182 }
183
184 /* The denom/2 is to get rounding instead of truncating. It
185 is added or subtracted to the numerator, depending upon the
186 sign of the numerator. */
187 num = (b1 * c2) - (b2 * c1);
188 if (num < 0) {
189 (*px)[0] = (num - offset) / denom;
190 } else {
191 (*px)[0] = (num + offset) / denom;
192 }
193
194 num = (a2 * c1) - (a1 * c2);
195 if (num < 0) {
196 (*px)[1] = (num - offset) / denom;
197 } else {
198 (*px)[1] = (num + offset) / denom;
199 }
200
201 /* lines_intersect */
203} /* vector_intersect(...) */
204
212 return (*vec1)[0] * (*vec2)[0] + (*vec1)[1] * (*vec2)[1] + (*vec1)[2] * (*vec2)[2];
213} /* vector_dot_product(...) */
214
221 double res = 0.0;
222 for (int i = 0; i < 3; i++) {
223 res += pow((*vec)[i], 2);
224 }
225 return sqrt(res);
226} /* vector_normalize(...) */
227
235 double norm = vector_normalize(vec1) * vector_normalize(vec2);
236 if (norm == 0.0) return 0.0;
237 return acos(vector_dot_product(vec1, vec2) / norm);
238} /* vector_angle_between( ... ) */
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:279
VECTOR3D acceleration
ax,ay,az actual acceleration
Definition n_3d.h:78
double vector_dot_product(VECTOR3D *vec1, VECTOR3D *vec2)
Compute the dot product of two VECTOR3D.
Definition n_3d.c:211
#define VECTOR3D_COLLINEAR
value when the two VECTOR3D are collinear
Definition n_3d.h:54
double distance(VECTOR3D *p1, VECTOR3D *p2)
compute the distance between two VECTOR3D points
Definition n_3d.c:37
#define VECTOR3D_DO_INTERSECT
value when the two VECTOR3D are intersecting
Definition n_3d.h:56
double VECTOR3D[3]
struct of a point
Definition n_3d.h:59
double vector_angle_between(VECTOR3D *vec1, VECTOR3D *vec2)
Compute angle between two VECTOR3D.
Definition n_3d.c:234
int update_physics_position_nb(PHYSICS *object, int it, double delta_t)
Update object position component.
Definition n_3d.c:50
#define VECTOR3D_DONT_INTERSECT
value when the two VECTOR3D are not connected
Definition n_3d.h:52
int update_physics_position_reverse(PHYSICS *object, double delta_t)
Update object position, reversed.
Definition n_3d.c:84
int update_physics_position_reverse_nb(PHYSICS *object, int it, double delta_t)
Update object position component, reversed.
Definition n_3d.c:68
double vector_normalize(VECTOR3D *vec)
Return the normalized value of vec.
Definition n_3d.c:220
int update_physics_position(PHYSICS *object, double delta_t)
Update object position.
Definition n_3d.c:106
int vector_intersect(VECTOR3D *p1, VECTOR3D *p2, VECTOR3D *p3, VECTOR3D *p4, VECTOR3D *px)
Compute if two vectors are intersecting or not.
Definition n_3d.c:134
structure of the physics of an object
Definition n_3d.h:70
static int same_sign(double a, double b)
Quickly check if two values are the same sign or not.
Definition n_3d.c:121
Simple 3D movement simulation.