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.AbstractShape; import edu.stanford.rsl.conrad.geometry.Axis; import edu.stanford.rsl.conrad.geometry.bounds.HalfSpaceBoundingCondition; import edu.stanford.rsl.conrad.geometry.transforms.AffineTransform; import edu.stanford.rsl.conrad.geometry.transforms.Transform; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleVector; /** * Creates a Cone. */ public class Cone extends QuadricSurface { private static final long serialVersionUID = 6986546973890638795L; private Axis principalAxis = new Axis(new SimpleVector(0,0,1)); public Cone() { } /** * @param dx * @param dy * @param dz */ public Cone(double dx, double dy, double dz){ init(dx, dy, dz, null); } /** * @param c */ public Cone(Cone c){ super(c); principalAxis = (c.principalAxis != null) ? c.principalAxis.clone() : null; min = c.min != null ? c.min.clone() : null; max = c.max != null ? c.max.clone() : null; } protected void init(double dx, double dy, double dz,Transform transform) { if(transform == null){ SimpleMatrix mat = new SimpleMatrix(3,3); mat.identity(); transform = new AffineTransform(mat, new SimpleVector(3)); } this.transform = transform; Plane3D topPlane = new Plane3D(new PointND(0,0,0), new SimpleVector(0,0,-1)); Plane3D bottomPlane = new Plane3D(new PointND(0,0,-dz), new SimpleVector(0,0,1)); addBoundingCondition(new HalfSpaceBoundingCondition(topPlane)); addBoundingCondition(new HalfSpaceBoundingCondition(bottomPlane)); double constArray[][] = {{dz/dx,0,0},{0,dz/dy,0},{0,0,-1}}; super.constMatrix = new SimpleMatrix(constArray); super.constant = 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() { return true; } @Override public int getDimension() { throw new UnsupportedOperationException(); } public double interpolate(double factor){ // how to add some weight to make it non-uniform distribution along z axis??? double first = min.get(2); double second = max.get(2); return (first*(1.0 - factor) + second*factor); } public float[] getRasterPoints(int elementCountU, int elementCountV) { if (elementCountV < 2 || elementCountV < 3){ System.out.println("Error! elementCounts too small."); return null; } int numberOfCurves = elementCountU; int pointsOnCurve = elementCountV; float[] curve = new float[numberOfCurves*pointsOnCurve*3]; double a = 0.5*(max.get(0) - min.get(0))/(max.get(2) - min.get(2)); double b = 0.5*(max.get(1) - min.get(1))/(max.get(2) - min.get(2)); double angleIncrement = (2*Math.PI)/(pointsOnCurve); double angle; double height; double factor; for (int j = 0; j < numberOfCurves; j++){ for (int i = 0; i < pointsOnCurve; i++) { angle = i*angleIncrement; height = (double)(j*(max.get(2) - min.get(2))/(numberOfCurves - 1)); factor = (double)(j/(numberOfCurves -1)); float coorZ = (float) (min.get(2) + height); //float coorZ = (float) (interpolate(height)); // ?? the input of interpolate() should be factor, but error. why??? curve[(i*numberOfCurves+j)*3] = (float) (((min.get(0) + max.get(0))/2) + a*coorZ*Math.cos(angle)); curve[(i*numberOfCurves+j)*3+1] = (float) (((min.get(1) + max.get(1))/2) + b*coorZ*Math.sin(angle)); curve[(i*numberOfCurves+j)*3+2] = coorZ; } } return curve; } @Override public Axis getPrincipalAxis() { return principalAxis; } @Override public void applyTransform(Transform t) { super.applyTransform(t); this.min = t.transform(this.min); this.max = t.transform(this.max); } @Override public AbstractShape tessellate(double accuracy) { // TODO Auto-generated method stub return null; } @Override public AbstractShape clone() { return new Cone(this); } 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){ Cone cone = new Cone (10,10,10); int u = 2; int v = 10; ArrayList<PointND> pointsList = new ArrayList<PointND>(); pointsList = cone.getPointCloud(u, v); PointCloudViewer pcv = new PointCloudViewer("Cone Visualization", pointsList); pcv.setVisible(true); } } /* * Copyright (C) 2010-2014 Andreas Maier, Rotimi X Ojo, Zijia Guo * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */