All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.database.geometry.EPoint Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: EPoint.java
 * Written by: Dmitry Nadezhin, Sun Microsystems.
 *
 * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
 *
 * Electric(tm) 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.
 *
 * Electric(tm) 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Electric(tm); see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, Mass 02111-1307, USA.
 */
package com.sun.electric.database.geometry;

import java.awt.geom.Point2D;
import java.io.Serializable;

import com.sun.electric.util.math.AbstractFixpPoint;
import com.sun.electric.util.math.DBMath;
import com.sun.electric.util.math.ECoord;
import com.sun.electric.util.math.FixpCoord;
import com.sun.electric.util.math.GenMath;

/**
 * The EPoint immutable class defines a point representing
 * a location in (x, y) coordinate space. This class extends abstract
 * class Point2D. This class is used in Electric database.
 * Coordiates are snapped to grid according to DBMath.round method.
 */
public class EPoint extends AbstractFixpPoint implements Serializable {

    /** EPoint with both zero coordinates. */
    public static final EPoint ORIGIN = new EPoint(0, 0);
    /**
     * The X coordinate of this EPoint in grid unuts.
     */
    private final int gridX;
    /**
     * The Y coordinate of this EPoint in grid units.
     */
    private final int gridY;
//    /**
//     * The X coordinate of this EPoint in lambda unuts.
//     */
//    private final double lambdaX;
//    /**
//     * The Y coordinate of this EPoint in lambda units.
//     */
//    private final double lambdaY;
    /**
     * Statistics: count of created EPoints
     */
    private static int createdEPoints;

    /**
     * Constructs and initializes a EPoint with the
     * specified coordinates in lambda units snapped to the grid.
     * @param lambdaX the x-coordinate to which to set the newly
     * constructed EPoint in lambda units.
     * @param lambdaY the y-coordinate to which to set the newly
     * constructed EPoint in lambda units.
     */
    public EPoint(double lambdaX, double lambdaY) {
        this(DBMath.lambdaToGrid(lambdaX), DBMath.lambdaToGrid(lambdaY));
    }

    /**
     * Constructs and initializes a EPoint with the
     * specified coordinates in grid units.
     * @param gridX the x-coordinate to which to set the newly
     * constructed EPoint in grid units.
     * @param gridX the y-coordinate to which to set the newly
     * constructed EPoint in grid units.
     */
    private EPoint(long gridX, long gridY) {
        this.gridX = (int) gridX;
        this.gridY = (int) gridY;
        if (this.gridX != gridX || this.gridY != gridY) {
            throw new IllegalArgumentException("Too large coordinates (" + gridX + "," + gridY + ")");
        }
//        lambdaX = DBMath.gridToLambda(gridX);
//        lambdaY = DBMath.gridToLambda(gridY);
        createdEPoints++;
    }

    @Override
    public void setFixpLocation(long fixpX, long fixpY) {
        throw new UnsupportedOperationException();
    }

    @Override
    protected AbstractFixpPoint create(long fixpX, long fixpY) {
        return fromFixp(fixpX, fixpY);
    }
    
    /**
     * Returns EPoint with specified grid coordinates.
     * @param lambdaX the x-coordinate in lambda units.
     * @param lambdaY the y-coordinate in lambda units.
     * @return EPoint with specified grid coordinates.
     */
    public static EPoint fromLambda(double lambdaX, double lambdaY) {
        return lambdaX == 0 && lambdaY == 0 ? ORIGIN : fromGrid(DBMath.lambdaToGrid(lambdaX), DBMath.lambdaToGrid(lambdaY));
    }

    /**
     * Returns EPoint with specified fixed-point coordinates.
     * @param fixpX the x-coordinate in fixed-point units.
     * @param fixpY the y-coordinate in fixed-point units.
     * @return EPoint with specified grid coordinates.
     */
    public static EPoint fromFixp(long fixpX, long fixpY) {
        long gridX = GenMath.roundToMultiple(fixpX, 1L << FixpCoord.FRACTION_BITS) >> FixpCoord.FRACTION_BITS;
        long gridY = GenMath.roundToMultiple(fixpY, 1L << FixpCoord.FRACTION_BITS) >> FixpCoord.FRACTION_BITS;
        return fromGrid(gridX, gridY);
    }

    /**
     * Returns EPoint with specified grid coordinates.
     * @param gridX the x-coordinate in grid units.
     * @param gridY the y-coordinate in grid units.
     * @return EPoint with specified grid coordinates.
     */
    public static EPoint fromGrid(long gridX, long gridY) {
        int intX = (int)gridX;
        int intY = (int)gridY;
        return gridX == 0 && gridY == 0 ? ORIGIN : intX == gridX && intY == gridY ? new EPoint(gridX, gridY) : new EPointLong(intX, intY);
    }

    /**
     * Returns EPoint from specified Point2D
     * snapped to the grid.
     * @param p specified Point2D
     * @return Snapped EPoint
     */
    public static EPoint snap(Point2D p) {
        return (p instanceof EPoint) ? (EPoint) p : fromLambda(p.getX(), p.getY());
    }

    /**
     * Returns the X coordinate of this EPoint
     * in lambda units in double precision.
     * @return the X coordinate of this EPoint.
     */
    @Override
    public double getX() {
        return DBMath.gridToLambda(getGridX());
    }

    /**
     * Returns the Y coordinate of this EPoint
     * in lambda unuts in double precision.
     * @return the Y coordinate of this EPoint.
     */
    @Override
    public double getY() {
        return DBMath.gridToLambda(getGridY());
    }

    /**
     * Returns the X coordinate of this EPoint as ECoord object.
     * @return the X coordinate of this EPoint.
     */
    public ECoord getCoordX() {
        return ECoord.fromGrid(getGridX());
    }

    /**
     * Returns the Y coordinate of this EPoint as ECoord object.
     * @return the Y coordinate of this EPoint.
     */
    public ECoord getCoordY() {
        return ECoord.fromGrid(getGridX());
    }

    /**
     * Returns the X coordinate of this EPoint
     * in lambda units in double precision.
     * @return the X coordinate of this EPoint.
     */
    public double getLambdaX() {
        return getX();
    }

    /**
     * Returns the Y coordinate of this EPoint
     * in lambda units in double precision.
     * @return the Y coordinate of this EPoint.
     */
    public double getLambdaY() {
        return getY();
    }

    /**
     * Returns the X coordinate of this EPoint
     * in fixed-point units in long precision.
     * @return the X coordinate of this EPoint.
     */
    @Override
    public long getFixpX() {
        return ((long) gridX) << FixpCoord.FRACTION_BITS;
    }

    /**
     * Returns the Y coordinate of this EPoint
     * in fixed-point units in long precision.
     * @return the Y coordinate of this EPoint.
     */
    @Override
    public long getFixpY() {
        return ((long) gridY) << FixpCoord.FRACTION_BITS;
    }

    /**
     * Returns the X coordinate of this EPoint
     * in grid units in long precision.
     * @return the X coordinate of this EPoint.
     */
    public long getGridX() {
        return gridX;
    }

    /**
     * Returns the Y coordinate of this EPoint
     * in grid units in long precision.
     * @return the Y coordinate of this EPoint.
     */
    public long getGridY() {
        return gridY;
    }

    /**
     * This method overrides Point2D.setLocation method.
     * It throws UnsupportedOperationException.
     * @param x the x-coordinate to which to set this EPoint
     * @param y the y-coordinate to which to set this EPoint
     * @throws UnsupportedOperationException
     */
    @Override
    public void setLocation(double x, double y) {
        throw new UnsupportedOperationException();
    }

    /**
     * Creates mutable Point2D.Double from the EPoint in lambda units.
     * @return mutable Point2D in lambda units
     */
    public Point2D.Double lambdaMutable() {
        return new Point2D.Double(getLambdaX(), getLambdaY());
    }

    /**
     * Creates mutable Point2D.Double from the EPoint in grid units.
     * @return mutable Point2D in grid units
     */
    public Point2D.Double gridMutable() {
        return new Point2D.Double(getGridX(), getGridY());
    }

    /**
     * Returns the distance from this EPoint to a
     * specified EPoint in lambda units.
     * @param pt the specified EPoint
     * @return the distance between this EPoint and
     * the specified Point in lambdaUnits.
     */
    public double lambdaDistance(EPoint pt) {
        return DBMath.gridToLambda(gridDistance(pt));
    }

    /**
     * Returns the distance from this EPoint to a
     * specified EPoint in grid units.
     * @param pt the specified EPoint
     * @return the distance between this EPoint and
     * the specified Point in gridUnits.
     */
    public double gridDistance(EPoint pt) {
        long PX = pt.getGridX() - this.getGridX();
        long PY = pt.getGridY() - this.getGridY();
        return PY == 0 ? Math.abs(PX) : PX == 0 ? Math.abs(PY) : Math.hypot(PX, PY);
    }

    /**
     * Returns the distance from this EPoint to a
     * specified EPoint in fixed-point units.
     * @param pt the specified EPoint
     * @return the distance between this EPoint and
     * the specified Point in gridUnits.
     */
    public double fixpDistance(EPoint pt) {
        return gridDistance(pt) * FixpCoord.FIXP_SCALE;
    }

    /**
     * Returns true if this EPoint is equal to the other EPoint.
     * This method returns the same result as general equals,
     * but it could be a little faster, because no virtual method dispatching is required.
     * @return true if this EPoint is equal to the other EPoint.
     * @see java.awt.geom.Point2D#equals
     */
    public boolean equals(EPoint that) {
        return this.getGridX() == that.getGridX() && this.getGridY() == that.getGridY();
    }

//    /**
//     * Returns a String that represents the value
//     * of this EPoint.
//     * @return a string representation of this EPoint.
//     */
//    @Override
//    public String toString() {
//        return "EPoint[" + getX() + ", " + getY() + "]";
//    }

    /**
     * Prints statistics about EPoint objects.
     */
    public static void printStatistics() {
        System.out.println(createdEPoints + " EPoints created");
    }
    
    private static class EPointLong extends EPoint {
        private final long gridX;
        private final long gridY;
        
        private EPointLong(long gridX, long gridY) {
            super(Integer.MIN_VALUE, Integer.MIN_VALUE);
            this.gridX = gridX;
            this.gridY = gridY;
        }
        /**
         * Returns the X coordinate of this EPoint
         * in fixed-point units in long precision.
         * @return the X coordinate of this EPoint.
         */
        @Override
        public long getFixpX() {
            return gridX << FixpCoord.FRACTION_BITS;
        }

        /**
         * Returns the Y coordinate of this EPoint
         * in fixed-point units in long precision.
         * @return the Y coordinate of this EPoint.
         */
        @Override
        public long getFixpY() {
            return gridY << FixpCoord.FRACTION_BITS;
        }

        /**
         * Returns the X coordinate of this EPoint
         * in grid units in long precision.
         * @return the X coordinate of this EPoint.
         */
        @Override
        public long getGridX() {
            return gridX;
        }

        /**
         * Returns the Y coordinate of this EPoint
         * in grid units in long precision.
         * @return the Y coordinate of this EPoint.
         */
        @Override
        public long getGridY() {
            return gridY;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy