Package org.jmol.modelset

Source Code of org.jmol.modelset.BoxInfo

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-10-14 12:33:20 -0500 (Sun, 14 Oct 2007) $
* $Revision: 8408 $

*
* Copyright (C) 2003-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library 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
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package org.jmol.modelset;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.vecmath.Point3f;
import javax.vecmath.Point3i;
import javax.vecmath.Point4f;
import javax.vecmath.Vector3f;

import org.jmol.util.Measure;
import org.jmol.util.Point3fi;
import org.jmol.util.TriangleData;

public class BoxInfo {

  private final Point3f bbCorner0 = new Point3f(-10, -10, -10);
  private final Point3f bbCorner1 = new Point3f(10, 10, 10);
  private final Point3f bbCenter = new Point3f();
  private final Vector3f bbVector = new Vector3f(-1, -1, -1);
  private final Point3fi[] bbVertices = new Point3fi[8];

  {
    for (int i = 8; --i >= 0;)
      bbVertices[i] = new Point3fi();
  }

  public static char[] bbcageTickEdges = {
    'z', 0, 0, 'y',
    'x', 0, 0, 0,
      0, 0, 0, 0};
 
  public static char[] uccageTickEdges = {
    'z', 'y', 'x', 0,
     0, 0, 0, 0,
     0, 0, 0, 0};
 
  public final static byte edges[] = {
      0,1, 0,2, 0,4, 1,3,
      1,5, 2,3, 2,6, 3,7,
      4,5, 4,6, 5,7, 6,7
      };

  /**
   * returns a set of points defining the geometric object within the given
   * plane that spans the unit cell within the given margins
   * @param plane
   * @param scale
   * @param flags
   *          0 -- polygon int[]  1 -- edges only 2 -- triangles only 3 -- both
   * @return    a set of points
   *
   */
  public List intersectPlane(Point4f plane, float scale, int flags) {
    List v = new ArrayList();
    v.add(getCanonicalCopy(scale));
    return TriangleData.intersectPlane(plane, v, flags);
  }


  public Point3f[] getCanonicalCopy(float scale) {
    return getCanonicalCopy(bbVertices, scale);
  }

  public final static Point3f[] getCanonicalCopy(Point3f[] bbUcPoints, float scale) {
    Point3f[] pts = new Point3f[8];
    for (int i = 0; i < 8; i++)
      pts[toCanonical[i]] = new Point3f(bbUcPoints[i]);
    scaleBox(pts, scale);
    return pts;
  }
 
  public static void scaleBox(Point3f[] pts, float scale) {
    if (scale == 0 || scale == 1)
      return;
    Point3f center = new Point3f();
    Vector3f v = new Vector3f();
    for (int i = 0; i < 8; i++)
      center.add(pts[i]);
    center.scale(1/8f);
    for (int i = 0; i < 8; i++) {
      v.sub(pts[i], center);
      v.scale(scale);
      pts[i].add(center, v);
    }
  }

  public static Point4f[] getFacesFromCriticalPoints(Point3f[] points) {
    Point4f[] faces = new Point4f[6];
    Vector3f vNorm = new Vector3f();
    Vector3f vAB = new Vector3f();
    Vector3f vAC = new Vector3f();
    Point3f va = new Point3f();
    Point3f vb = new Point3f();
    Point3f vc = new Point3f();
   
    Point3f[] vertices = new Point3f[8];
    for (int i = 0; i < 8; i++) {
      vertices[i] = new Point3f(points[0]);
      if ((i & 1) == 1)
        vertices[i].add(points[1]);
      if ((i & 2) == 2)
        vertices[i].add(points[2]);
      if ((i & 4) == 4)
        vertices[i].add(points[3]);
    }

    for (int i = 0; i < 6; i++) {
      va.set(vertices[facePoints[i].x]);
      vb.set(vertices[facePoints[i].y]);
      vc.set(vertices[facePoints[i].z]);
      faces[i] = Measure
          .getPlaneThroughPoints(va, vb, vc, vNorm, vAB, vAC);
    }
    return faces;
  }

  /*                     Y
   *                      2 --------6--------- 6                           
   *                     /|                   /|         
   *                    / |                  / |          
   *                   /  |                 /  |          
   *                  5   1               11   |          
   *                 /    |               /    9          
   *                /     |              /     |        
   *               3 --------7--------- 7      |        
   *               |      |             |      |        
   *               |      0 ---------2--|----- 4    X       
   *               |     /              |     /         
   *               3    /              10    /          
   *               |   0                |   8           
   *               |  /                 |  /            
   *               | /                  | /              
   *               1 ---------4-------- 5                
   *              Z                                      
   */
 
  public final static Point3f[] unitCubePoints = {
    new Point3f(0, 0, 0), // 0
    new Point3f(0, 0, 1), // 1
    new Point3f(0, 1, 0), // 2
    new Point3f(0, 1, 1), // 3
    new Point3f(1, 0, 0), // 4
    new Point3f(1, 0, 1), // 5
    new Point3f(1, 1, 0), // 6
    new Point3f(1, 1, 1), // 7
  };

  private static Point3i[] facePoints = {
    new Point3i(4, 0, 6),
    new Point3i(4, 6, 5),
    new Point3i(5, 7, 1),
    new Point3i(1, 3, 0),
    new Point3i(6, 2, 7),
    new Point3i(1, 0, 5),
  };

  public final static int[] toCanonical = new int[] {0, 3, 4, 7, 1, 2, 5, 6};

  protected final static Point3i[] cubeVertexOffsets = {
    new Point3i(0, 0, 0), //0 pt
    new Point3i(1, 0, 0), //1 pt + yz
    new Point3i(1, 0, 1), //2 pt + yz + 1
    new Point3i(0, 0, 1), //3 pt + 1
    new Point3i(0, 1, 0), //4 pt + z
    new Point3i(1, 1, 0), //5 pt + yz + z
    new Point3i(1, 1, 1), //6 pt + yz + z + 1
    new Point3i(0, 1, 1//7 pt + z + 1
  };

  public final static Point3f[] getCriticalPoints(Point3f[] bbVertices, Point3f offset) {
    Point3f center = new Point3f(bbVertices[0]);
    Point3f a = new Point3f(bbVertices[1]);
    Point3f b = new Point3f(bbVertices[2]);
    Point3f c = new Point3f(bbVertices[4]);
    a.sub(center);
    b.sub(center);
    c.sub(center);
    if (offset != null)
      center.add(offset);
    return new Point3f[] { center, a, b, c };
  }
 
  private final static Point3f[] unitBboxPoints = new Point3f[8];
  {
    for (int i = 0; i < 8; i++) {
      unitBboxPoints[i] = new Point3f(-1, -1, -1);
      unitBboxPoints[i].scaleAdd(2, unitCubePoints[i], unitBboxPoints[i]);
    }
  }

  public Point3f getBoundBoxCenter() {
    return bbCenter;
  }

  public Vector3f getBoundBoxCornerVector() {
    return bbVector;
  }

  public Point3f[] getBoundBoxPoints() {
    return new Point3f[] {bbCenter, new Point3f(bbVector), bbCorner0, bbCorner1};
  }

  public Point3fi[] getBboxVertices() {
    return bbVertices;
  }
 
  Hashtable getBoundBoxInfo() {
    Hashtable info = new Hashtable();
    info.put("center", new Point3f(bbCenter));
    info.put("vector", new Vector3f(bbVector));
    info.put("corner0", new Point3f(bbCorner0));
    info.put("corner1", new Point3f(bbCorner1));
    return info;
  }

  void setBoundBox(Point3f pt1, Point3f pt2, boolean byCorner, float scale) {
    if (pt1 != null) {
      if (scale == 0)
        return;
      if (byCorner) {
        if (pt1.distance(pt2) == 0)
          return;
        bbCorner0.set(Math.min(pt1.x, pt2.x), Math.min(pt1.y, pt2.y), Math.min(
            pt1.z, pt2.z));
        bbCorner1.set(Math.max(pt1.x, pt2.x), Math.max(pt1.y, pt2.y), Math.max(
            pt1.z, pt2.z));
      } else { // center and vector
        if (pt2.x == 0 || pt2.y == 0 && pt2.z == 0)
          return;
        bbCorner0.set(pt1.x - pt2.x, pt1.y - pt2.y, pt1.z - pt2.z);
        bbCorner1.set(pt1.x + pt2.x, pt1.y + pt2.y, pt1.z + pt2.z);
      }
    }
    setBbcage(scale);
  }

  void reset() {
    bbCorner0.set(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
    bbCorner1.set(-Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
  }
 
  void addBoundBoxPoint(Point3f pt) {
    float t = pt.x;
    if (t < bbCorner0.x)
      bbCorner0.x = t;
    if (t > bbCorner1.x)
      bbCorner1.x = t;
    t = pt.y;
    if (t < bbCorner0.y)
      bbCorner0.y = t;
    if (t > bbCorner1.y)
      bbCorner1.y = t;
    t = pt.z;
    if (t < bbCorner0.z)
      bbCorner0.z = t;
    if (t > bbCorner1.z)
      bbCorner1.z = t;
  }

  void setBbcage(float scale) {
    bbCenter.add(bbCorner0, bbCorner1);
    bbCenter.scale(0.5f);
    bbVector.sub(bbCorner1, bbCenter);
    if (scale > 0) {
      bbVector.scale(scale);
    } else {
      bbVector.x -= scale / 2;
      bbVector.y -= scale / 2;
      bbVector.z -= scale / 2;
    }
    for (int i = 8; --i >= 0;) {
      Point3f pt = bbVertices[i];
      pt.set(unitBboxPoints[i]);
      pt.x *= bbVector.x;
      pt.y *= bbVector.y;
      pt.z *= bbVector.z;
      pt.add(bbCenter);
    }
    bbCorner0.set(bbVertices[0]);
    bbCorner1.set(bbVertices[7]);
  }
 
  boolean isWithin(Point3f pt) {
   return (pt.x >= bbCorner0.x && pt.x <= bbCorner1.x
       && pt.y >= bbCorner0.y && pt.y <= bbCorner1.y
       && pt.z >= bbCorner0.z && pt.z <= bbCorner1.z);
  }



}
TOP

Related Classes of org.jmol.modelset.BoxInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.