IsometryData.java |
1 /**************************************************************************** 2 * This demo file is part of yFiles for Java 2.14. 3 * Copyright (c) 2000-2017 by yWorks GmbH, Vor dem Kreuzberg 28, 4 * 72070 Tuebingen, Germany. All rights reserved. 5 * 6 * yFiles demo files exhibit yFiles for Java functionalities. Any redistribution 7 * of demo files in source code or binary form, with or without 8 * modification, is not permitted. 9 * 10 * Owners of a valid software license for a yFiles for Java version that this 11 * demo is shipped with are allowed to use the demo source code as basis 12 * for their own yFiles for Java powered applications. Use of such programs is 13 * governed by the rights and conditions as set out in the yFiles for Java 14 * license agreement. 15 * 16 * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 19 * NO EVENT SHALL yWorks BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 21 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 ***************************************************************************/ 28 package demo.view.isometry; 29 30 import java.awt.geom.Rectangle2D; 31 32 /** 33 * The class stores the height, width and depth of a solid figure. This data is used to get its bounds in the view space 34 * and the bounds of its base area used in the layout space. 35 */ 36 public class IsometryData implements Cloneable { 37 // Matrix to transform points from the layout space into the view space. 38 public static final double M_TO_VIEW_11 = Math.sqrt(3) * 0.5; 39 public static final double M_TO_VIEW_12 = M_TO_VIEW_11; 40 public static final double M_TO_VIEW_21 = -0.5; 41 public static final double M_TO_VIEW_22 = 0.5; 42 43 // Matrix to transform points from the view space into the layout space. 44 public static final double M_TO_LAYOUT_11 = 1 / Math.sqrt(3); 45 public static final double M_TO_LAYOUT_12 = -1; 46 public static final double M_TO_LAYOUT_21 = M_TO_LAYOUT_11; 47 public static final double M_TO_LAYOUT_22 = -M_TO_LAYOUT_12; 48 49 // Indices for the corners of the bounding box. 50 public static final int C0_X = 0; // lower left 51 public static final int C0_Y = 1; 52 public static final int C1_X = 2; // lower front 53 public static final int C1_Y = 3; 54 public static final int C2_X = 4; // lower right 55 public static final int C2_Y = 5; 56 public static final int C3_X = 6; // lower back 57 public static final int C3_Y = 7; 58 public static final int C4_X = 8; // upper left 59 public static final int C4_Y = 9; 60 public static final int C5_X = 10; // upper front 61 public static final int C5_Y = 11; 62 public static final int C6_X = 12; // upper right 63 public static final int C6_Y = 13; 64 public static final int C7_X = 14; // upper back 65 public static final int C7_Y = 15; 66 67 private double width; 68 private double height; 69 private double depth; 70 71 private boolean isHorizontal; 72 73 /** 74 * Creates an instance with the given dimensions. 75 */ 76 public IsometryData(final double width, final double depth, final double height, final boolean isHorizontal) { 77 this.width = width; 78 this.depth = depth; 79 this.height = height; 80 this.isHorizontal = isHorizontal; 81 } 82 83 /** 84 * Returns the width of the solid figure. 85 */ 86 public double getWidth() { 87 return width; 88 } 89 90 /** 91 * Sets the width of the solid figure. 92 */ 93 public void setWidth(final double width) { 94 this.width = width; 95 } 96 97 /** 98 * Returns the depth of the solid figure. 99 */ 100 public double getDepth() { 101 return depth; 102 } 103 104 /** 105 * Sets the depth of the solid figure. 106 */ 107 public void setDepth(final double depth) { 108 this.depth = depth; 109 } 110 111 /** 112 * Returns the height of the solid figure. 113 */ 114 public double getHeight() { 115 return height; 116 } 117 118 /** 119 * Sets the height of the solid figure. 120 */ 121 public void setHeight(final double height) { 122 this.height = height; 123 } 124 125 /** 126 * Determines whether or no the base of the solid figure is horizontal in layout space. 127 * This is important for labels that may be rotated during layout. 128 */ 129 public boolean isHorizontal() { 130 return isHorizontal; 131 } 132 133 /** 134 * Specifies whether or no the base of the solid figure is horizontal in layout space. 135 * This is important for labels that may be rotated during layout. 136 */ 137 public void setHorizontal(boolean horizontal) { 138 isHorizontal = horizontal; 139 } 140 141 /** 142 * Calculates the bounds of the solid figure in the view space. 143 * 144 * @param bounds the calculated bounds 145 */ 146 public void calculateViewBounds(final Rectangle2D bounds) { 147 final double[] corners = new double[16]; 148 calculateCorners(corners); 149 calculateViewBounds(corners, bounds); 150 } 151 152 /** 153 * Calculates the bounds of the solid figure in the view space. 154 * 155 * @param corners the corners of the projection of the bounds of solid figure into the view space 156 * @param bounds the calculated bounds 157 */ 158 public static void calculateViewBounds(final double[] corners, final Rectangle2D bounds) { 159 double minX = corners[C0_X]; 160 double minY = corners[C0_Y]; 161 double maxX = corners[C0_X]; 162 double maxY = corners[C0_Y]; 163 for (int i = 2; i < corners.length; i += 2) { 164 minX = Math.min(minX, corners[i]); 165 minY = Math.min(minY, corners[i + 1]); 166 maxX = Math.max(maxX, corners[i]); 167 maxY = Math.max(maxY, corners[i + 1]); 168 } 169 bounds.setFrame(minX, minY, maxX - minX, maxY - minY); 170 } 171 172 /** 173 * Calculates the corners of the projection of the bounds of solid figure into the view space. 174 * 175 * @param corners the calculated corners. 176 */ 177 public void calculateCorners(final double[] corners) { 178 corners[C0_X] = 0; 179 corners[C0_Y] = 0; 180 181 corners[C1_X] = toViewX(getWidth(), 0); 182 corners[C1_Y] = toViewY(getWidth(), 0); 183 184 corners[C2_X] = toViewX(getWidth(), getDepth()); 185 corners[C2_Y] = toViewY(getWidth(), getDepth()); 186 187 corners[C3_X] = toViewX(0, getDepth()); 188 corners[C3_Y] = toViewY(0, getDepth()); 189 190 for (int i = 0; i < 8; i += 2) { 191 corners[i + 8] = corners[i]; 192 corners[i + 9] = corners[i + 1] - getHeight(); 193 } 194 } 195 196 /** 197 * Transforms the given point from the layout space into the view space. 198 * 199 * @param layoutX x-coordinate in layout space 200 * @param layoutY y-coordinate in layout space 201 * @return x-coordinate in view space 202 */ 203 static double toViewX(final double layoutX, final double layoutY) { 204 return M_TO_VIEW_11 * layoutX + M_TO_VIEW_12 * layoutY; 205 } 206 207 /** 208 * Transforms the given point from the layout space into the view space. 209 * 210 * @param layoutX x-coordinate in layout space 211 * @param layoutY y-coordinate in layout space 212 * @return y-coordinate in view space 213 */ 214 static double toViewY(final double layoutX, final double layoutY) { 215 return M_TO_VIEW_21 * layoutX + M_TO_VIEW_22 * layoutY; 216 } 217 218 /** 219 * Transforms the given point from the view space into the layout space. 220 * 221 * @param viewX x-coordinate in view space 222 * @param viewY y-coordinate in view space 223 * @return x-coordinate in layout space 224 */ 225 static double toLayoutX(final double viewX, final double viewY) { 226 return M_TO_LAYOUT_11 * viewX + M_TO_LAYOUT_12 * viewY; 227 } 228 229 /** 230 * Transforms the given point from the view space into the layout space. 231 * 232 * @param viewX x-coordinate in view space 233 * @param viewY y-coordinate in view space 234 * @return y-coordinate in layout space 235 */ 236 static double toLayoutY(final double viewX, final double viewY) { 237 return M_TO_LAYOUT_21 * viewX + M_TO_LAYOUT_22 * viewY; 238 } 239 240 /** 241 * Translates the given corner to the given location, so that the upper left location of the bounds of the given 242 * corners is on the given location. 243 * 244 * @param x x-coordinate of the location where the corners should be moved to 245 * @param y y-coordinate of the location where the corners should be moved to 246 * @param corners corners to be moved 247 */ 248 public static void moveTo(final double x, final double y, final double[] corners) { 249 // Calculate the upper left location of the bounds of the given corners. 250 double minX = corners[C0_X]; 251 double minY = corners[C0_Y]; 252 for (int i = 2; i < corners.length; i += 2) { 253 minX = Math.min(minX, corners[i]); 254 minY = Math.min(minY, corners[i + 1]); 255 } 256 257 // Move the corners to the given location. 258 final double dx = x - minX; 259 final double dy = y - minY; 260 for (int i = 0; i < corners.length; i += 2) { 261 corners[i] += dx; 262 corners[i + 1] += dy; 263 } 264 } 265 266 public Object clone () throws CloneNotSupportedException { 267 return super.clone(); 268 } 269 } 270