/* * 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. * * Point.java * * Created on 1. Februar 2003, 11:38 */ package geometry.planar; import java.math.BigInteger; /** * Abstract class describing functionality for Points in the plane. * * @author Alfons Wirtz */ public abstract class Point implements java.io.Serializable { /** * returns the translation of this point by p_vector */ public abstract Point translate_by(Vector p_vector ); /** * returns the difference vector of this point and p_other */ public abstract Vector difference_by(Point p_other); /** * approximates the coordinates of this point by float coordinates */ public abstract FloatPoint to_float(); /** * returns true, if this Point is a RationalPoint with denominator z = 0. */ public abstract boolean is_infinite(); /** * creates the smallest Box with integer coordinates containing this point. */ public abstract IntBox surrounding_box(); /** * creates the smallest Octagon with integer coordinates containing this point. */ public abstract IntOctagon surrounding_octagon(); /** * Returns true, if this point lies in the interiour or on the border * of p_box. */ public abstract boolean is_contained_in( IntBox p_box); public abstract Side side_of(Line p_line); /** * returns the nearest point to this point on p_line */ public abstract Point perpendicular_projection(Line p_line); /** * Standard implementation of the zero point . */ public static final IntPoint ZERO = new IntPoint(0, 0); /** * creates an IntPoint from p_x and p_y. If p_x or p_y is to big for * an IntPoint, a RationalPoint is created. */ public static Point get_instance(int p_x, int p_y) { IntPoint result = new IntPoint(p_x, p_y); if ( Math.abs(p_x) > Limits.CRIT_INT || Math.abs(p_x) > Limits.CRIT_INT ) { return new RationalPoint(result); } return result; } /** * factory method for creating a Point from 3 BigIntegers */ public static Point get_instance(BigInteger p_x, BigInteger p_y, BigInteger p_z) { if (p_z.signum() < 0) { // the dominator z of a RationalPoint is expected to be positive p_x = p_x.negate(); p_y = p_y.negate(); p_z = p_z.negate(); } if ((p_x.mod(p_z)).signum() == 0 && (p_x.mod(p_z)).signum() == 0) { // p_x and p_y can be divided by p_z p_x = p_x.divide(p_z); p_y = p_y.divide(p_z); p_z = BigInteger.ONE; } if (p_z.equals(BigInteger.ONE)) { if ( (p_x.abs()).compareTo(Limits.CRIT_INT_BIG) <= 0 && (p_y.abs()).compareTo(Limits.CRIT_INT_BIG) <= 0 ) { // the Point fits into an IntPoint return new IntPoint(p_x.intValue(), p_y.intValue()); } } return new RationalPoint(p_x, p_y, p_z); } /** * The function returns * Side.ON_THE_LEFT, if this Point is on the left of the line from p_1 to p_2; * Side.ON_THE_RIGHT, if this Point is on the right of the line from p_1 to p_2; * and Side.COLLINEAR, if this Point is collinear with p_1 and p_2. */ public Side side_of(Point p_1, Point p_2) { Vector v1 = difference_by(p_1); Vector v2 = p_2.difference_by(p_1); return v1.side_of(v2); } /** * Calculates the perpendicular direction froma this point * to p_line. Returns Direction.NULL, if this point lies on p_line. */ public Direction perpendicular_direction(Line p_line) { Side side = this.side_of(p_line); if (side == Side.COLLINEAR) { return Direction.NULL; } Direction result; if (side == Side.ON_THE_RIGHT) { result = p_line.direction().turn_45_degree(2); } else { result = p_line.direction().turn_45_degree(6); } return result; } /** * Returns 1, if this Point has a strict bigger x coordinate than p_other, * 0, if the x cooordinates are equal, and -1 otherwise. */ public abstract int compare_x(Point p_other); /** * Returns 1, if this Point has a strict bigger y coordinate than p_other, * 0, if the y cooordinates are equal, and -1 otherwise. */ public abstract int compare_y(Point p_other); /** * The function returns compare_x (p_other), if the result is not 0. * Otherwise it returns compare_y (p_other). */ public int compare_x_y(Point p_other) { int result = compare_x(p_other); if (result == 0) { result = compare_y(p_other); } return result; } /** * Turns this point by p_factor times 90 degree around p_pole. */ public Point turn_90_degree(int p_factor, Point p_pole) { Vector v = this.difference_by(p_pole); v = v.turn_90_degree(p_factor); return p_pole.translate_by(v); } /** * Mirrors this point at the vertical line through p_pole. */ public Point mirror_vertical(Point p_pole) { Vector v = this.difference_by(p_pole); v = v. mirror_at_y_axis(); return p_pole.translate_by(v); } /** * Mirrors this point at the horizontal line through p_pole. */ public Point mirror_horizontal(Point p_pole) { Vector v = this.difference_by(p_pole); v = v. mirror_at_x_axis(); return p_pole.translate_by(v); } // auxiliary functions needed because the virtual function mechanism // does not work in parameter position abstract Point translate_by(IntVector p_vector ); abstract Point translate_by(RationalVector p_vector ); abstract Vector difference_by(IntPoint p_other); abstract Vector difference_by(RationalPoint p_other); abstract int compare_x(IntPoint p_other); abstract int compare_x(RationalPoint p_other); abstract int compare_y(IntPoint p_other); abstract int compare_y(RationalPoint p_other); }