/* * Copyright (C) 2014 Alfons Wirtz * website www.freerouting.net * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License at <http://www.gnu.org/licenses/> * for more details. * * IntVector.java * * Created on 1. Februar 2003, 14:47 */ package geometry.planar; import datastructures.BigIntAux; import datastructures.Signum; /** * * Implementation of the interface Vector via a tuple of integers * * @author Alfons Wirtz */ public class IntVector extends Vector implements java.io.Serializable { /** * creates an IntVector from two integer coordinates */ public IntVector(int p_x, int p_y) { // range check ommitet for performance reasons x = p_x; y = p_y; } /** * returns true, if this IntVector is equal to p_ob */ public final boolean equals( Object p_ob ) { if ( this == p_ob ) { return true; } if ( p_ob == null ) { return false; } if ( getClass() != p_ob.getClass() ) { return false ; } IntVector other = (IntVector)p_ob ; return ( x == other.x && y == other.y ) ; } /** * returns true, if both coordinates of this vector are 0 */ public final boolean is_zero() { return x == 0 && y == 0; } /** * returns the Vector such that this plus this.minus() is zero */ public Vector negate() { return new IntVector(-x, -y); } public boolean is_orthogonal() { return ( x == 0 || y == 0 ) ; } public boolean is_diagonal() { return ( Math.abs(x) == Math.abs(y) ) ; } /** * Calculates the determinant of the matrix consisting of this * Vector and p_other. */ public final long determinant(IntVector p_other) { return (long)x * p_other.y - (long)y * p_other.x; } public Vector turn_90_degree(int p_factor) { int n = p_factor; while (n < 0) { n += 4; } while (n >= 4) { n -= 4; } int new_x ; int new_y ; switch (n) { case 0: // 0 degree new_x = x; new_y = y; break; case 1: // 90 degree new_x = -y ; new_y = x ; break; case 2: // 180 degree new_x = -x ; new_y = -y ; break; case 3: // 270 degree new_x = y ; new_y = -x ; break; default: new_x = 0 ; new_y = 0 ; } return new IntVector(new_x, new_y) ; } public Vector mirror_at_y_axis() { return new IntVector(-this.x, this.y); } public Vector mirror_at_x_axis() { return new IntVector(this.x, -this.y); } /** * adds p_other to this vector */ public final Vector add( Vector p_other) { return p_other.add(this); } final Vector add( IntVector p_other) { return new IntVector(x + p_other.x, y + p_other.y); } final Vector add( RationalVector p_other) { return p_other.add(this); } /** * returns the Point, which results from adding this vector to p_point */ final Point add_to(IntPoint p_point) { return new IntPoint(p_point.x + x, p_point.y + y); } final Point add_to(RationalPoint p_point) { return p_point.translate_by(this); } /** * Let L be the line from the Zero Vector to p_other. * The function returns * Side.ON_THE_LEFT, if this Vector is on the left of L * Side.ON_THE_RIGHT, if this Vector is on the right of L * and Side.COLLINEAR, if this Vector is collinear with L. */ public Side side_of(Vector p_other) { Side tmp = p_other.side_of(this); return tmp.negate(); } Side side_of(IntVector p_other) { double determinant = (double) p_other.x * y - (double) p_other.y * x; return Side.of(determinant); } Side side_of(RationalVector p_other) { Side tmp = p_other.side_of(this); return tmp.negate(); } /** * The function returns * Signum.POSITIVE, if the scalar product of this vector and p_other > 0, * Signum.NEGATIVE, if the scalar product Vector is < 0, * and Signum.ZERO, if the scalar product is equal 0. */ public Signum projection(Vector p_other) { return p_other.projection(this); } public double scalar_product(Vector p_other) { return p_other.scalar_product(this); } /** * converts this vector to a PointFloat. */ public FloatPoint to_float() { return new FloatPoint(x, y); } public Vector change_length_approx(double p_length) { FloatPoint new_point = this.to_float().change_size(p_length); return new_point.round().difference_by(Point.ZERO); } Direction to_normalized_direction() { int dx = x; int dy = y; int gcd = BigIntAux.binaryGcd(Math.abs(dx), Math.abs(dy)); if (gcd > 1) { dx /= gcd; dy /= gcd; } return new IntDirection(dx, dy); } /** * The function returns * Signum.POSITIVE, if the scalar product of this vector and p_other > 0, * Signum.NEGATIVE, if the scalar product Vector is < 0, * and Signum.ZERO, if the scalar product is equal 0. */ Signum projection(IntVector p_other) { double tmp = (double) x * p_other.x + (double) y * p_other.y; return Signum.of(tmp); } double scalar_product(IntVector p_other) { return (double) x * p_other.x + (double) y * p_other.y; } double scalar_product(RationalVector p_other) { return p_other.scalar_product(this); } Signum projection(RationalVector p_other) { return p_other.projection(this); } /** * the x coordinate of this vector */ public final int x; /** * the y coordinate of this vector */ public final int y; }