package edu.stanford.rsl.conrad.geometry.shapes.simple; import java.util.ArrayList; import edu.stanford.rsl.apps.gui.opengl.PointCloudViewer; import edu.stanford.rsl.conrad.geometry.AbstractCurve; import edu.stanford.rsl.conrad.geometry.AbstractShape; import edu.stanford.rsl.conrad.geometry.Axis; import edu.stanford.rsl.conrad.geometry.General; import edu.stanford.rsl.conrad.geometry.transforms.AffineTransform; import edu.stanford.rsl.conrad.geometry.transforms.Translation; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleVector; import edu.stanford.rsl.conrad.utils.CONRAD; /** * Creates a Pyramid */ public class Pyramid extends SimpleSurface { /** * */ private static final long serialVersionUID = -3684428666704786034L; private Axis principalAxis = new Axis(new SimpleVector(0,0,1)); public Pyramid() { // TODO Auto-generated constructor stub } /** * @param dx * @param dy * @param dz */ public Pyramid(double dx, double dy, double dz) { this(); init(dx, dy, dz, null); } /** * @param dx * @param dy * @param dz * @param transform */ public Pyramid(double dx, double dy, double dz,AffineTransform transform){ this(); init(dx, dy, dz, transform); } /** * @param p */ public Pyramid(Pyramid p) { super(p); // TODO Auto-generated constructor stub principalAxis = (p.principalAxis != null) ? p.principalAxis.clone() : null; } public void init(double dx, double dy, double dz, AffineTransform transform){ if(transform == null){ SimpleMatrix mat = new SimpleMatrix(3,3); mat.identity(); this.transform = new AffineTransform(mat, new SimpleVector(3)); } this.transform = new Translation(0, 0, 0); this.min = new PointND(-dx, -dy, -dz); //this.min = this.transform.transform(this.min); this.max = new PointND(dx, dy, 0); //this.max = this.transform.transform(this.max); } @Override public boolean isBounded() { // TODO Auto-generated method stub return true; } @Override public Axis getPrincipalAxis() { // TODO Auto-generated method stub return null; } @Override public AbstractShape tessellate(double accuracy) { // TODO Auto-generated method stub return null; } @Override public AbstractShape clone() { // TODO Auto-generated method stub return null; } public PointND interpolatePoint(double factor, PointND[] point){ PointND first; PointND second; if (factor < 0.25){ first = point[0]; second = point[1]; }else if (factor < 0.5){ first = point[1]; second = point[2]; factor -= 0.25; }else if (factor < 0.75){ first = point[2]; second = point[3]; factor -= 0.5; }else { first = point[3]; second = point[0]; factor -= 0.75; } return interpolation(first, second, 4.0*factor); } public PointND interpolation(PointND first, PointND second, double factor){ SimpleVector resultVector = first.getAbstractVector().multipliedBy(1.0 - factor); resultVector.add(second.getAbstractVector().multipliedBy(factor)); return new PointND(resultVector); } public float[] getRasterPoints(int elementCountU, int elementCountV){ if (elementCountV < 2 || elementCountV < 3){ System.out.println("Error! elementCounts too small."); return null; } PointND[] point = new PointND[4]; int numberOfCurves = elementCountU; int pointsOnCurve = elementCountV; float[] curve = new float[numberOfCurves*pointsOnCurve*3]; double range = (max.get(2) - min.get(2)); double a = 0.5*(max.get(0) - min.get(0))/ range; double b = 0.5*(max.get(1) - min.get(1))/ range; double height; for (int j = 0; j < numberOfCurves; j++){ //double factor = ((double)j/(numberOfCurves - 1)); height = j*(max.get(2) - min.get(2))/(numberOfCurves - 1); //double coorZ = (double)min.get(2) + factor; double coorZ = (min.get(2) + height)/range; for (int i = 0; i < pointsOnCurve; i++){ double v = ((double)i/(pointsOnCurve)); point[0] = transform.transform(new PointND(min.get(0)*a*Math.abs(coorZ), min.get(1)*b*Math.abs(coorZ), coorZ*range)); point[1] = transform.transform(new PointND(max.get(0)*a*Math.abs(coorZ), min.get(1)*b*Math.abs(coorZ), coorZ*range)); point[2] = transform.transform(new PointND(max.get(0)*a*Math.abs(coorZ), max.get(1)*b*Math.abs(coorZ), coorZ*range)); point[3] = transform.transform(new PointND(min.get(0)*a*Math.abs(coorZ), max.get(1)*b*Math.abs(coorZ), coorZ*range)); PointND rasterPointV = interpolatePoint(v, point); curve[(i*numberOfCurves+j)*3] = (float)rasterPointV.get(0); curve[(i*numberOfCurves+j)*3+1] = (float)rasterPointV.get(1); curve[(i*numberOfCurves+j)*3+2] = (float)(coorZ*range); } } return curve; } public ArrayList<PointND> getPointCloud(int u, int v){ float[] rasterPoints = this.getRasterPoints(u, v); //PointND[] points = box.getRasterPoints(256); ArrayList<PointND> pointsList= new ArrayList<PointND>(); for (int i= 0; i < rasterPoints.length/3; i++){ PointND point = new PointND(rasterPoints[(i*3)],rasterPoints[(i*3)+1],rasterPoints[(i*3)+2]); // PointND point = new PointND(points[i].get(0),points[i].get(1),points[i].get(2)); pointsList.add(point); } return pointsList; } public static void main(String [] args){ Pyramid pyramid = new Pyramid(10,10,10); if (pyramid != null) { float[] rasterPoints = pyramid.getRasterPoints(3, 16); ArrayList<PointND> pointsList= new ArrayList<PointND>(); for (int i= 0; i < rasterPoints.length/3; i++){ PointND point = new PointND(rasterPoints[(i*3)],rasterPoints[(i*3)+1],rasterPoints[(i*3)+2]); // PointND point = new PointND(points[i].get(0),points[i].get(1),points[i].get(2)); pointsList.add(point); } PointCloudViewer pcv = new PointCloudViewer("Pyramid Visualization", pointsList); pcv.setVisible(true); } } @Override public ArrayList<PointND> getHits(AbstractCurve other) { // TODO Auto-generated method stub //throw new RuntimeException("Not implemented yet"); //return null; StraightLine buff = (StraightLine) other; StraightLine line = new StraightLine(buff.getPoint().clone(), buff.getDirection().clone()); line.applyTransform(transform.inverse()); ArrayList<PointND> hitsOnShape = General.intersectRayWithCuboid(line, min, max); return getCorrectedHits(hitsOnShape); } @Override public boolean isMember(PointND point, boolean pointTransformed) { // TODO Auto-generated method stub //throw new RuntimeException("Not implemented yet"); //return false; // Now, only the bounding box is checked. for (int j=0; j < point.getDimension(); j++){ double coord = point.get(j); if (coord > max.get(j) + CONRAD.SMALL_VALUE || coord < min.get(j) - CONRAD.SMALL_VALUE) { return false; } } return true; } @Override public PointND evaluate(double u, double v) { // TODO Auto-generated method stub throw new RuntimeException("Not implemented yet"); //return null; } @Override public int getDimension() { return 3; } @Override public PointND[] getRasterPoints(int number) { // TODO Auto-generated method stub //getRasterPoints((int)Math.sqrt(number), (int)Math.sqrt(number)); throw new RuntimeException("Not implemented yet"); } } /* * Copyright (C) 2010-2014 Zijia Guo, Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */