001/*
002 * Renderer Models. The MIT License.
003 * Copyright (c) 2022 rlkraft@pnw.edu
004 * See LICENSE for details.
005*/
006
007package renderer.models_L;
008
009import java.util.function.DoubleFunction;
010import java.util.function.ToDoubleFunction;    // could use this instead
011import java.util.function.DoubleUnaryOperator; // could use this instead
012//https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
013
014/**
015   Create a wireframe model of a surface of revolution around the y-axis.
016<p>
017   See <a href="https://en.wikipedia.org/wiki/Surface_of_revolution#Rotating_a_function" target="_top">
018                https://en.wikipedia.org/wiki/Surface_of_revolution#Rotating_a_function</a>
019
020   @see ParametricSurface
021*/
022public class SurfaceOfRevolution extends ParametricSurface
023{
024   /**
025      Create a surface of revolution around the y-axis
026      based on a cosine function.
027   */
028   public SurfaceOfRevolution()
029   {
030      this(t -> 0.5 * (1 + Math.cos(Math.PI * t)),
031           -1.0, 1.0, 49, 49);
032   }
033
034
035   /**
036      Create a surface of revolution around the y-axis
037      with the given radial function, {@code r = r(y)},
038      the given parameter range along the y-axis, and
039      the given number of circles of latitude.
040
041      @param r   radius function
042      @param y1  beginning value along the y-axis
043      @param y2  ending value along the y-axis
044      @param n   number of circles of latitude
045      @param k   number of lines of longitude
046      @throws IllegalArgumentException if {@code n} is less than 2
047      @throws IllegalArgumentException if {@code k} is less than 2
048   */
049   public SurfaceOfRevolution(final DoubleFunction<Double> r,
050                              final double y1, final double y2,
051                              final int n, final int k)
052   {
053      this(r, y1, y2, 0, 2*Math.PI, n, k);
054   }
055
056
057   /**
058      Create a surface of revolution around the y-axis with
059      the given radial function, {@code r = r(y)}, the given
060      angular range for the sector of revolution, the given
061      parameter range along the y-axis, and the given number
062      of circles of latitude.
063
064      @param r       radius function
065      @param y1      beginning value along the y-axis
066      @param y2      ending value along the y-axis
067      @param theta1  beginning value of angular parameter range
068      @param theta2  ending value of angular parameter range
069      @param n       number of circles of latitude
070      @param k       number of lines of longitude
071      @throws IllegalArgumentException if {@code n} is less than 2
072      @throws IllegalArgumentException if {@code k} is less than 2
073   */
074   public SurfaceOfRevolution(final DoubleFunction<Double> r,
075                              final double y1, final double y2,
076                              final double theta1, final double theta2,
077                              final int n, final int k)
078   {
079      super( (y,t) -> r.apply(y) * Math.cos(t),
080             (y,t) -> y,
081             (y,t) -> r.apply(y) * Math.sin(t),
082             y1, y2,
083             theta1, theta2,
084             n, k );
085   }
086
087
088   /**
089      Create a surface of revolution around the y-axis
090      of the given radial parametric curve.
091
092      @param x   first component function of the parametric curve
093      @param y   second component function of the parametric curve
094      @param s1  beginning parameter value
095      @param s2  ending parameter value
096      @param n   number of circles of latitude
097      @param k   number of lines of longitude
098      @throws IllegalArgumentException if {@code n} is less than 2
099      @throws IllegalArgumentException if {@code k} is less than 2
100   */
101   public SurfaceOfRevolution(final DoubleFunction<Double> x,
102                              final DoubleFunction<Double> y,
103                              final double s1, final double s2,
104                              final int n, final int k)
105   {
106      this(x, y, s1, s2, 0, 2*Math.PI, n, k );
107   }
108
109
110   /**
111      Create a surface of revolution around the y-axis
112      of the given radial parametric curve and the given
113      angular range for the sector of revolution.
114
115      @param x       first component function of the parametric curve
116      @param y       second component function of the parametric curve
117      @param s1      beginning parameter value
118      @param s2      ending parameter value
119      @param theta1  beginning value of angular parameter range
120      @param theta2  ending value of angular parameter range
121      @param n       number of circles of latitude
122      @param k       number of lines of longitude
123      @throws IllegalArgumentException if {@code n} is less than 2
124      @throws IllegalArgumentException if {@code k} is less than 2
125   */
126   public SurfaceOfRevolution(final DoubleFunction<Double> x,
127                              final DoubleFunction<Double> y,
128                              final double s1, final double s2,
129                              final double theta1, final double theta2,
130                              final int n, final int k)
131   {
132      super( (s,t) -> x.apply(s) * Math.cos(t),
133             (s,t) -> y.apply(s),
134             (s,t) -> x.apply(s) * Math.sin(t),
135             s1, s2,
136             theta1, theta2,
137             n, k,
138             String.format("SurfaceOfRevolution(%d,%d)", n, k) );
139   }
140}//Surface of Revolution