/// _ /// __ ___ __ | |__ ___ _ __ ___ /// \ \/ / '_ \| '_ \ / _ \ '__/ _ \ /// > <| |_) | | | | __/ | | __/ /// /_/\_\ .__/|_| |_|\___|_| \___| /// |_| /// /// 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 { real distance; real horizontal; real vertical; } sphere_vector; static boolean sphere_epsilon (real error) { return (error < 0.000001); } static real sphere_distance (real x, real y, real z) { return (square_root (x * x + y * y + z * z)); } static real sphere_horizontal (real x, real z) { return ((sphere_epsilon (z)) ? (sign (x) * pi / 2.0f) : (arc_tangent (x / z))); } static real sphere_vertical (real y, real z) { return ((sphere_epsilon (z)) ? (sign (y) * pi / 2.0f) : (arc_tangent (y / z))); } static real sphere_x (real horizontal, real z) { return (z * tangent (horizontal)); } static real sphere_y (real vertical, real z) { return (z * tangent (vertical)); } static real sphere_z (real distance, real horizontal, real vertical) { real x_over_z = tangent (horizontal); real 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 procedure sphere_transpose_x (real * distance, real * horizontal, real x) { real origin = (* distance) * (* distance); real offset = x * x; real square = origin + offset + 2 * x * (* distance) * cosine (* horizontal); * distance = square_root (square); * horizontal = arc_sine ((square + offset - origin) / (2 * (* distance) * x)); } static procedure sphere_transpose_y (real * distance, real * vertical, real y) { real origin = (* distance) * (* distance); real offset = y * y; * distance = square_root (origin + offset + 2 * y * (* distance) * cosine (* vertical)); } static procedure sphere_transpose_z (real * distance, real * horizontal, real * vertical, real z) { real origin = (* distance) * (* distance); real offset = z * z; real side_a = secant (* vertical); real 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 procedure sphere_convert (sphere_vector * vector, real x, real y, real z) { vector->distance = sphere_distance (x, y, z); vector->horizontal = sphere_horizontal (x, z); vector->vertical = sphere_vertical ( y, z); }