2 * Sixth 3D engine. Author: Svjatoslav Agejenko.
3 * This project is released under Creative Commons Zero (CC0) license.
5 package eu.svjatoslav.sixth.e3d.geometry;
7 import eu.svjatoslav.sixth.e3d.renderer.octree.IntegerPoint;
9 import static java.lang.Math.*;
12 * Used to represent point in a 3D space or vector.
17 public class Point3D implements Cloneable {
20 public double x, y, z;
25 public Point3D(final double x, final double y, final double z) {
31 public Point3D(final float x, final float y, final float z) {
37 public Point3D(final int x, final int y, final int z) {
43 public Point3D(IntegerPoint point) {
51 * Creates new current point by cloning coordinates from parent point.
53 public Point3D(final Point3D parent) {
60 * Add other point to current point. Value of other point will not be changed.
62 * @param otherPoint point to add.
63 * @return current point.
65 public Point3D add(final Point3D otherPoint) {
73 * Add coordinates of current point to other point. Value of current point will not be changed.
75 * @return current point.
77 public Point3D addTo(final Point3D... otherPoints) {
78 for (final Point3D otherPoint : otherPoints) otherPoint.add(this);
83 * Create new point by cloning position of current point.
85 * @return newly created clone.
87 public Point3D clone() {
88 return new Point3D(this);
92 * Copy coordinates from other point to current point. Value of other point will not be changed.
94 public Point3D clone(final Point3D otherPoint) {
102 * Set current point coordinates to the middle point between two other points.
104 * @param p1 first point.
105 * @param p2 second point.
106 * @return current point.
108 public Point3D computeMiddlePoint(final Point3D p1, final Point3D p2) {
109 x = (p1.x + p2.x) / 2d;
110 y = (p1.y + p2.y) / 2d;
111 z = (p1.z + p2.z) / 2d;
116 * @return true if current point coordinates are equal to zero.
118 public boolean isZero() {
119 return (x == 0) && (y == 0) && (z == 0);
122 public double getAngleXZ(final Point3D anotherPoint) {
123 return Math.atan2(x - anotherPoint.x, z - anotherPoint.z);
126 public double getAngleYZ(final Point3D anotherPoint) {
127 return Math.atan2(y - anotherPoint.y, z - anotherPoint.z);
130 public double getAngleXY(final Point3D anotherPoint) {
131 return Math.atan2(x - anotherPoint.x, y - anotherPoint.y);
135 * Compute distance to another point.
137 * @param anotherPoint point to compute distance to.
138 * @return distance to another point.
140 public double getDistanceTo(final Point3D anotherPoint) {
141 final double xDelta = x - anotherPoint.x;
142 final double yDelta = y - anotherPoint.y;
143 final double zDelta = z - anotherPoint.z;
145 return sqrt(((xDelta * xDelta) + (yDelta * yDelta) + (zDelta * zDelta)));
149 * @return length of current vector.
151 public double getVectorLength() {
152 return sqrt(((x * x) + (y * y) + (z * z)));
156 * Invert current point coordinates.
158 * @return current point.
160 public Point3D invert() {
168 * Rotate current point around center point by angleXZ and angleYZ.
170 * See also: <a href="https://marctenbosch.com/quaternions/">Let's remove Quaternions from every 3D Engine</a>
172 * @param center center point.
173 * @param angleXZ angle around XZ axis.
174 * @param angleYZ angle around YZ axis.
176 public Point3D rotate(final Point3D center, final double angleXZ,
177 final double angleYZ) {
178 final double s1 = sin(angleXZ);
179 final double c1 = cos(angleXZ);
181 final double s2 = sin(angleYZ);
182 final double c2 = cos(angleYZ);
188 final double y1 = (z * s2) + (y * c2);
189 final double z1 = (z * c2) - (y * s2);
191 final double x1 = (z1 * s1) + (x * c1);
192 final double z2 = (z1 * c1) - (x * s1);
201 public Point3D rotate(final double angleXZ, final double angleYZ) {
202 return rotate(new Point3D(0, 0, 0), angleXZ, angleYZ);
206 * Round current point coordinates to integer values.
208 public void roundToInteger() {
215 * Scale down current point by factor.
216 * All coordinates will be divided by factor.
218 * @param factor factor to scale by.
219 * @return current point.
221 public Point3D scaleDown(final double factor) {
229 * Scale up current point by factor.
230 * All coordinates will be multiplied by factor.
232 * @param factor factor to scale by.
233 * @return current point.
235 public Point3D scaleUp(final double factor) {
243 * Set current point coordinates to given values.
245 * @param x X coordinate.
246 * @param y Y coordinate.
247 * @param z Z coordinate.
249 public void setValues(final double x, final double y, final double z) {
256 * Subtract other point from current point. Value of other point will not be changed.
258 * @return current point.
260 public Point3D subtract(final Point3D otherPoint) {
268 public String toString() {
269 return "x:" + x + " y:" + y + " z:" + z;
273 * Translate current point along X axis by given increment.
275 * @return current point.
277 public Point3D translateX(final double xIncrement) {
283 * Translate current point along Y axis by given increment.
285 * @return current point.
287 public Point3D translateY(final double yIncrement) {
293 * Translate current point along Z axis by given increment.
295 * @return current point.
297 public Point3D translateZ(final double zIncrement) {
303 * Here we assume that Z coordinate is distance to the viewer.
304 * If Z is positive, then point is in front of the viewer, and therefore it is visible.
306 * @return point visibility status.
308 public boolean isVisible() {
313 * Resets point coordinates to zero along all axes.
315 * @return current point.
317 public Point3D zero() {