/*
- * Sixth - System for data storage, computation, exploration and interaction.
- * Copyright ©2012-2016, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 3 of the GNU Lesser General Public License
- * or later as published by the Free Software Foundation.
+ * Sixth 3D engine. Author: Svjatoslav Agejenko.
+ * This project is released under Creative Commons Zero (CC0) license.
*/
-
package eu.svjatoslav.sixth.e3d.geometry;
+import static java.lang.Math.*;
+
/**
- * Used to represent point in a 3D space, vector or speed.
+ * Used to represent point in a 3D space or vector.
*/
-public class Point3D extends Point2D implements Cloneable {
+public class Point3D implements Cloneable {
- public static final Point3D ZERO = new Point3D();
- public double z;
+ // coordinates
+ public double x, y, z;
public Point3D() {
}
this.z = z;
}
- public Point3D(final Point3D parentPoint) {
- x = parentPoint.x;
- y = parentPoint.y;
- z = parentPoint.z;
+ /**
+ * Creates new current point by cloning coordinates from parent point.
+ */
+ public Point3D(final Point3D parent) {
+ x = parent.x;
+ y = parent.y;
+ z = parent.z;
}
- public Point3D add(final Point3D direction) {
- super.add(direction);
- z += direction.z;
+ /**
+ * Add other point to current point. Value of other point will not be changed.
+ *
+ * @param otherPoint point to add.
+ * @return current point.
+ */
+ public Point3D add(final Point3D otherPoint) {
+ x += otherPoint.x;
+ y += otherPoint.y;
+ z += otherPoint.z;
return this;
}
- @Override
public Point3D clone() {
return new Point3D(this);
}
- public Point3D clone(final Point3D source) {
- x = source.x;
- y = source.y;
- z = source.z;
+ /**
+ * Copy coordinates from other point to current point. Value of other point will not be changed.
+ */
+ public Point3D clone(final Point3D otherPoint) {
+ x = otherPoint.x;
+ y = otherPoint.y;
+ z = otherPoint.z;
return this;
}
+ /**
+ * Set current point coordinates to the middle point between two other points.
+ *
+ * @param p1 first point.
+ * @param p2 second point.
+ * @return current point.
+ */
public Point3D computeMiddlePoint(final Point3D p1, final Point3D p2) {
x = (p1.x + p2.x) / 2d;
y = (p1.y + p2.y) / 2d;
return this;
}
+ /**
+ * @return true if current point coordinates are equal to zero.
+ */
+ public boolean isZero() {
+ return (x == 0) && (y == 0) && (z == 0);
+ }
+
public double getAngleXZ(final Point3D anotherPoint) {
return Math.atan2(x - anotherPoint.x, z - anotherPoint.z);
}
return Math.atan2(y - anotherPoint.y, z - anotherPoint.z);
}
+ public double getAngleXY(final Point3D anotherPoint) {
+ return Math.atan2(x - anotherPoint.x, y - anotherPoint.y);
+ }
+
/**
* Compute distance to another point.
+ *
+ * @param anotherPoint point to compute distance to.
+ * @return distance to another point.
*/
public double getDistanceTo(final Point3D anotherPoint) {
final double xDelta = x - anotherPoint.x;
final double yDelta = y - anotherPoint.y;
final double zDelta = z - anotherPoint.z;
- return Math
- .sqrt(((xDelta * xDelta) + (yDelta * yDelta) + (zDelta * zDelta)));
+ return sqrt(((xDelta * xDelta) + (yDelta * yDelta) + (zDelta * zDelta)));
}
- @Override
+ /**
+ * @return length of current vector.
+ */
+ public double getVectorLength() {
+ return sqrt(((x * x) + (y * y) + (z * z)));
+ }
+
+ /**
+ * Invert current point coordinates.
+ *
+ * @return current point.
+ */
public Point3D invert() {
x = -x;
y = -y;
return this;
}
+ /**
+ * Rotate current point around center point by angleXZ and angleYZ.
+ * <p>
+ * See also: <a href="https://marctenbosch.com/quaternions/">Let's remove Quaternions from every 3D Engine</a>
+ *
+ * @param center center point.
+ * @param angleXZ angle around XZ axis.
+ * @param angleYZ angle around YZ axis.
+ */
public void rotate(final Point3D center, final double angleXZ,
final double angleYZ) {
- final double s1 = Math.sin(angleXZ);
- final double c1 = Math.cos(angleXZ);
+ final double s1 = sin(angleXZ);
+ final double c1 = cos(angleXZ);
- final double s2 = Math.sin(angleYZ);
- final double c2 = Math.cos(angleYZ);
+ final double s2 = sin(angleYZ);
+ final double c2 = cos(angleYZ);
x -= center.x;
y -= center.y;
z = z2 + center.z;
}
- @Override
+ /**
+ * Round current point coordinates to integer values.
+ */
public void roundToInteger() {
x = (int) x;
y = (int) y;
z = (int) z;
}
+ /**
+ * Scale down current point by factor.
+ * All coordinates will be divided by factor.
+ *
+ * @param factor factor to scale by.
+ * @return current point.
+ */
public Point3D scaleDown(final double factor) {
x /= factor;
y /= factor;
return this;
}
+ /**
+ * Scale up current point by factor.
+ * All coordinates will be multiplied by factor.
+ *
+ * @param factor factor to scale by.
+ * @return current point.
+ */
public Point3D scaleUp(final double factor) {
x *= factor;
y *= factor;
return this;
}
+ /**
+ * Set current point coordinates to given values.
+ * @param x X coordinate.
+ * @param y Y coordinate.
+ * @param z Z coordinate.
+ */
public void setValues(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
- public Point3D subtract(final Point3D direction) {
- super.subtract(direction);
- z -= direction.z;
+ /**
+ * Subtract other point from current point. Value of other point will not be changed.
+ *
+ * @return current point.
+ */
+ public Point3D subtract(final Point3D otherPoint) {
+ x -= otherPoint.x;
+ y -= otherPoint.y;
+ z -= otherPoint.z;
return this;
}
return "x:" + x + " y:" + y + " z:" + z;
}
+ /**
+ * Translate current point along X axis by given increment.
+ *
+ * @return current point.
+ */
public Point3D translateX(final double xIncrement) {
x += xIncrement;
return this;
}
+ /**
+ * Translate current point along Y axis by given increment.
+ *
+ * @return current point.
+ */
public Point3D translateY(final double yIncrement) {
y += yIncrement;
return this;
}
+ /**
+ * Translate current point along Z axis by given increment.
+ *
+ * @return current point.
+ */
public Point3D translateZ(final double zIncrement) {
z += zIncrement;
return this;
}
- public boolean withinDrawingLimits() {
-
- if (z > 0)
- return true;
-
- // if ((z > 0) && (x > -1000) && (y > -1000) && (x < 2000) && (y <
- // 2000))
- // return true;
-
- return false;
+ /**
+ * Here we assume that Z coordinate is distance to the viewer.
+ * If Z is positive, then point is in front of the viewer, and therefore it is visible.
+ *
+ * @return point visibility status.
+ */
+ public boolean isVisible() {
+ return z > 0;
}
- @Override
+ /**
+ * Resets point coordinates to zero along all axes.
+ *
+ * @return current point.
+ */
public Point3D zero() {
- super.zero();
+ x = 0;
+ y = 0;
z = 0;
return this;
}