87 lines
3.1 KiB
C
Executable File
87 lines
3.1 KiB
C
Executable File
/// _
|
|
/// __ ___ __ | |__ ___ _ __ ___
|
|
/// \ \/ / '_ \| '_ \ / _ \ '__/ _ \
|
|
/// > <| |_) | | | | __/ | | __/
|
|
/// /_/\_\ .__/|_| |_|\___|_| \___|
|
|
/// |_|
|
|
///
|
|
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
|
|
///
|
|
/// xolatile@chud.cyou - xphere - Spherical coordinate system header-only literally library for use in CPU-computed ray tracing...
|
|
///
|
|
/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
|
|
/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
|
|
///
|
|
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
|
|
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
|
|
/// for more details, if you dare, it is a lot of text that nobody wants to read...
|
|
|
|
typedef struct {
|
|
float distance;
|
|
float horizontal;
|
|
float vertical;
|
|
} sphere_vector;
|
|
|
|
static bool sphere_epsilon (float error) {
|
|
return (error < 0.000001);
|
|
}
|
|
|
|
static float sphere_distance (float x, float y, float z) {
|
|
return (square_root (x * x + y * y + z * z));
|
|
}
|
|
|
|
static float sphere_horizontal (float x, float z) {
|
|
return ((sphere_epsilon (z)) ? (sign (x) * pi / 2.0f) : (arc_tangent (x / z)));
|
|
}
|
|
|
|
static float sphere_vertical (float y, float z) {
|
|
return ((sphere_epsilon (z)) ? (sign (y) * pi / 2.0f) : (arc_tangent (y / z)));
|
|
}
|
|
|
|
static float sphere_x (float horizontal, float z) {
|
|
return (z * tangent (horizontal));
|
|
}
|
|
|
|
static float sphere_y (float vertical, float z) {
|
|
return (z * tangent (vertical));
|
|
}
|
|
|
|
static float sphere_z (float distance, float horizontal, float vertical) {
|
|
float x_over_z = tangent (horizontal);
|
|
float y_over_z = tangent (vertical);
|
|
|
|
return (distance * square_root (1.0f / (x_over_z * x_over_z + y_over_z * y_over_z + 1.0f)));
|
|
}
|
|
|
|
static void sphere_transpose_x (float * distance, float * horizontal, float x) {
|
|
float origin = (* distance) * (* distance);
|
|
float offset = x * x;
|
|
float square = origin + offset + 2 * x * (* distance) * cosine (* horizontal);
|
|
|
|
* distance = square_root (square);
|
|
|
|
* horizontal = arc_sine ((square + offset - origin) / (2 * (* distance) * x));
|
|
}
|
|
|
|
static void sphere_transpose_y (float * distance, float * vertical, float y) {
|
|
float origin = (* distance) * (* distance);
|
|
float offset = y * y;
|
|
|
|
* distance = square_root (origin + offset + 2 * y * (* distance) * cosine (* vertical));
|
|
}
|
|
|
|
static void sphere_transpose_z (float * distance, float * horizontal, float * vertical, float z) {
|
|
float origin = (* distance) * (* distance);
|
|
float offset = z * z;
|
|
float side_a = secant (* vertical);
|
|
float side_b = tangent (* horizontal);
|
|
|
|
* distance = square_root (origin + offset + 2 * z * (* distance) * square_root (1.0f / (side_a * side_a + sibe_b * side_b)));
|
|
}
|
|
|
|
static void sphere_convert (sphere_vector * vector, float x, float y, float z) {
|
|
vector->distance = sphere_distance (x, y, z);
|
|
vector->horizontal = sphere_horizontal (x, z);
|
|
vector->vertical = sphere_vertical ( y, z);
|
|
}
|