    001/* ===========================================================
    002 * Orson Charts : a 3D chart library for the Java(tm) platform
    003 * ===========================================================
    004 *
    005 * (C)opyright 2013-2022, by David Gilbert.  All rights reserved.
    006 *
    007 * https://github.com/jfree/orson-charts
    008 *
    009 * This program is free software: you can redistribute it and/or modify
    010 * it under the terms of the GNU General Public License as published by
    011 * the Free Software Foundation, either version 3 of the License, or
    012 * (at your option) any later version.
    013 *
    014 * This program is distributed in the hope that it will be useful,
    015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
    016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    017 * GNU General Public License for more details.
    018 *
    019 * You should have received a copy of the GNU General Public License
    020 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    021 *
    022 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    023 * Other names may be trademarks of their respective owners.]
    024 *
    025 * If you do not wish to be bound by the terms of the GPL, an alternative
    026 * commercial license can be purchased.  For details, please see visit the
    027 * Orson Charts home page:
    028 *
    029 * http://www.object-refinery.com/orsoncharts/index.html
    030 *
    031 */
    032
    033package org.jfree.chart3d.graphics3d;
    034
    035import java.io.Serializable;
    036
    037/**
    038 * A point in 3D space (this class is also used to represent vectors in 3D
    039 * space).  Instances of this class are immutable.
    040 * <br><br>
    041 * NOTE: This class is serializable, but the serialization format is subject
    042 * to change in future releases and should not be relied upon for persisting
    043 * instances of this class.
    044 */
    045@SuppressWarnings("serial")
    046public final class Point3D implements Serializable {
    047
    048    /** The origin {@code (0, 0, 0)}. */
    049    public static final Point3D ORIGIN = new Point3D(0, 0, 0);
    050
    051    /** The point {@code (1, 0, 0)}. */
    052    public static final Point3D UNIT_X = new Point3D(1, 0, 0);
    053
    054    /** The point {@code (0, 1, 0)}. */
    055    public static final Point3D UNIT_Y = new Point3D(0, 1, 0);
    056
    057    /** The point {@code (0, 0, 1)}. */
    058    public static final Point3D UNIT_Z = new Point3D(0, 0, 1);
    059
    060    /** The x-coordinate. */
    061    public double x;
    062
    063    /** The y-coordinate. */
    064    public double y;
    065
    066    /** The z-coordinate. */
    067    public double z;
    068
    069    /**
    070     * Creates a new {@code Point3D} instance from spherical coordinates.
    071     *
    072     * @param theta  theta (in radians).
    073     * @param phi  phi (in radians).
    074     * @param rho  the distance from the origin.
    075     *
    076     * @return The point (never {@code null}).
    077     */
    078    public static Point3D createPoint3D(double theta, double phi, double rho) {
    079        double x = rho * Math.sin(phi) * Math.cos(theta);
    080        double y = rho * Math.sin(phi) * Math.sin(theta);
    081        double z = rho * Math.cos(phi);
    082        return new Point3D(x, y, z);
    083    }
    084
    085    /**
    086     * Creates a new point in 3D space.
    087     *
    088     * @param x  the x-coordinate.
    089     * @param y  the y-coordinate.
    090     * @param z  the z-coordinate.
    091     */
    092    public Point3D(double x, double y, double z) {
    093        this.x = x;
    094        this.y = y;
    095        this.z = z;
    096    }
    097
    098    /**
    099     * Returns the x-coordinate specified in the constructor.
    100     *
    101     * @return The x-coordinate.
    102     */
    103    public double getX() {
    104        return this.x;
    105    }
    106
    107    /**
    108     * Returns the y-coordinate specified in the constructor.
    109     *
    110     * @return The y-coordinate.
    111     */
    112    public double getY() {
    113        return this.y;
    114    }
    115
    116    /**
    117     * Returns the z-coordinate specified in the constructor.
    118     *
    119     * @return The z-coordinate.
    120     */
    121    public double getZ() {
    122        return this.z;
    123    }
    124
    125    /**
    126     * Returns theta (calculated from the cartesian coordinates).
    127     *
    128     * @return Theta.
    129     */
    130    public double getTheta() {
    131        return Math.atan2(y, x);
    132    }
    133
    134    /**
    135     * Returns phi (calculated from the cartesian coordinates).
    136     *
    137     * @return phi.
    138     */
    139    public double getPhi() {
    140        return Math.acos(z / getRho());
    141    }
    142
    143    /**
    144     * Returns rho (calculated from the cartesian coordinates).
    145     *
    146     * @return rho.
    147     */
    148    public double getRho() {
    149        return Math.sqrt(x * x + y * y + z * z);
    150    }
    151
    152    /**
    153     * Tests this instance for equality to an arbitrary object.
    154     *
    155     * @param obj  the object ({@code null} permitted).
    156     *
    157     * @return A boolean.
    158     */
    159    @Override
    160    public boolean equals(Object obj) {
    161        if (obj == this) {
    162            return true;
    163        }
    164        if (!(obj instanceof Point3D)) {
    165            return false;
    166        }
    167        Point3D that = (Point3D) obj;
    168        if (this.x != that.x) {
    169            return false;
    170        }
    171        if (this.y != that.y) {
    172            return false;
    173        }
    174        if (this.z != that.z) {
    175            return false;
    176        }
    177        return true;
    178    }
    179
    180    @Override
    181    public int hashCode() {
    182        int hash = 7;
    183        hash = 29 * hash + (int) (Double.doubleToLongBits(this.x)
    184                ^ (Double.doubleToLongBits(this.x) >>> 32));
    185        hash = 29 * hash + (int) (Double.doubleToLongBits(this.y)
    186                ^ (Double.doubleToLongBits(this.y) >>> 32));
    187        hash = 29 * hash + (int) (Double.doubleToLongBits(this.z)
    188                ^ (Double.doubleToLongBits(this.z) >>> 32));
    189        return hash;
    190    }
    191
    192    /**
    193     * Returns a string representation of this instance, primarily for
    194     * debugging purposes.
    195     *
    196     * @return A string (never {@code null}).
    197     */
    198    @Override
    199    public String toString() {
    200        return "[" + this.x + ", " + this.y + ", " + this.z + "]";
    201    }
    202
    203}