/** * */ package wblut.geom; // TODO: Auto-generated Javadoc /** * The Class WB_NurbsSurfaceOfRevolution. * * @author Frederik Vanhoutte, W:Blut */ public class WB_NurbsSurfaceOfRevolution { /** * Gets the surface of revolution. * * @param C the c * @param p the p * @param v the v * @param theta the theta * @return the surface of revolution */ public static WB_RBSplineSurface getSurfaceOfRevolution(final WB_BSpline C, final WB_Point3d p, final WB_Vector3d v, double theta) { if (theta < 0) { theta *= -1; v.mult(-1); } while (theta > 360) { theta -= 360; } int narcs; final WB_Line L = new WB_Line(p, v); final double[] U; if (theta <= 90) { narcs = 1; U = new double[6]; } else if (theta <= 180) { narcs = 2; U = new double[8]; U[3] = 0.5; U[4] = 0.5; } else if (theta <= 270) { U = new double[10]; narcs = 3; U[3] = 1.0 / 3; U[4] = U[3]; U[5] = 2.0 / 3; U[6] = U[5]; } else { U = new double[12]; narcs = 4; U[3] = 0.25; U[4] = U[3]; U[5] = 0.5; U[6] = U[5]; U[7] = 0.75; U[8] = U[7]; } final WB_Point3d[][] points = new WB_Point3d[1 + 2 * narcs][C.n() + 1]; final double[][] weights = new double[1 + 2 * narcs][C.n() + 1]; final double dtheta = theta / narcs * Math.PI / 180; int i = 0; int j = 3 + 2 * (narcs - 1); for (i = 0; i < 3; j++, i++) { U[i] = 0; U[j] = 1; } final int n = 2 * narcs; final double wm = Math.cos(dtheta * 0.5); double angle = 0; final double[] cosines = new double[narcs + 1]; final double[] sines = new double[narcs + 1]; for (i = 1; i <= narcs; i++) { angle = angle + dtheta; cosines[i] = Math.cos(angle); sines[i] = Math.sin(angle); } for (j = 0; j <= C.n(); j++) { final WB_Point3d O = WB_Intersection.closestPoint(C.points()[j], L); final WB_Vector3d X = C.points()[j].subToVector(O); final double r = X.normalize(); final WB_Vector3d Y = new WB_Vector3d(v.cross(X)); final WB_Point3d P0 = new WB_Point3d(C.points()[j]); points[0][j] = new WB_Point3d(P0); weights[0][j] = 1; final WB_Vector3d T0 = new WB_Vector3d(Y); int index = 0; angle = 0.0; for (i = 1; i <= narcs; i++) { final WB_Point3d P2 = new WB_Point3d(O); P2.add(X, r * cosines[i]); P2.add(Y, r * sines[i]); points[index + 2][j] = new WB_Point3d(P2); weights[index + 2][j] = 1; final WB_Vector3d T2 = Y.multAndCopy(cosines[i]); T2.add(X, -sines[i]); final WB_Line L1 = new WB_Line(P0, T0); final WB_Line L2 = new WB_Line(P2, T2); final WB_IntersectionResult is = WB_Intersection.closestPoint( L1, L2); final WB_Point3d p1 = (is.dimension == 0) ? (WB_Point3d) is.object : ((WB_ExplicitSegment) is.object).getOrigin(); points[index + 1][j] = p1; weights[index + 1][j] = wm; index = index + 2; if (i < narcs) { P0.set(P2); T0.set(T2); } } } final WB_NurbsKnot UKnot = new WB_NurbsKnot(2, U); return new WB_RBSplineSurface(points, UKnot, C.knot(), weights); } /** * Gets the surface of revolution. * * @param C the c * @param p the p * @param v the v * @param theta the theta * @return the surface of revolution */ public static WB_RBSplineSurface getSurfaceOfRevolution( final WB_RBSpline C, final WB_Point3d p, final WB_Vector3d v, double theta) { if (theta < 0) { theta *= -1; v.mult(-1); } while (theta > 360) { theta -= 360; } int narcs; final WB_Line L = new WB_Line(p, v); final double[] U; if (theta <= 90) { narcs = 1; U = new double[6]; } else if (theta <= 180) { narcs = 2; U = new double[8]; U[3] = 0.5; U[4] = 0.5; } else if (theta <= 270) { U = new double[10]; narcs = 3; U[3] = 1.0 / 3; U[4] = U[3]; U[5] = 2.0 / 3; U[6] = U[5]; } else { U = new double[12]; narcs = 4; U[3] = 0.25; U[4] = U[3]; U[5] = 0.5; U[6] = U[5]; U[7] = 0.75; U[8] = U[7]; } final WB_Point3d[][] points = new WB_Point3d[1 + 2 * narcs][C.n() + 1]; final double[][] weights = new double[1 + 2 * narcs][C.n() + 1]; final double dtheta = theta / narcs * Math.PI / 180; int i = 0; int j = 3 + 2 * (narcs - 1); for (i = 0; i < 3; j++, i++) { U[i] = 0; U[j] = 1; } final int n = 2 * narcs; final double wm = Math.cos(dtheta * 0.5); double angle = 0; final double[] cosines = new double[narcs + 1]; final double[] sines = new double[narcs + 1]; for (i = 1; i <= narcs; i++) { angle = angle + dtheta; cosines[i] = Math.cos(angle); sines[i] = Math.sin(angle); } for (j = 0; j <= C.n(); j++) { final WB_Point3d O = WB_Intersection.closestPoint(C.points()[j], L); final WB_Vector3d X = C.points()[j].subToVector(O); final double r = X.normalize(); final WB_Vector3d Y = new WB_Vector3d(v.cross(X)); final WB_Point3d P0 = new WB_Point3d(C.points()[j]); points[0][j] = new WB_Point3d(P0); weights[0][j] = C.wpoints()[j].w; final WB_Vector3d T0 = new WB_Vector3d(Y); int index = 0; angle = 0.0; for (i = 1; i <= narcs; i++) { final WB_Point3d P2 = new WB_Point3d(O); P2.add(X, r * cosines[i]); P2.add(Y, r * sines[i]); points[index + 2][j] = new WB_Point3d(P2); weights[index + 2][j] = C.wpoints()[j].w; final WB_Vector3d T2 = Y.multAndCopy(cosines[i]); T2.add(X, -sines[i]); final WB_Line L1 = new WB_Line(P0, T0); final WB_Line L2 = new WB_Line(P2, T2); final WB_IntersectionResult is = WB_Intersection.closestPoint( L1, L2); final WB_Point3d p1 = (is.dimension == 0) ? (WB_Point3d) is.object : ((WB_ExplicitSegment) is.object).getOrigin(); points[index + 1][j] = p1; weights[index + 1][j] = wm * C.wpoints()[j].w; index = index + 2; if (i < narcs) { P0.set(P2); T0.set(T2); } } } final WB_NurbsKnot UKnot = new WB_NurbsKnot(2, U); return new WB_RBSplineSurface(points, UKnot, C.knot(), weights); } }