001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.util.imagery; 003 004import java.awt.geom.Point2D; 005 006/** 007 * A utility class for mapping a point onto a spherical coordinate system and vice versa 008 * @since 18246 009 */ 010public final class UVMapping { 011 private static final double TWO_PI = 2 * Math.PI; 012 private UVMapping() { 013 // Private constructor to avoid instantiation 014 } 015 016 /** 017 * Returns the point of the texture image that is mapped to the given point in 3D space (given as {@link Vector3D}) 018 * See <a href="https://en.wikipedia.org/wiki/UV_mapping">the Wikipedia article on UV mapping</a>. 019 * 020 * @param vector the vector to which the texture point is mapped 021 * @return a point on the texture image somewhere in the rectangle between (0, 0) and (1, 1) 022 */ 023 public static Point2D.Double getTextureCoordinate(final Vector3D vector) { 024 final double u = 0.5 + (Math.atan2(vector.getX(), vector.getZ()) / TWO_PI); 025 final double v = 0.5 + (Math.asin(vector.getY()) / Math.PI); 026 return new Point2D.Double(u, v); 027 } 028 029 /** 030 * For a given point of the texture (i.e. the image), return the point in 3D space where the point 031 * of the texture is mapped to (as {@link Vector3D}). 032 * 033 * @param u x-coordinate of the point on the texture (in the range between 0 and 1, from left to right) 034 * @param v y-coordinate of the point on the texture (in the range between 0 and 1, from top to bottom) 035 * @return the vector from the origin to where the point of the texture is mapped on the sphere 036 */ 037 public static Vector3D getVector(final double u, final double v) { 038 if (u > 1 || u < 0 || v > 1 || v < 0) { 039 throw new IllegalArgumentException("u and v must be between or equal to 0 and 1"); 040 } 041 final double vectorY = Math.cos(v * Math.PI); 042 final double vectorYSquared = Math.pow(vectorY, 2); 043 return new Vector3D(-Math.sin(TWO_PI * u) * Math.sqrt(1 - vectorYSquared), -vectorY, 044 -Math.cos(TWO_PI * u) * Math.sqrt(1 - vectorYSquared)); 045 } 046}