/******************************************************************************* * Copyright (c) 2012 Rushan R. Gilmullin and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Rushan R. Gilmullin - initial API and implementation *******************************************************************************/ package org.semanticsoft.commons.geom; /** * @author rushan * */ public class Vector { private double x; private double y; public static Vector ortX = new Vector(1, 0); public static Vector ortY = new Vector(0, 1); public static Vector ZERO = new Vector(0, 0); public static Vector vectorX(double x) { return new Vector(x, 0); } public static Vector vectorY(double y) { return new Vector(0, y); } /** * shortcut for vectorX */ public static Vector vX(double x) { return vectorX(x); } /** * shortcut for vectorY */ public static Vector vY(double y) { return vectorY(y); } public Vector(double x, double y) { this.x = x; this.y = y; } public static Vector valueOf(double x, double y) { return new Vector(x, y); } public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public void setXY(double x, double y) { setX(x); setY(y); } public Vector getXProectionVector() { return Vector.vectorX(this.x); } public Vector getYProectionVector() { return Vector.vectorY(this.y); } public double getLength() { return Math.sqrt(getX()*getX() + getY()*getY()); } public Vector opposite() { return new Vector(-this.getX(), -this.getY()); } public Vector normalize() { double len = getLength(); return new Vector(getX()/len, getY()/len); } public boolean isNull() { return getX() == 0.0 && getY() == 0.0; } public Vector scale(double n) { return new Vector(this.getX()*n, this.getY()*n); } public Vector div(double n) { return scale(1/n); } public Vector scaleX(double n) { return new Vector(this.getX()*n, this.getY()); } public Vector scaleY(double n) { return new Vector(this.getX(), this.getY()*n); } public Vector plus(Vector v) { return new Vector(this.getX() + v.getX(), this.getY() + v.getY()); } public Vector minus(Vector v) { return new Vector(this.getX() - v.getX(), this.getY() - v.getY()); } public static double dotProduct(Vector v1, Vector v2) { return v1.getX()*v2.getX() + v1.getY()*v2.getY(); } public static double getAngle(Vector v1, Vector v2) { //косинус угла между векторами double cos = dotProduct(v1, v2)/(v1.getLength()*v2.getLength()); return Math.acos(cos); } public static Vector[] getOrtogonalOrts(Vector v) { double len = v.getLength(); Vector ort1 = new Vector(v.getY()/len, -v.getX()/len); Vector ort2 = new Vector(-v.getY()/len, v.getX()/len); return new Vector[] {ort1, ort2}; } @Override public String toString() { return String.format("(%s, %s)", this.getX(), this.getY()); } private static boolean sameSign(double val1, double val2) { if (val1 == 0 && val2 == 0) return true; if (val1 == 0 && val2 != 0 || val2 == 0 && val1 != 0) return false; return (val1 > 0 && val2 > 0) || (val1<0 && val2 <0); } public static boolean isEqual(Vector v1, Vector v2, double E) { return Math.abs(v1.getX() - v2.getX()) < E && Math.abs(v1.getY() - v2.getY()) < E; } public static boolean isEqual(Vector v1, Vector v2) { return v1.getX() == v2.getX() && v1.getY() == v2.getY(); } public static boolean isSameDirection(Vector v1, Vector v2, double E) { if (v1.isNull() || v2.isNull()) return false; double s = v2.getX() !=0? v1.getX()/v2.getX() : v1.getY()/v2.getY(); Vector test2 = v2.scale(s); if (isEqual(v1, test2, E)) { //Проверка, что вектора направлены в одну и ту же сторону return sameSign(v1.getX(), v2.getX()) && sameSign(v1.getY(), v2.getY()); } else return false; } public static boolean nonStrictCompare(Vector v1, Vector v2, double E) { if (Math.abs(v1.getX() - v2.getX()) < E) if (Math.abs(v1.getY() - v2.getY()) < E) return true; return false; } public static Vector maximum(Vector v1, Vector v2) { return v1.getLength()>v2.getLength() ? v1.getCopy() : v2.getCopy(); } public Vector getCopy() { return new Vector(getX(), getY()); } }