
org.biojava.nbio.structure.symmetry.geometry.Prism Maven / Gradle / Ivy
/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
/**
*
*/
package org.biojava.nbio.structure.symmetry.geometry;
import javax.vecmath.Matrix3d;
import javax.vecmath.Point3d;
import java.util.ArrayList;
import java.util.List;
/**
* @author Peter
*
*/
public class Prism implements Polyhedron {
private int n = 3;
private double circumscribedRadius = 1.0;
private double height = 1.0;
public Prism(int n) {
this.n = n;
}
/**
* @return the height
*/
public double getHeight() {
return height;
}
/**
* @param height the height to set
*/
public void setHeight(double height) {
this.height = height;
}
/**
* Returns the radius of a circumscribed sphere, that goes
* through all vertices
* @return the cirumscribedRadius
*/
@Override
public double getCirumscribedRadius() {
return circumscribedRadius;
}
/**
* Set the radius of a circumscribed sphere, that goes
* through all vertices
* @param cirumscribedRadius the cirumscribedRadius to set
*/
public void setCirumscribedRadius(double cirumscribedRadius) {
this.circumscribedRadius = cirumscribedRadius;
}
/**
* Returns the radius of an inscribed sphere, that is tangent to each
* of the icosahedron's faces
* @return the inscribedRadius
*/
public double getInscribedRadius() {
double side = getSideLengthFromCircumscribedRadius(circumscribedRadius, n);
return getInscribedRadiusFromSideLength(side, n);
}
/**
* Sets the radius of an inscribed sphere, that is tangent to each
* of the icosahedron's faces
* @param inscribedRadius the inscribedRadius to set
*/
public void setInscribedRadius(double radius) {
double side = getSideLengthFromInscribedRadius(radius, n);
this.circumscribedRadius = getCircumscribedRadiusFromSideLength(side, n);
}
/**
* Returns the vertices of an n-fold polygon of given radius and center
* @return
*/
@Override
public Point3d[] getVertices() {
Point3d[] polygon = new Point3d[2*n];
Matrix3d m = new Matrix3d();
Point3d center = new Point3d(0, 0, height/2);
for (int i = 0; i < n; i++) {
polygon[i] = new Point3d(0, circumscribedRadius, 0);
m.rotZ(i*2*Math.PI/n);
m.transform(polygon[i]);
polygon[n+i] = new Point3d(polygon[i]);
polygon[i].sub(center);
polygon[n+i].add(center);
}
return polygon;
};
@Override
public List getLineLoops() {
List list = new ArrayList();
int[] l1 = new int[2*n+2];
for (int i = 0; i < n; i++) {
l1[i] = i;
}
l1[n] = 0;
for (int i = 0; i < n; i++) {
l1[n+i+1] = n+i;
}
l1[2*n+1] = l1[n+1];
list.add(l1);
for (int i = 1; i < n; i++) {
int[] l2 = new int[2];
l2[0] = i;
l2[1] = n+i;
list.add(l2);
}
return list;
}
/**
* Returns the vertices of an n-fold polygon of given radius and center
* @return
*/
public static Point3d[] getPolygonVertices(int n, double radius, Point3d center) {
Point3d[] polygon = new Point3d[n];
Matrix3d m = new Matrix3d();
for (int i = 0; i < n; i++) {
polygon[i] = new Point3d(0, radius, 0);
m.rotZ(i*2*Math.PI/n);
m.transform(polygon[i]);
polygon[i].add(center);
}
return polygon;
}
@Override
public int getViewCount() {
return 4;
}
@Override
public String getViewName(int index) {
String name;
switch (index) {
case 0: name = "Front C" + n + " axis";
break;
case 1: name = "Side edge-centered";
break;
case 2: name = "Side face-centered";
break;
case 3: name = "Back C" + n + " axis";
break;
default: throw new IllegalArgumentException("getViewMatrix: index out of range:" + index);
}
return name;
}
@Override
public Matrix3d getViewMatrix(int index) {
Matrix3d m = new Matrix3d();
switch (index) {
case 0:
m.setIdentity(); // front
break;
case 1:
m.rotX(Math.PI/2); // side edge-centered
break;
case 2:
m.rotY(Math.PI/n); // side face-centered
Matrix3d m1 = new Matrix3d();
m1.rotX(Math.PI/2);
m.mul(m1);
break;
case 3:
m.set(flipX()); // back
break;
default:
throw new IllegalArgumentException("getViewMatrix: index out of range:" + index);
}
return m;
}
// http://www.mathopenref.com/polygonincircle.html
private static double getSideLengthFromInscribedRadius(double radius, int n) {
if (n == 2) {
return radius;
}
return radius * 2 * Math.tan(Math.PI/n);
}
private static double getInscribedRadiusFromSideLength(double length, int n) {
if (n == 2) {
return length;
}
return length / (2 * Math.tan(Math.PI/n));
}
// http://www.mathopenref.com/polygonradius.html
private static double getSideLengthFromCircumscribedRadius(double radius, int n) {
if (n == 2) {
return radius;
}
return radius * (2 * Math.sin(Math.PI/n));
}
private static double getCircumscribedRadiusFromSideLength(double length, int n) {
if (n == 2) {
return length;
}
return length / (2 * Math.sin(Math.PI/n));
}
private static Matrix3d flipX() {
Matrix3d rot = new Matrix3d();
rot.m00 = 1;
rot.m11 = -1;
rot.m22 = -1;
return rot;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy