CCL Home Page
Up Directory CCL view.java
/**
 * view.java - camera angle, XYZ-to-screen coord translation, perspective
 * Copyright (c) 1997 Will Ware, all rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    or its derived works must display the following acknowledgement:
 * 	This product includes software developed by Will Ware.
 * 
 * This software is provided "as is" and any express or implied warranties,
 * including, but not limited to, the implied warranties of merchantability
 * or fitness for any particular purpose are disclaimed. In no event shall
 * Will Ware be liable for any direct, indirect, incidental, special,
 * exemplary, or consequential damages (including, but not limited to,
 * procurement of substitute goods or services; loss of use, data, or
 * profits; or business interruption) however caused and on any theory of
 * liability, whether in contract, strict liability, or tort (including
 * negligence or otherwise) arising in any way out of the use of this
 * software, even if advised of the possibility of such damage.
 */

import java.lang.Math;
import java.lang.Double;

public class view
{
  public static final String rcsid =
  "$Id: view.java,v 1.14 1997/08/12 03:52:22 wware Exp $";
  // rotation matrix
  private double[] m = { 1, 0, 0, 0, 1, 0, 0, 0, 1 };
  public double zoomFactor = 25; // pixels per angstrom
  public double perspDist = 400; // z distance for perspective, in pixels
  private double xCenter = 200;
  private double yCenter = 200;
  private double zCenter = 0;
  public void updateSize (int x, int y)
  {
    xCenter = x / 2;
    yCenter = y / 2;
    zCenter = 0;
  }
  public void pan (int dx, int dy)
  {
    xCenter += dx;
    yCenter += dy;
  }
  public void rotate (double xAngle, double yAngle)
  {
    double sa, ca, m0, m1, m2, m3, m4, m5;
    sa = Math.sin (xAngle);
    ca = Math.cos (xAngle);

    m0 = ca * m[0] + sa * m[6];
    m1 = ca * m[1] + sa * m[7];
    m2 = ca * m[2] + sa * m[8];
    m[6] = -sa * m[0] + ca * m[6];
    m[7] = -sa * m[1] + ca * m[7];
    m[8] = -sa * m[2] + ca * m[8];
    m[0] = m0;
    m[1] = m1;
    m[2] = m2;

    sa = Math.sin (yAngle);
    ca = Math.cos (yAngle);

    m3 = ca * m[3] + sa * m[6];
    m4 = ca * m[4] + sa * m[7];
    m5 = ca * m[5] + sa * m[8];
    m[6] = -sa * m[3] + ca * m[6];
    m[7] = -sa * m[4] + ca * m[7];
    m[8] = -sa * m[5] + ca * m[8];
    m[3] = m3;
    m[4] = m4;
    m[5] = m5;
  }
  public double perspectiveFactor (double z)
  {
    double denom = perspDist - z;
    if (denom < 5) denom = 5;
    return perspDist / denom;
  }
  public double perspectiveFactor (double[] scrPos)
  {
    return perspectiveFactor (scrPos[2] - zCenter);
  }
  public double[] xyzToScreen (double[] xyz)
  {
    double x, y, z, denom;
    double[] rvec = new double[3];
    // rotate
    x = m[0] * xyz[0] + m[1] * xyz[1] + m[2] * xyz[2];
    y = m[3] * xyz[0] + m[4] * xyz[1] + m[5] * xyz[2];
    z = m[6] * xyz[0] + m[7] * xyz[1] + m[8] * xyz[2];
    // zoom
    x = zoomFactor * x;
    y = zoomFactor * y;
    z = zoomFactor * z;
    // perspective
    double perspective = perspectiveFactor (z);
    x *= perspective;
    y *= perspective;
    // translation
    rvec[0] = x + xCenter;
    rvec[1] = y + yCenter;
    rvec[2] = z + zCenter;
    return rvec;
  }
  public double[] screenToXyz (double[] vec)
  {
    double x, y, z, denom;
    double[] rvec = new double[3];
    // undo translation
    x = vec[0] - xCenter;
    y = vec[1] - yCenter;
    z = vec[2] - zCenter;
    // undo persective
    double perspective = perspectiveFactor (z);
    x /= perspective;
    y /= perspective;
    // undo zoom
    x = x / zoomFactor;
    y = y / zoomFactor;
    z = z / zoomFactor;
    // undo rotation, multiply by the inverted matrix
    denom = 1.0 / (m[0] * (m[4] * m[8] - m[5] * m[7]) +
		   m[1] * (m[5] * m[6] - m[3] * m[8]) +
		   m[2] * (m[3] * m[7] - m[4] * m[6]));
    rvec[0] =
      ((m[4] * m[8] - m[5] * m[7]) * x +
       (m[2] * m[7] - m[1] * m[8]) * y +
       (m[1] * m[5] - m[2] * m[4]) * z) * denom;
    rvec[1] =
      ((m[5] * m[6] - m[3] * m[8]) * x +
       (m[0] * m[8] - m[2] * m[6]) * y +
       (m[2] * m[3] - m[0] * m[5]) * z) * denom;
    rvec[2] =
      ((m[3] * m[7] - m[4] * m[6]) * x +
       (m[1] * m[6] - m[0] * m[7]) * y +
       (m[0] * m[4] - m[1] * m[3]) * z) * denom;
    return rvec;
  }
}

Modified: Sat Jan 17 17:00:00 1998 GMT
Page accessed 4038 times since Sat May 22 21:57:54 1999 GMT