1 /* 2 * Copyright 2005 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.common.geometry; 17 18 /** 19 * R2Vector represents a vector in the two-dimensional space. It defines the 20 * basic geometrical operations for 2D vectors, e.g. cross product, addition, 21 * norm, comparison etc. 22 * 23 */ 24 public final strictfp class R2Vector { 25 private final double x; 26 private final double y; 27 R2Vector()28 public R2Vector() { 29 this(0, 0); 30 } 31 R2Vector(double x, double y)32 public R2Vector(double x, double y) { 33 this.x = x; 34 this.y = y; 35 } 36 R2Vector(double[] coord)37 public R2Vector(double[] coord) { 38 if (coord.length != 2) { 39 throw new IllegalStateException("Points must have exactly 2 coordinates"); 40 } 41 x = coord[0]; 42 y = coord[1]; 43 } 44 x()45 public double x() { 46 return x; 47 } 48 y()49 public double y() { 50 return y; 51 } 52 get(int index)53 public double get(int index) { 54 if (index > 1) { 55 throw new ArrayIndexOutOfBoundsException(index); 56 } 57 return index == 0 ? this.x : this.y; 58 } 59 add(final R2Vector p1, final R2Vector p2)60 public static R2Vector add(final R2Vector p1, final R2Vector p2) { 61 return new R2Vector(p1.x + p2.x, p1.y + p2.y); 62 } 63 mul(final R2Vector p, double m)64 public static R2Vector mul(final R2Vector p, double m) { 65 return new R2Vector(m * p.x, m * p.y); 66 } 67 norm2()68 public double norm2() { 69 return (x * x) + (y * y); 70 } 71 dotProd(final R2Vector p1, final R2Vector p2)72 public static double dotProd(final R2Vector p1, final R2Vector p2) { 73 return (p1.x * p2.x) + (p1.y * p2.y); 74 } 75 dotProd(R2Vector that)76 public double dotProd(R2Vector that) { 77 return dotProd(this, that); 78 } 79 crossProd(final R2Vector that)80 public double crossProd(final R2Vector that) { 81 return this.x * that.y - this.y * that.x; 82 } 83 lessThan(R2Vector vb)84 public boolean lessThan(R2Vector vb) { 85 if (x < vb.x) { 86 return true; 87 } 88 if (vb.x < x) { 89 return false; 90 } 91 if (y < vb.y) { 92 return true; 93 } 94 return false; 95 } 96 97 @Override equals(Object that)98 public boolean equals(Object that) { 99 if (!(that instanceof R2Vector)) { 100 return false; 101 } 102 R2Vector thatPoint = (R2Vector) that; 103 return this.x == thatPoint.x && this.y == thatPoint.y; 104 } 105 106 /** 107 * Calcualates hashcode based on stored coordinates. Since we want +0.0 and 108 * -0.0 to be treated the same, we ignore the sign of the coordinates. 109 */ 110 @Override hashCode()111 public int hashCode() { 112 long value = 17; 113 value += 37 * value + Double.doubleToLongBits(Math.abs(x)); 114 value += 37 * value + Double.doubleToLongBits(Math.abs(y)); 115 return (int) (value ^ (value >>> 32)); 116 } 117 118 @Override toString()119 public String toString() { 120 return "(" + x + ", " + y + ")"; 121 } 122 } 123