📄 orientation.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Orientation.java * * Copyright (c) 2005 Sun Microsystems and Static Free Software * * 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.AffineTransform;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;import java.util.HashMap;import java.io.Serializable;/** * Class <code>Orientation</code> represents 2D affine transform which is composition of rotation and possible flip. * The C code used an angle (in tenth-degrees) and a "transpose" factor * which would flip the object along the major diagonal after rotation. * The Java code uses the same angle (in tenth-degrees) but has two mirror * options: Mirror X and Mirror Y. */public class Orientation implements Serializable { // The internal representation of orientation is the 2D transformation matrix: // [ sX*cos(angle) -sX*sin(angle) ] = [ sX 0 ] * [ cos(angle) -sin(angle) ] // [ sY*sin(angle) sY*cos(angle) ] [ 0 sY ] [ sin(angle) cos(angle) ] // -------------------------------------- // sX = jMirrorX ? -1 : 1 // sY = jMirrorY ? -1 : 1 // 0 <= jAngle < 3600 is in tenth-degrees private final short jAngle;// private final short jOctant; private final boolean jMirrorX; private final boolean jMirrorY; private final String jString; private final short cAngle; private final boolean cTranspose; private final Orientation inverse; private final AffineTransform trans; private static final HashMap<Integer,Orientation> map = new HashMap<Integer,Orientation>(); private static final Orientation[] map45; private static final int OCTANT = 0x07; private static final int XMIRROR45 = 0x08; private static final int YMIRROR45 = 0x10; static { Orientation[] m = new Orientation[32]; for (int i = 0; i < m.length; i++) { int octant = i & OCTANT; boolean jMirrorX = (i&XMIRROR45) != 0; boolean jMirrorY = (i&YMIRROR45) != 0; Orientation orient = new Orientation(octant*450, jMirrorX, jMirrorY, null); m[i] = orient; if (orient.inverse == orient) continue; m[i + 8 - octant*2] = orient.inverse; } map45 = m; } /** Identical Orientation */ public static final Orientation IDENT = fromJava(0, false, false); public static final Orientation R = fromJava(900, false, false); public static final Orientation RR = fromJava(1800, false, false); public static final Orientation RRR = fromJava(2700, false, false); public static final Orientation X = fromJava(0, true, false); public static final Orientation XR = fromJava(900, true, false); public static final Orientation XRR = fromJava(1800, true, false); public static final Orientation XRRR = fromJava(2700, true, false); public static final Orientation Y = fromJava(0, false, true); public static final Orientation YR = fromJava(900, false, true); public static final Orientation YRR = fromJava(1800, false, true); public static final Orientation YRRR = fromJava(2700, false, true); public static final Orientation XY = fromJava(0, true, true); public static final Orientation XYR = fromJava(900, true, true); public static final Orientation XYRR = fromJava(1800, true, true); public static final Orientation XYRRR = fromJava(2700, true, true); // flags for manhattan orientations private static final byte MNONE = -1; private static final byte MIDENT = 0; private static final byte MR = 1; private static final byte MRR = 2; private static final byte MRRR = 3; private static final byte MY = 4; private static final byte MYR = 5; private static final byte MYRR = 6; private static final byte MYRRR = 7; private final byte manh; private Orientation(int jAngle, boolean jMirrorX, boolean jMirrorY, Orientation inverse) { assert 0 <= jAngle && jAngle < 3600; // store Java information this.jAngle = (short)jAngle;// this.jOctant = (short)(jAngle % 450 == 0 ? jAngle/450 : -1); this.jMirrorX = jMirrorX; this.jMirrorY = jMirrorY; // compute C information int cAngle = jAngle; boolean cTranspose = false; if (jMirrorX) { if (jMirrorY) { cAngle = (cAngle + 1800) % 3600; } else { cAngle = (cAngle + 900) % 3600; cTranspose = true; } } else if (jMirrorY) { cAngle = (cAngle + 2700) % 3600; cTranspose = true; } this.cAngle = (short)cAngle; this.cTranspose = cTranspose; // check for manhattan orientation switch (cAngle) { case 0: manh = cTranspose ? MYR : MIDENT; break; case 900: manh = cTranspose ? MYRR : MR; break; case 1800: manh = cTranspose ? MYRRR : MRR; break; case 2700: manh = cTranspose ? MY : MRRR; break; default: manh = MNONE; } if (inverse == null) { if (cTranspose || jAngle == 0 || jAngle == 1800) inverse = this; else inverse = new Orientation(3600 - jAngle, jMirrorX, jMirrorY, this); } this.inverse = inverse; double[] matrix = new double[4]; int sect = jAngle / 450; assert 0 <= sect && sect < 8; int ang = jAngle % 450; if (sect % 2 != 0) ang = 450 - ang; assert 0 <= ang && ang <= 450; double cos0, sin0; if (ang == 0) { cos0 = 1; sin0 = 0; } else if (ang == 450) { cos0 = sin0 = Math.sqrt(0.5); } else { double alpha = ang * Math.PI / 1800.0; cos0 = Math.cos(alpha); sin0 = Math.sin(alpha); } double cos = 0, sin = 0; switch (sect) { case 0: cos = cos0; sin = sin0; break; case 1: cos = sin0; sin = cos0; break; case 2: cos = -sin0; sin = cos0; break; case 3: cos = -cos0; sin = sin0; break; case 4: cos = -cos0; sin = -sin0; break; case 5: cos = -sin0; sin = -cos0; break; case 6: cos = sin0; sin = -cos0; break; case 7: cos = cos0; sin = -sin0; break; default: assert false; } matrix[0] = cos * (jMirrorX ? -1 : 1); matrix[1] = sin * (jMirrorY ? -1 : 1); matrix[2] = sin * (jMirrorX ? 1 : -1); matrix[3] = cos * (jMirrorY ? -1 : 1); if (jAngle % 900 == 0) { for (int i = 0; i < matrix.length; i++) matrix[i] = Math.round(matrix[i]); } this.trans = new AffineTransform(matrix); // compute Jelib String String s = ""; if (jMirrorX) s += 'X'; if (jMirrorY) s += 'Y'; while (jAngle >= 900) { s += 'R'; jAngle -= 900; } if (jAngle != 0) s = s + jAngle; this.jString = s; } private Object readResolve() { return fromJava(jAngle, jMirrorX, jMirrorY); } /** * Get Orientation by the new Java style parameters. * @param jAngle the angle of rotation (in tenth-degrees) * @param jMirrorX if true, object is flipped over the vertical (mirror in X). * @param jMirrorY if true, object is flipped over the horizontal (mirror in Y). * @return the Orientation. */ public static Orientation fromJava(int jAngle, boolean jMirrorX, boolean jMirrorY) { if (jAngle % 450 == 0) { int index = jAngle/450 & OCTANT; if (jMirrorX) index |= XMIRROR45;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -