e2c9868c0c696f707418dd111c6ec9687de6d6d2
[sixth-3d.git] / src / main / java / eu / svjatoslav / sixth / e3d / geometry / Point3D.java
1 /*
2  * Sixth 3D engine. Author: Svjatoslav Agejenko. 
3  * This project is released under Creative Commons Zero (CC0) license.
4  */
5 package eu.svjatoslav.sixth.e3d.geometry;
6
7 import static java.lang.Math.*;
8
9 /**
10  * Used to represent point in a 3D space or vector.
11  */
12
13 public class Point3D implements Cloneable {
14
15     public double x, y, z;
16
17     public Point3D() {
18     }
19
20     public Point3D(final double x, final double y, final double z) {
21         this.x = x;
22         this.y = y;
23         this.z = z;
24     }
25
26     public Point3D(final float x, final float y, final float z) {
27         this.x = x;
28         this.y = y;
29         this.z = z;
30     }
31
32     public Point3D(final int x, final int y, final int z) {
33         this.x = x;
34         this.y = y;
35         this.z = z;
36     }
37
38     /**
39      * Creates new current point by cloning coordinates from parent point.
40      */
41     public Point3D(final Point3D parent) {
42         x = parent.x;
43         y = parent.y;
44         z = parent.z;
45     }
46
47     /**
48      * Add other point to current point.
49      *
50      * @return current point.
51      */
52     public Point3D add(final Point3D otherPoint) {
53         x += otherPoint.x;
54         y += otherPoint.y;
55         z += otherPoint.z;
56         return this;
57     }
58
59     public Point3D clone() {
60         return new Point3D(this);
61     }
62
63     public Point3D clone(final Point3D parent) {
64         x = parent.x;
65         y = parent.y;
66         z = parent.z;
67         return this;
68     }
69
70     public Point3D computeMiddlePoint(final Point3D p1, final Point3D p2) {
71         x = (p1.x + p2.x) / 2d;
72         y = (p1.y + p2.y) / 2d;
73         z = (p1.z + p2.z) / 2d;
74         return this;
75     }
76
77     public boolean isZero() {
78         return (x == 0) && (y == 0) && (z == 0);
79     }
80
81     public double getAngleXZ(final Point3D anotherPoint) {
82         return Math.atan2(x - anotherPoint.x, z - anotherPoint.z);
83     }
84
85     public double getAngleYZ(final Point3D anotherPoint) {
86         return Math.atan2(y - anotherPoint.y, z - anotherPoint.z);
87     }
88
89     public double getAngleXY(final Point3D anotherPoint) {
90         return Math.atan2(x - anotherPoint.x, y - anotherPoint.y);
91     }
92
93     /**
94      * Compute distance to another point.
95      */
96     public double getDistanceTo(final Point3D anotherPoint) {
97         final double xDelta = x - anotherPoint.x;
98         final double yDelta = y - anotherPoint.y;
99         final double zDelta = z - anotherPoint.z;
100
101         return sqrt(((xDelta * xDelta) + (yDelta * yDelta) + (zDelta * zDelta)));
102     }
103
104     public double getVectorLength() {
105         return sqrt(((x * x) + (y * y) + (z * z)));
106     }
107
108     public Point3D invert() {
109         x = -x;
110         y = -y;
111         z = -z;
112         return this;
113     }
114
115     public void rotate(final Point3D center, final double angleXZ,
116                        final double angleYZ) {
117         final double s1 = sin(angleXZ);
118         final double c1 = cos(angleXZ);
119
120         final double s2 = sin(angleYZ);
121         final double c2 = cos(angleYZ);
122
123         x -= center.x;
124         y -= center.y;
125         z -= center.z;
126
127         final double y1 = (z * s2) + (y * c2);
128         final double z1 = (z * c2) - (y * s2);
129
130         final double x1 = (z1 * s1) + (x * c1);
131         final double z2 = (z1 * c1) - (x * s1);
132
133         x = x1 + center.x;
134         y = y1 + center.y;
135         z = z2 + center.z;
136     }
137
138     public void roundToInteger() {
139         x = (int) x;
140         y = (int) y;
141         z = (int) z;
142     }
143
144     public Point3D scaleDown(final double factor) {
145         x /= factor;
146         y /= factor;
147         z /= factor;
148         return this;
149     }
150
151     public Point3D scaleUp(final double factor) {
152         x *= factor;
153         y *= factor;
154         z *= factor;
155         return this;
156     }
157
158     public void setValues(final double x, final double y, final double z) {
159         this.x = x;
160         this.y = y;
161         this.z = z;
162     }
163
164     /**
165      * Subtract other point from current point.
166      *
167      * @return current point.
168      */
169     public Point3D subtract(final Point3D otherPoint) {
170         x -= otherPoint.x;
171         y -= otherPoint.y;
172         z -= otherPoint.z;
173         return this;
174     }
175
176     @Override
177     public String toString() {
178         return "x:" + x + " y:" + y + " z:" + z;
179     }
180
181     /**
182      * @return current point.
183      */
184     public Point3D translateX(final double xIncrement) {
185         x += xIncrement;
186         return this;
187     }
188
189     /**
190      * @return current point.
191      */
192     public Point3D translateY(final double yIncrement) {
193         y += yIncrement;
194         return this;
195     }
196
197     /**
198      * @return current point.
199      */
200     public Point3D translateZ(final double zIncrement) {
201         z += zIncrement;
202         return this;
203     }
204
205     /**
206      * Here we assume that Z coordinate is distance to the viewer.
207      * If Z is positive, then point is in front of the viewer, and therefore it is visible.
208      *
209      * @return point visibility status.
210      */
211     public boolean isVisible() {
212         return z > 0;
213     }
214
215     /**
216      * Resets point to 0 coordinate in X, Y and Z axis.
217      *
218      * @return current point.
219      */
220     public Point3D zero() {
221         x = 0;
222         y = 0;
223         z = 0;
224         return this;
225     }
226
227 }