- All Implemented Interfaces:
Shape3D
Each element of the grid contains
- a point on the surface that the grid represents. This
point corresponds to the U-V coordinate (0,0), and may
be null. It may also be marked as "unfilled" by calling
remove(int,int)
orremove(int,int,int,int)
. - the intermediate control points for a cubic Bézier curve along the edge from (0,0) to (1, 0), excluding the initial control point. These control points are P10 and P20, where Pij are the control points for the corresponding cubic Bézier patch. The values of these intermediate control points can be explicitly set, although they will be computed if necessary.
- the intermediate control points for a cubic Bézier curve along the edge from (0,0) to (0, 1), excluding the initial control point. These control points are P01 and P02, where Pij are the control points for the corresponding cubic Bézier patch. The values of these intermediate control points can be explicitly set, although they will be computed if necessary.
- the four control points P11, P21, P12 and P22. While these control points can be provided explicitly, if these points are not provided a default will be computed.
createConnectionsTo(BezierGrid)
,
createConnectionsTo(BezierGrid,int)
,
createConnectionsTo(BezierGrid,int,boolean)
,
createConnectionsTo(BezierGrid,boolean,int...)
,
createConnectionsTo(BezierGrid,int,boolean,int...)
, and
createConnectionsTo(BezierGrid,int,boolean,boolean,int...)
have a precondition: except when a loop is being closed (that is, the
intermediate control points differ from the grid points), multiple
points on a grid must not have the same values. For cases where it
is convenient to create grids in which multiple points have the
same values, one may be able to use the method
subgrid(int,int,int,int)
to create a suitable
grid. This is useful in some unusual cases such as creating a Möbius
strip where to get a closed curve, the surface has to be traversed twice,
and a subgrid will produce a shape that is closed.
A grid has two dimensions, with indices (i,j). For an element at indices (i, j), the end points for each edge of the patch are shown in the following table.
Edge 2 and Edge 3 are traversed in the opposite direction from the one shown when determining the patch's orientation, which uses the right-hand rule. The implementation stores the control points for Edge 0 and Edge 3 in the element associated with the index (i,j). Adjacent elements are queried to find the remaining edge's control points.
Starting
(u,v)Ending
(uv)Starting
indicesEnding
indicesEdge 0 (0,0) (1,0) (i,j) (i+1,j) Edge 1 (1,0) (1,1) (i+1,j) (i+1,j+1) Edge 2 (0,1) (1,1) (i,j+1) (i+1,j+1) Edge 3 (0,0) (0,1) (i,j) (i,j+1)
Splines are automatically created to set the shape of each edge, ensuring that adjacent patches share common edges. The knots for these splines have either constant values of i or constant values of j. These splines are controlled by two constructor arguments: uclosed and vclosed:
- When uclosed is false, the splines with knots at constant values of j cover spans of points that are within the grid and not null.
- When uclosed is true, the splines with knots at constant values of j also cover spans of points that are within the grid and not null. If none of the elements are null, a cyclic spine is created. Otherwise splines are delimited by null grid points, and the sequence of knots with wrap around if necessary (i.e., a knot at the maximum value of i may be followed by a knot for which i = 0).
- When vclosed is false, the splines with knots at constant values of i cover spans of points that are within the grid and not null.
- When vclosed is true, the splines with knots at constant values of i also cover spans of points that are within the grid and not null. If none of the elements are null, a cyclic spine is created. Otherwise splines are delimited by null grid points, and the sequence of knots with wrap around if necessary (i.e., a knot at the maximum value of j may be followed by a knot for which j = 0).
- When one is true, the grid can represent a cylinder or a ring with two boundaries.
One can partition the grid into regions by giving each point a
region ID (by default, points will be in region 0). The splines described
above will be split into multiple splines when a region boundary is
crossed. This allows the grid to have sharp corners or edges at the
region boundaries. A point on one side of a boundary will be connected to
a point on the other side by a straight line segment. The methods to
create regions are setRegion(int,int,int)
and
setRegion(int,int,int,int,int)
.
In addition, users may define additional splines.
The additional splines are used to set edges after the
automatically generated splines are created, thus overriding
those values. The additional splines are used in the order in which
they were defined. The methods startSpline(int,int)
,
moveU(int)
, moveV(int)
, and endSpline(boolean)
are used for configuring these splines.
For example, in order to create the following object,
Note that the value of z for each point adds a constant 10.0 to each value, which translates the grid upwards. After this grid is created, it can be modified by removing the vertices above a specific latitude (note that the area removed has boundary that corresponds to a series of points with a constant latitude).int N = 41; // grid height and width int NC = N/2; // grid center point. Point3D[][] array1 = new Point3D[N][N]; double r = 100.0; // radius of the sphere for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { int k = Math.max(Math.abs(i-NC),Math.abs(j-NC)); double theta = k*(Math.PI/(N-1)); double x, y, z; if (k == 0) { // top of the sphere x = 0.0; y = 0.0; z = r; } else { // Each square box around the center of // the grid (in U-V space) represents a // line of constant latitude. Adjacent // vertices along a specific box are // separated by evenly spaced longitude // values. int nanglesHalf = k*4; double delta = Math.PI/(nanglesHalf); double angle; if (i == NC+k) { angle = -(NC-j)*delta; } else if (j == NC-k) { angle = -(NC + 2*k - i)*delta; } else if (i == NC-k) { angle = -((j-NC) + 4*k)*delta; } else if (j == NC+k) { angle = (NC+2*k-i)*delta; } else { throw new Error(); } x = r * Math.cos(angle) * Math.sin(theta); y = r * Math.sin(angle) * Math.sin(theta); // the 10.0 shifts the sphere up slightly // along the Z axis z = 10.0 + r * Math.cos(theta); } array1[i][j] = new Point3D.Double(x, y, z); } } BezierGrid grid1 = new BezierGrid(array1);
The half sphere now has a boundary with two components (two distinct continuous, closed paths). For these, we set a user defined spline in order to make sure that splines will be created going through these vertices and that the spline will be a cyclic one (the argument of true for endSpline makes the spline a cyclic spline).grid1.remove(NC-3, NC-3, 6, 6);
The next step is to create the bottom half of the sphere. A constructor (please see the documentation forgrid1.startSpline(NC-3, NC-3); grid1.moveU(6); grid1.moveV(6); grid1.moveU(-6); grid1.moveV(-6); grid1.endSpline(true); grid1.startSpline(0,0); grid1.moveU(N-1); grid1.moveV(N-1); grid1.moveU(-(N-1)); grid1.moveV(-(N-1)); grid1.endSpline(true);
BezierGrid(BezierGrid,boolean,UnaryOperator)
for restrictions) allows one to reproduce the configuration of an
existing grid, with a lambda expression mapping previous vertex
locations into new ones:
The argumentBezierGrid grid2 = new BezierGrid(grid1, true, (p) -> { double x = p.getX(); double y = p.getY(); double z = - p.getZ(); return new Point3D.Double(x, y, z); });
true
indicates that grid2 should have its
orientation reversed compared to grid1.
At this point, one can create a surface and append the two grids.
The next step is to create an array of grids (it will just contain a single element). This grid will have two vertices in its U direction, and will connect grid1 to grid2. The argument 'false' prevents the grids from being split at spline boundaries, and the two arguments with the valueSurface3D surface = new Surface3D.Double(); surface.append(grid1); surface.append(grid2);
NC-3
are indices of a point on grid1's
boundary corresponding to the circular hole in grid1 at the 'top' of
its half sphere. Because there are only two vertices in the U direction,
the call to createConnectionsTo generates a cylinder.
The newly created grid is appended to the surface.
Similarly, one can create a second set of grids, this time with 11 vertices in the U direction.BezierGrid[] connections = grid1.createConnectionsTo(grid2, false, NC-3, NC-3); for (BezierGrid g: connections) { surface.append(g); }
In the U direction index 0 and 10 represent V values that match the boundaries at the widest points of the two half spheres (grid1 and grid2). The remaining vertices have to be configured manually. For an example, this is done as follows:connections = grid1.createConnectionsTo(grid2, 11, false, 0, 0);
The result is a 'bulge' connecting the two half spheres, with the bulge using a sinusoidal shape. Finally, one can create a series of images using methods from the p3d package:BezierGrid cgrid = connections[0]; int limu = cgrid.getUArrayLength() ; int limv = cgrid.getVArrayLength(); for (int j = 0; j < limv; j++) { for (int i = 1; i < limu - 1; i++) { Point3D p = cgrid.getPoint(0, j); double t = ((double)i)/limu; double z1 = p.getZ(); double z2 = cgrid.getPoint(10, j).getZ(); double z = z1*(1-t) + z2*t; double scale = 1.0 + 0.25*Math.sin(Math.PI*t); double x = scale*p.getX(); double y = scale*p.getY(); cgrid.setPoint(i, j, x, y, z); } } surface.append(cgrid);
Model3D m3d = new Model3D(); m3d.append(surface); m3d.setTessellationLevel(2); m3d.createImageSequence (new FileOutputStream("images.isq"), "png", 8, 6, 0.0, 0.0, 0.0, false);
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interface
Interface for mapping one point in a two or three dimensional space into a point in a three dimensional point, with parameters indicating if the point is a control point. -
Constructor Summary
ConstructorsConstructorDescriptionBezierGrid
(double[] sarray, boolean uclosed, double[] tarray, boolean vclosed, boolean linear, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions and specifying if the U and V directions are cyclic or not, with possibly a linear constraint for the line segments connecting adjacent points on the grid.BezierGrid
(double[] sarray, boolean uclosed, double[] tarray, boolean vclosed, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions and specifying if the U and V directions are cyclic or not.BezierGrid
(double[] sarray, double[] tarray, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions.BezierGrid
(int nu, boolean uclosed, int nv, boolean vclosed) Constructor for an empty grid.BezierGrid
(int nu, boolean uclosed, int nv, boolean vclosed, boolean linear) Constructor for an empty, possibly linear grid.BezierGrid
(Path2D template, BezierGrid.Mapper mapper) Constructor given a 2D path and a Mapper.BezierGrid
(Path2D path, Point3DMapper<Point3D> mapper, int n, boolean uclosed) Constructor based on a 2D path.BezierGrid
(BezierGrid grid, boolean reverse, UnaryOperator<Point3D> f) Constructor based on an existing Bézier grid.BezierGrid
(Point3D[][] points) Constructor.BezierGrid
(Point3D[][] points, boolean uclosed, boolean vclosed) Constructor for open or closed grids.BezierGrid
(Point3D[][] points, boolean uclosed, boolean vclosed, boolean linear) Constructor for open or closed grids with possibily linear connections between adjacent grid points. -
Method Summary
Modifier and TypeMethodDescriptionboolean
badSplines
(Appendable out) Test if a spline was created with inappropriate values.Create Bézier grids that will connect this grid to a specified grid.createConnectionsTo
(BezierGrid grid, boolean split) Create Bézier grids that will connect this grid to a specified grid, optionally splitting the returned grids into multiple grids.createConnectionsTo
(BezierGrid grid, boolean split, int... indices) Create Bézier grids that will connect this grid to a specified grid, optionally splitting the returned grids into multiple grids, and restricting the returned grids to ones that match a specified boundary.createConnectionsTo
(BezierGrid grid, int n) Create Bézier grids, with a specified number of vertices in the 'U' direction, that will connect this grid to a specified rid.createConnectionsTo
(BezierGrid grid, int n, boolean split) Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis and optionally splitting the returned grids into multiple grids.createConnectionsTo
(BezierGrid grid, int n, boolean split, boolean exclude, int... indices) Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis and optionally splitting the returned grids into multiple grids, and specifying pairs of indices for vertices along allowed or disallowed boundaries.createConnectionsTo
(BezierGrid grid, int n, boolean split, int... indices) Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis, optionally splitting the returned grids into multiple grids, and specifying pairs of indices for vertices along allowed boundaries.createExtensionGrid
(Point3DMapper<Point3D> mapping, int[] regionChanges, int n, int uIndex, int vIndex) Create an extension to a Bézier grid based on a mapping function.void
Create all splines.void
endSpline
(boolean cyclic) Assert that the end of a user-defined spline has been reached.flip()
Reverse the orientation from the current orientation.Get the boundary for this Shape3D.getBoundary
(int... indices) Get the boundary components that pass through specific grid points.Get a bounding rectangular cuboid for a 3D shape.getComponent
(int i) Get a component of this shape.boolean
getFullSplineU
(int i, int j, double[] coords) Get all the control points for the spline connecting a point with indices (i, j) to a point with indices (i+1, j).boolean
getFullSplineV
(int i, int j, double[] coords) Get all the control points for the spline connecting a point with indices (i, j) to a point with indices (i, j+1).static BezierGrid.Mapper
Get a mapper that will apply an indexed affine transform to points along a 2D or 3D curve.boolean
getPatch
(int i, int j, double[] coords) Get the coordinates for a cubic Bézier patch corresponding to the specified grid coordinates for this Bézier grid.getPoint
(int i, int j) Get the current value of a point on the grid.boolean
getRemainingControlPoints
(int i, int j, double[] coords) Get the remaining control points for a patch.boolean
getSplineU
(int i, int j, double[] coords) Get the spline connecting a point with indices (i, j) to a point with indices (i+1, j).boolean
getSplineV
(int i, int j, double[] coords) Get the spline connecting a point with indices (i, j) to a point with indices (i, j+1).getSurfaceIterator
(Transform3D tform) Get a surface iterator for this Shape3D.final SurfaceIterator
getSurfaceIterator
(Transform3D tform, int level) Get a surface iterator for this Shape3D, subdividing the surface.int
Get the array length in the U direction (e.g., the length for the first index).int
Get the array length in the V direction (e.g., the length for the second index).boolean
Determine if this Shape3D is a closed two-dimensional manifold.boolean
Determine if a surface is oriented.boolean
Determine if the orientation for this grid is reversed.boolean
Determine if the grid is closed in the U direction.boolean
Determine if the grid is closed in the V direction.boolean
Determine if the grid is well formedboolean
isWellFormed
(Appendable out) Determine if the grid is well formed, logging error messages to an Appendablevoid
moveU
(int n) Add elements to a spline in the U direction.void
moveV
(int n) Add elements to a spline in the V direction.int
Get the number of components for this shape.void
print()
Print the points on this grid.void
print
(Appendable out) Print the points on this grid, using an Appendable for output.void
Print the points on this grid, specifying a prefix to be printed at the start of each line.void
print
(String prefix, Appendable out) Print the points on this grid, using an Appendable for output and specifying a prefix to be printed at the start of each line.void
Print the sequence of indices for explicitly added splines.void
printSplines
(Appendable out) Print the sequence of indices for explicitly added splines to an Appendable The output will list the splines in the sequence in which they were defined, and whether the splines are cyclic or not.void
printSplines
(String prefix, Appendable out) Print the sequence of indices for explicitly added splines to an Appendable and with a prefix The output will list the splines in the sequence in which they were defined, and whether the splines are cyclic or not.void
remove
(int i, int j) Remove a patch.void
remove
(int i, int j, int width, int height) Remove a rectangle of patches The patches removed will have indices varying from i to i+width exclusive an j to j+height exclusive.void
restore
(int i, int j) Restore a patch.void
restore
(int i, int j, int width, int height) Restore a rectangle of patches The patches restored will have indices varying from i to i+width exclusive an j to j+height exclusive.protected void
Reverse the use of true and false in the methodreverseOrientation(boolean)
.reverseOrientation
(boolean reverse) Set the orientation of the patches.void
Set the color for all patches on this grid.void
Set the color for a patch on this grid.void
Set the color for all patches on this grid.boolean
setLinearU
(int i, int j) Set the spline connecting a point with indices (i, j) to a point with indices (i+1, j) so that the segment is a straight line.boolean
setLinearV
(int i, int j) Set the spline connecting a point with indices (i, j) to a point with indices (i, j+1) so that the segment is a straight line.void
setPatch
(int i, int j, double[] coords) Set control points for a cubic patch associated with a grid point.void
setPatchCorners
(int i, int j, double[] coords) Set points at the corner of the cell associated with a grid location.void
setPoint
(int i, int j, double x, double y, double z) Set a point on a grid given x, y, and z coordinates for the point.void
Set a point on a grid.void
setRegion
(int i, int j, int id) Set a region ID.void
setRegion
(int i, int j, int width, int height, int id) Set a region ID for a rectangle of grid points.boolean
setRemainingControlPoints
(int i, int j, double[] rest) Set the remaining control points for a patch.boolean
setSplineU
(int i, int j, double[] coords) Set the spline connecting a point with indices (i, j) to a point with indices (i+1, j).boolean
setSplineV
(int i, int j, double[] coords) Set the spline connecting a point with indices (i, j) to a point with indices (i, j+1).void
startSpline
(int i, int j) Indicate the starting indices for a user-defined spline.subgrid
(int i, int j, int n, int m) Create a subgrid of this Bézier grid.void
traceSplines
(Appendable out) Trace calls to createSpline, indicating which grid points have control points added to them.Transpose a BezierGrid.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.bzdev.geom.Shape3D
getBoundary
-
Constructor Details
-
BezierGrid
public BezierGrid(int nu, boolean uclosed, int nv, boolean vclosed) Constructor for an empty grid. When a direction is closed, then when all points along a line in that direction are defined, no points along that line have been removed, and all points along that lie are in the same region, then the spline created will be a cyclic one. When closed, one should not duplicate an end point: the expected behavior occurs automatically.- Parameters:
nu
- the number of vertices in the U directionuclosed
- true if the U direction is close; false otherwisenv
- the number of vertices in the V directionvclosed
- true if the V direction is closed; false otherwise
-
BezierGrid
public BezierGrid(int nu, boolean uclosed, int nv, boolean vclosed, boolean linear) Constructor for an empty, possibly linear grid. When a direction is closed, then when all points along a line in that direction are defined, no points along that line have been removed, and all points along that lie are in the same region, then the spline created will be a cyclic one. When closed, one should not duplicate an end point: the expected behavior occurs automatically.When the argument
linear
is true, each grid point is configured to have its own region. By default, each line connecting two adjacent grid points will be a straight line.- Parameters:
nu
- the number of vertices in the U directionuclosed
- true if the U direction is close; false otherwisenv
- the number of vertices in the V directionvclosed
- true if the V direction is closed; false otherwiselinear
- true if lines connecting grid points are straight lines; false otherwise
-
BezierGrid
Constructor. The points on each patch are functions of two variables u and v. Increasing u moves a point on the surface towards the next highest first index and increasing v moves a point on the surface towards the next highest second index. Both u and v must be in the range [0.0, 1.0].When stored, the points provided will have their coordinates rounded to the nearest 'float' value by first casting the values to a float and then to a double.
- Parameters:
points
- a two-dimensional array of points
-
BezierGrid
Constructor for open or closed grids. The points on each patch are functions of two variables u and v. Increasing u moves a point on the surface towards the next highest first index and increasing v moves a point on the surface towards the next highest second index. Both u and v must be in the range [0.0, 1.0]. If the array is an n by m array with indices [i][j], the points at i = n-1 should not repeat the points at i = 0 to create a closed surface—that will be done automatically when uclosed is true. Similarly, when vclosed is true, the points at j = m-1 should not contain the same values as those at i = 0 as the additional patches will be provided automatically.When uclosed or vclosed is true, the splines used to create the Bézier patches will be a smooth at all points including the end points.
When stored, the points provided will have their coordinates rounded to the nearest 'float' value by first casting the values to a float and then to a double.
- Parameters:
points
- a two-dimensional array of pointsuclosed
- the grid is closed in the U directionvclosed
- the grid is closed in the V direction
-
BezierGrid
Constructor for open or closed grids with possibily linear connections between adjacent grid points. The points on each patch are functions of two variables u and v. Increasing u moves a point on the surface towards the next highest first index and increasing v moves a point on the surface towards the next highest second index. Both u and v must be in the range [0.0, 1.0]. If the array is an n by m array with indices [i][j], the points at i = n-1 should not repeat the points at i = 0 to create a closed surface—that will be done automatically when uclosed is true. Similarly, when vclosed is true, the points at j = m-1 should not contain the same values as those at i = 0 as the additional patches will be provided automatically.When uclosed or vclosed is true, the splines used to create the Bézier patches will be a smooth at all points including the end points.
When stored, the points provided will have their coordinates rounded to the nearest 'float' value by first casting the values to a float and then to a double.
When the argument
linear
is true, each grid point is configured to have its own region. By default, each line connecting two adjacent grid points will be a straight line.- Parameters:
points
- a two-dimensional array of pointsuclosed
- the grid is closed in the U directionvclosed
- the grid is closed in the V directionlinear
- true if lines connecting grid points are straight lines; false otherwise
-
BezierGrid
public BezierGrid(double[] sarray, double[] tarray, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions. The grid is a two-dimensional array whose values are points in a three-dimensional space. The first index refers to the 'U' axis and the second index refers to the 'V' axis. The values u and v are restricted to the range [0, 1) for a given pair. of indices [i][j]. The real-valued functions are functions of two arguments (s,t). Arrays sarray and tarray are one-dimensional arrays whose indices are i and j respectively and whose values are the corresponding values for s and t.When stored, the points provided will have their coordinates rounded to the nearest 'float' value by first casting the values to a float and then to a double.
- Parameters:
sarray
- the 's' values at grid points in increasing ordertarray
- the 't' values at grid points in increasing orderxfunct
- the function fx(s,t) providing the X coordinate at (s,t)yfunct
- the function fy(s,t) providing the Y coordinate at (s,t)zfunct
- the function fz(s,t) providing the Z coordinate at (s,t)
-
BezierGrid
public BezierGrid(double[] sarray, boolean uclosed, double[] tarray, boolean vclosed, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions and specifying if the U and V directions are cyclic or not. The grid is a two-dimensional array whose values are points in a three-dimensional space. The first index refers to the 'U' axis and the second index refers to the 'V' axis. The values u and v are restricted to the range [0, 1) for a given pair. of indices [i][j]. The real-valued functions are functions of two arguments (s,t). Arrays sarray and tarray are one-dimensional arrays whose indices are i and j respectively and whose values are the corresponding values for s and t.The argument uclosed, when true, indicates that the surface corresponding to the grid is closed in the 'U' direction. Similarly vclosed, when true, indicates that the surface corresponding to the grid is closed in the 'V' direction. When the grid is closed in the U direction, sarray's final element must not repeat its initial element. Similarly when the grid is closed in the V direction, tarray's final element must not repeat its initial element.
When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
- Parameters:
sarray
- the 's' values at grid points in increasing orderuclosed
- true if the U direction is closed, false otherwisetarray
- the 't' values at grid points in increasing ordervclosed
- true if the V direction is closed, false otherwisexfunct
- the function fx(s,t) providing the X coordinate at (s,t)yfunct
- the function fy(s,t) providing the Y coordinate at (s,t)zfunct
- the function fz(s,t) providing the Z coordinate at (s,t)
-
BezierGrid
public BezierGrid(double[] sarray, boolean uclosed, double[] tarray, boolean vclosed, boolean linear, RealValuedFunctTwoOps xfunct, RealValuedFunctTwoOps yfunct, RealValuedFunctTwoOps zfunct) Constructor using real-valued functions and specifying if the U and V directions are cyclic or not, with possibly a linear constraint for the line segments connecting adjacent points on the grid.The paths connecting adjectent grid points can be constrained to be linear. The grid is a two-dimensional array whose values are points in a three-dimensional space. The first index refers to the 'U' axis and the second index refers to the 'V' axis. The values u and v are restricted to the range [0, 1) for a given pair. of indices [i][j]. The real-valued functions are functions of two arguments (s,t). Arrays sarray and tarray are one-dimensional arrays whose indices are i and j respectively and whose values are the corresponding values for s and t.
The argument uclosed, when true, indicates that the surface corresponding to the grid is closed in the 'U' direction. Similarly vclosed, when true, indicates that the surface corresponding to the grid is closed in the 'V' direction. When the grid is closed in the U direction, sarray's final element must not repeat its initial element. Similarly when the grid is closed in the V direction, tarray's final element must not repeat its initial element.
When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
When the argument
linear
is true, each grid point is configured to have its own region. By default, each line connecting two adjacent grid points will be a straight line.- Parameters:
sarray
- the 's' values at grid points in increasing orderuclosed
- true if the U direction is closed, false otherwisetarray
- the 't' values at grid points in increasing ordervclosed
- true if the V direction is closed, false otherwiselinear
- true if lines connecting grid points are straight lines; false otherwisexfunct
- the function fx(s,t) providing the X coordinate at (s,t)yfunct
- the function fy(s,t) providing the Y coordinate at (s,t)zfunct
- the function fz(s,t) providing the Z coordinate at (s,t)
-
BezierGrid
Constructor based on an existing Bézier grid. Modifications to the existing grid by calls tosetSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
will not be copied to the new grid. Other modifications (additional splines and the removal of grid cells) will be copied. The unary operator argument f, if not null, will map a point on the existing grid to the corresponding point on the new grid. If f is null, the two grids will share identical grid points.If, for example, a
BezierGrid
grid1 represents a 'top' half of a sphere centered on (0,0,0), with the boundary of grid1 having Z values of zero,
will create the 'bottom' half of the sphere. If the configuration for grid 1 is changed (e.g., by adding splines to represent paths with a constant 'latitude'), the corresponding changes will not have to be made to grid 2.BezierGrid grid2 = new BezierGrid(grid1, true, (p) -> { double z = p.getZ(); if (z > 0) z = -z; return new Point2D.Double(p.getX(), p.getY(), z); }); ... Surface3D surface = new Surface3D.Double(); surface.append(grid1); surface.append(grid2);
While the grid points, regions, splines, and whether or not a patch associated with a grid point has been removed are copied to the new grid, explicitly-set control points are not copied. As a result, if the argument grid is a subgrid, or if the argument grid's methods
setSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
have been called, one may have to use these methods on the newly created grid to get the desired results. For example, consider the following statements:BezierGrid grid1 = new BezierGrid(array); BezierGrid grid2 = grid1.subgrid(10,10,6,2); BezierGrid grid3 = new BezierGrid(grid2, false, (p) -> { return p; });
- Parameters:
grid
- the existing gridreverse
- true if this grid should have the opposite orientation from the existing grid; false if this grid should have the same orientationf
- a unary operator to map an existing grid point into a new one.
-
BezierGrid
Constructor based on a 2D path. A default method of the interfacePoint3DMapper
first converts the control points into aPoint3D
with the same X and Y values, and a Z value of 0.0, and then calls the methodPoint3DMapper.apply(int,Point3D,Point3DMapper.Type,Point3D...)
on each control point to set the Bézier curves in the V direction, repeated with the index indicating the position along the U direction. The resulting grid will generate splines along the U direction but will not alter the splines in the V direction.If mapper makes the 2D path's Y coordinate the Z coordinate and treats the 2D path's X coordinate (or a non-negative function of that coordinate) as a radius, if the 2D path's shape is such that traversing this path (when closed) is counterclockwise, and if increasing the mapper's index results in a counterclockwise rotation about the Z axis, then the surface's orientation will be correct. Othewise the surface willhave to be flipped.
- Parameters:
path
- the pathmapper
- the object that maps 2D points to 3D pointsn
- the number of points along the U axis.uclosed
- true if the U direction is closed, false otherwise
-
BezierGrid
Constructor given a 2D path and a Mapper. The mapper can be created bygetMapper(Path3D,double[])
and that mapper will be used to create the points along the grid. Control points for two-dimensional pathtemplate
will be mapped and set for control points along the V axis. The number of points long the U axis is given byBezierGrid.Mapper.getN()
and whether or not the U direction is closed is determined byBezierGrid.Mapper.isClosed()
.This constructor can be used to create 'wires' with the template specifying the cross section, with
getMapper(Path3D,double[])
creating a mapper given the wire's path. WhengetMapper(Path3D,double[])
is used, the point (0,0) will be mapped to a point on the 3D path provided bygetMapper
, a unit vector pointing along X axis in the 2 dimensional space containing the template will be mapped to the unit normal vector N for a point on the wire's path. Similarly a unit vector pointing along the Y axis in the 2 dimensional space containing the template will be mapped to the unit vector N × T, where T is the unit tangent vector for the same point on the wire's path.- Parameters:
template
- a two-dimensional path representing a cross section of a 'wire'mapper
- an instance ofBezierGrid.Mapper
that maps points on the template to points on the 'wire'
-
-
Method Details
-
getUArrayLength
public int getUArrayLength()Get the array length in the U direction (e.g., the length for the first index).- Returns:
- the array length for the U direction
-
getVArrayLength
public int getVArrayLength()Get the array length in the V direction (e.g., the length for the second index).- Returns:
- the array length for the V direction
-
isUClosed
public boolean isUClosed()Determine if the grid is closed in the U direction.- Returns:
- true if the grid is closed in the U direction; false otherwise
-
isVClosed
public boolean isVClosed()Determine if the grid is closed in the V direction.- Returns:
- true if the grid is closed in the V direction; false otherwise
-
reverseFlip
protected void reverseFlip()Reverse the use of true and false in the methodreverseOrientation(boolean)
. -
getMapper
Get a mapper that will apply an indexed affine transform to points along a 2D or 3D curve. The indexes range from 0 to N where N is the value returned byPath3DInfo.numberOfDrawableSegments(wire)
. This mapper treats a two dimensional point (x, y) the same as the three dimenional point (x, y, 0.0).For each segment along the path 'wire' that starts with a unit tangent vector T, a unit vector N perpendicular to T is set to a unit vector in the direction T × (N′ × T), where N′ is the previous value of N. The initial value of N′ is the vector given by the argument inormal. For points along a 2 dimensional path, an affine transform maps a unit vector in the X direction to N, a unit vector in the Y direction to (N × T), and the point (0,0) to the ith point along the 3D path
wire
, excluding intermediate control points.Straight-line segments along the 'wire' path are handled specially: these are given a region that distinguishes these segments from those that precede them or follow them so that straight line segments in the 'wire' path correspond to cylindrical sections along the generated surface.
The normal vector is represented by an array containing the vector's X, Y and Z coordinates in that order, and its norm does not matter as long as it is not zero. The class
VectorOps
contains methods that can simplify the creation of normal vectors, specificallyVectorOps.createUnitVector3(double,double)
, which uses spherical coordinates.- Parameters:
wire
- a 3D path, either open or closedinormal
- the vector that provides an initial normal vector (ignored if a normal vector can be computed from the 'wire')- Returns:
- the mapper
- See Also:
-
transpose
Transpose a BezierGrid. This method returns a new grid with the U and V coordinates swapped. The transposed grid will be in the same state as the original. Because of the way orientations are determined, a transposed grid's orientation is opposite to that of the original grid.- Returns:
- the transposed grid
- Throws:
IllegalStateException
- the grid to be transposed was created as an extension to an existing grid or as a connection between existing grid boundaries; a user-defined spline was started but not finished
-
subgrid
Create a subgrid of this Bézier grid. A subgrid is never a closed grid in either the U or V directions, or both. The maximum size of a subgrid in either the U or V directions is the corresponding size of this grid. When this grid is not closed in the U direction and the size of this grid in the U direction is nu, then n ≤ nu-i. Similarly when this grid is not closed in the U direction and the size of this grid in the V direction is nv, then m ≤ nv-i. The indices (i, j) must satisfy i ∈ [0,nu) and j ∈ [0, nv). A subgrid will copy this grid's splines and will be 'frozen' (i.e., the subgrid's splines cannot be modified).While a subgrid can be used to isolate a portion of a grid for convenience, it's main purpose is to handle cases where the full grid is not well formed. For example, to create a Möbius strip that can be 3D printed, one can start with a template representing a rectangle, and apply an affine transformation to create copies at points along the strip:
The U values for a full grid cover an angular extent of of 4π so that corresponding points match at the ends and so that the splines in the U direction are cyclic. Because the V values follow a rectangle, the region for each point is set to the value of its V index, which forces all the edges in the V direction to be linear. Unfortunately, the full grid has multiple vertices that correspond to the same points, so this grid is not well formed. The use of a subgrid extracts a grid corresponding to an angular extent of 2π, which is just enough for the desired Möbius strip.int N = 64; int M = 4; Point3D[][] array = new Point3D[2*N][M]; Point3D[] template = new Point3D[M]; double r = 100.0; double width = 50.0; double height = 10.0; template[0] = new Point3D.Double(0.0, width/2, height/2); template[1] = new Point3D.Double(0.0, -width/2,height/2); template[2] = new Point3D.Double(0.0, -width/2,-height/2); template[3] = new Point3D.Double(0.0, width/2, -height/2); for (int i = 0; i < 2*N; i++) { double theta = (Math.PI * i)/N; double psi = (2 * Math.PI * i)/N; AffineTransform3D af = AffineTransform3D.getRotateInstance(0.0, 0.0, psi); af.translate(0.0, r, 0.0); af.rotate(0.0, theta, 0.0); for (int j = 0; j < M; j++) { array[i][j] = af.transform(template[j], null); } } BezierGrid grid = new BezierGrid(array, true, true); for (int i = 0; i < 2*N; i++) { for (int j = 0; j < M; j++) { grid.setRegion(i, j, j); } } BezierGrid mgrid = grid.subgrid(0, 0, N+1, M+1);
- Parameters:
i
- the U index for an index of this grid that will correspond to the index (0,0) for the subgridj
- the V index for an index of this grid that will correspond to the index (0,0) for the subgridn
- the number of grid points in the U direction for the subgridm
- the number of grid points in the V direction for the subgrid- Returns:
- the subgrid
-
getFullSplineU
public boolean getFullSplineU(int i, int j, double[] coords) Get all the control points for the spline connecting a point with indices (i, j) to a point with indices (i+1, j). The coords array will contain the initial, first, second, and final control points in that order. For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.Intermediate control points will be set along all grid segments as a side effect of calling this method.
- Parameters:
i
- the U indexj
- the V indexcoords
- and array to hold the results- Returns:
- true if the spline exists; false if it does not
-
getFullSplineV
public boolean getFullSplineV(int i, int j, double[] coords) Get all the control points for the spline connecting a point with indices (i, j) to a point with indices (i, j+1). The coords array will contain the initial, first, second, and final control points in that order. For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.Intermediate control points will be set along all grid segments as a side effect of calling this method.
- Parameters:
i
- the U indexj
- the V indexcoords
- an array to hold the results- Returns:
- true if the spline exists; false if it does not
-
getSplineU
public boolean getSplineU(int i, int j, double[] coords) Get the spline connecting a point with indices (i, j) to a point with indices (i+1, j). The coords array will contain the first, second, and final control points in that order, but not the initial control point. For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.Intermediate control points will be set along all grid segments as a side effect of calling this method.
- Parameters:
i
- the U indexj
- the V indexcoords
- and array to hold the results- Returns:
- true if the spline exists; false if it does not
-
getSplineV
public boolean getSplineV(int i, int j, double[] coords) Get the spline connecting a point with indices (i, j) to a point with indices (i, j+1). The coords array will contain the first, second, and final control points in that order, but not the initial control point. For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.Intermediate control points will be set along all grid segments as a side effect of calling this method.
- Parameters:
i
- the U indexj
- the V indexcoords
- and array to hold the results- Returns:
- true if the spline exists; false if it does not
-
setSplineU
public boolean setSplineU(int i, int j, double[] coords) Set the spline connecting a point with indices (i, j) to a point with indices (i+1, j). The array must have a length of at least 6, and will contain the first and second control points, but not the initial or final control points (if the final point is present in the array, that value is ignored). For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.After this method is called, and successfully returns, splines cannot be defined by sequences of methods starting with calls to
startSpline(int,int)
and grid points cannot be modified (e.g, by callingsetPoint(int,int,Point3D)
.When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
This method returns false if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
, with its 'linear' argument set to true.- Parameters:
i
- the U indexj
- the V indexcoords
- the coordinates for the intermediate control points.- Returns:
- true if the spline is allowed for this point; false if it is not
- Throws:
IllegalArgumentException
- the coords array is too short or i and/or j are out of range
-
setLinearU
public boolean setLinearU(int i, int j) Set the spline connecting a point with indices (i, j) to a point with indices (i+1, j) so that the segment is a straight line. After this method is called, and successfully returns, splines cannot be defined by sequences of methods starting with calls tostartSpline(int,int)
and grid points cannot be modified (e.g, by callingsetPoint(int,int,Point3D)
.When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
This method merely calls
setSplineU(int,int,double[])
with the appropriate argument, and should be used when a linear segment will be attached to a planar triangle in order to ensure that the tessellation will work as expected: otherwise small floating-point errors can result in a surface that is not well formed.This method returns false if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
, with its 'linear' argument set to false.- Parameters:
i
- the U indexj
- the V index- Returns:
- true if the spline is allowed for this point; false if it is not
- Throws:
IllegalArgumentException
- i and/or j are out of range
-
setLinearV
public boolean setLinearV(int i, int j) Set the spline connecting a point with indices (i, j) to a point with indices (i, j+1) so that the segment is a straight line. After this method is called, and successfully returns, splines cannot be defined by sequences of methods starting with calls tostartSpline(int,int)
and grid points cannot be modified (e.g, by callingsetPoint(int,int,Point3D)
.When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
This method merely calls
setSplineV(int,int,double[])
with the appropriate argument, and should be used when a linear segment will be attached to a planar triangle in order to ensure that the tessellation will work as expected: otherwise small floating-point errors can result in a surface that is not well formed.This method returns false if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
, with its 'linear' argument set to true.- Parameters:
i
- the U indexj
- the V index- Returns:
- true if the spline is allowed for this point; false if it is not
- Throws:
IllegalArgumentException
- i and/or j are out of range
-
setSplineV
public boolean setSplineV(int i, int j, double[] coords) Set the spline connecting a point with indices (i, j) to a point with indices (i, j+1). The array must have a length of at least 6, and will contain the first and second control points, but not the initial or final control points (if the final point is present in the array, that value is ignored). For each control point, the array contains three successive values giving the control point's X, Y, and Z coordinates respectively.After this method is called, and successfully returns, splines cannot be defined by sequences of methods starting with calls to
startSpline(int,int)
and grid points cannot be modified (e.g, by callingsetPoint(int,int,Point3D)
.When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
This method returns false if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
. with its 'linear' argument set to true.- Parameters:
i
- the U indexj
- the V indexcoords
- and array to hold the results- Returns:
- true if the spline is allowed for this point; false if it is not
- Throws:
IllegalArgumentException
- the coords array is too short or i and/or j are out of range
-
setRemainingControlPoints
public boolean setRemainingControlPoints(int i, int j, double[] rest) throws IllegalArgumentException Set the remaining control points for a patch. The control points P11, P12, P21 and P22 are specified by an array (rest) of length 12, each stored so that the X value of a control point is followed by its Y value and in turn by its Z value, with the control points listed in the order shown.If this method is not called for a pair of indices or the control-point array is null, a default will be used to generate the missing control points.
When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double.
This method returns false if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
. with its 'linear' argument set to true.- Parameters:
i
- the U index, which must be in the range [0,N) where N is the largest allowable U indexj
- the V index, which must be in the range[0,M) where M is the largest allowable V indexrest
- an array holding the remaining control points; null if these should be cleared- Returns:
- true if a patch exists for this point; false if it does not
- Throws:
IllegalArgumentException
- an argument was out of range or the array was too small
-
getRemainingControlPoints
public boolean getRemainingControlPoints(int i, int j, double[] coords) throws IllegalArgumentException Get the remaining control points for a patch. The control points P11, P12, P21 and P22 are specified by an array (rest) of length 12, each stored so that the X value of a control point is followed by its Y value and in turn by its Z value, with the control points listed in the order shown.- Parameters:
i
- the U index, which must be in the range [0,N) where N is the largest allowable U indexj
- the V index, which must be in the range[0,M) where M is the largest allowable V indexcoords
- an array that will hold the remaining control points- Returns:
- true if a patch exists for this point with explicit values for the remaining control points; otherwise false
- Throws:
IllegalArgumentException
- if an argument was out of range or the array was too small
-
getPoint
Get the current value of a point on the grid.- Parameters:
i
- the U indexj
- the V index- Returns:
- the corresponding point; null if there is none
-
getPatch
public boolean getPatch(int i, int j, double[] coords) Get the coordinates for a cubic Bézier patch corresponding to the specified grid coordinates for this Bézier grid. The patch can be added directly to a surface: if this grid has its orientation reversed, that will not be reflected in the patch coordinates.- Parameters:
i
- the U index, which must be in the range [0,N) where N is the largest allowable U indexj
- the V index, which must be in the range[0,M) where M is the largest allowable V indexcoords
- an array of length 48 or larger that will hold the coordinates for a patch- Returns:
- true if patch coordinates can be computed; otherwise false
- Throws:
IllegalArgumentException
- the arguments are out of range or the coordinates array is too small
-
setPoint
public void setPoint(int i, int j, Point3D p) throws IllegalArgumentException, IllegalStateException Set a point on a grid. This method can be used to adjust the value of points on the grid. It must be called before any call to the methodssetSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
. If a grid point already exists, its cell's status (empty or filled) is unchanged. Otherwise its cell status is set to filled if the point is non null and empty if the point is null- Parameters:
i
- the U indexj
- the V indexp
- the point- Throws:
IllegalArgumentException
- an index was out of rangeIllegalStateException
- splines were previously set by calls tosetSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
- See Also:
-
setPatchCorners
public void setPatchCorners(int i, int j, double[] coords) throws IllegalArgumentException, IllegalStateException Set points at the corner of the cell associated with a grid location. For each corner, if a grid point already exists, its cell's status (empty or filled) is unchanged. Otherwise its cell status is set to filled.- Parameters:
i
- the U indexj
- the V indexcoords
- the control points.- Throws:
IllegalArgumentException
IllegalStateException
- See Also:
-
setPatch
public void setPatch(int i, int j, double[] coords) throws IllegalArgumentException, IllegalStateException Set control points for a cubic patch associated with a grid point. For each corner, if a grid point already exists, its cell's status (empty or filled) is unchanged. Otherwise its cell status is set to filled.This throws an exception if the grid is a linear grid: one created with the constructors
BezierGrid(int,boolean,int,boolean,boolean)
,BezierGrid(Point3D[][],boolean,boolean,boolean)
, orBezierGrid(double[],boolean,double[],boolean,boolean,RealValuedFunctTwoOps,RealValuedFunctTwoOps,RealValuedFunctTwoOps)
, with its 'linear' argument set to true.- Parameters:
i
- the U index of the grid pointj
- the V index of the grid pointcoords
- the control points.- Throws:
IllegalArgumentException
- if an argument is out of rangeIllegalStateException
- if a patch may not be set- See Also:
-
setPoint
public void setPoint(int i, int j, double x, double y, double z) throws IllegalArgumentException, IllegalStateException Set a point on a grid given x, y, and z coordinates for the point. This method can be used to adjust the value of points on the grid. It must be called before any call to the methodssetSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
.When stored, the coordinates provided will have their values rounded to the nearest 'float' value by first casting the values to a float and then to a double. If a grid point already exists, its cell's status (empty or filled) is unchanged. Otherwise its cell status is set to filled.
- Parameters:
i
- the U indexj
- the V indexx
- the point's X coordinatey
- the point's Y coordinatez
- the point's Z coordinate- Throws:
IllegalArgumentException
- the coords array is too short or i and j are out of rangeIllegalStateException
- splines were previously set by calls tosetSplineU(int,int,double[])
,setSplineV(int,int,double[])
, orsetRemainingControlPoints(int,int,double[])
-
startSpline
Indicate the starting indices for a user-defined spline. The indices i and j vary in the U and V directions respectively. For example for fixed j, the value when u = 1.0 and v = 0.0 at grid element (i, j) is the same as the value when = u 0.0 and v = 0.0 at grid element(i+1, j).- Parameters:
i
- the first indexj
- the second index- Throws:
IllegalArgumentException
- the coords array is too short or i and j are out of range- See Also:
-
moveV
public void moveV(int n) Add elements to a spline in the V direction. The current index will change from (i, j) to (i, j+n). The method does nothing if the argument is 0.- Parameters:
n
- a positive number when n elements are added to the spline in the positive V direction; a negative number when -n elements are added to the spline in the negative V direction- Throws:
IllegalArgumentException
- the argument was out of rangeIllegalStateException
- a spline has not been stated- See Also:
-
moveU
public void moveU(int n) Add elements to a spline in the U direction. The current index will change from (i, j) to (i+n, j). The method does nothing if the argument is 0.- Parameters:
n
- a positive number when n elements are added to the spline in the positive U direction; a negative number when -n elements are added to the spline in the negative U direction- Throws:
IllegalArgumentException
- the argument was out of rangeIllegalStateException
- a spline has not been stated- See Also:
-
endSpline
Assert that the end of a user-defined spline has been reached. For a non-cyclic spline, the current point for the spline is the end point of the spline. For a cyclic spline, points will be added in either the U or V direction, but not both, until the spline is completed- Parameters:
cyclic
- true if the spline is cyclic, false otherwise- Throws:
IllegalStateException
- if the spline is cyclic and cannot be completed by moving in the U direction or the V direction but not both, or if a spline has not been started- See Also:
-
print
public void print()Print the points on this grid. The output will first indicate if the grid is closed in the U and V directions. This will be followed by the string "grid:" followed by a series of lines showing each point as an ordered triplet of X, Y, and Z coordinates, or the string "(null)" if undefined. Each line corresponds to a successively higher U coordinate, with points on each line in ascending order for their V coordinates. This is followed by a line containing the string "spline status", followed by lines containing the strings- (uv) if a grid point has both U and V intermediate control points defined.
- (u ) if a grid point has only U intermediate control points defined.
- ( v) if a grid point has only V intermediate control points defined.
- ( ) if a grid point has no intermediate control points defined
- (F) if a grid point's cell is filled (i.e., part of a surface.)
- ( ) if a grid point's cell is not filled (in which case it is part of a boundary.)
- Throws:
RuntimeException
- an IO error occurred
-
print
Print the points on this grid, using an Appendable for output.This method calls
createSplines()
if it has not already been called, but the state is restored so thatcreateSplines()
can be called subsequently. There is, however, a side effect: the intermediate control points for each spline will be set.The output will first indicate if the grid is closed in the U and V directions. This will be followed by the string "grid:" followed by a series of lines showing each point as an ordered triplet of X, Y, and Z coordinates, or the string "(null)" if undefined. Each line corresponds to a successively higher U coordinate, with points on each line in ascending order for their V coordinates. This is followed by a line containing the string "spline status", followed by lines containing the strings
- (uv) if a grid point has both U and V intermediate control points defined.
- (u ) if a grid point has only U intermediate control points defined.
- ( v) if a grid point has only V intermediate control points defined.
- ( ) if a grid point has no intermediate control points defined
- (F) if a grid point's cell is filled (i.e., part of a surface.)
- ( ) if a grid point's cell is not filled (in which case it is part of a boundary.)
- Parameters:
out
- the output- Throws:
RuntimeException
- an IO error occurred
-
print
Print the points on this grid, specifying a prefix to be printed at the start of each line.This method calls
createSplines()
if it has not already been called, but the state is restored so thatcreateSplines()
can be called subsequently. There is, however, a side effect: the intermediate control points for each spline will be set. The output will first indicate if the grid is closed in the U and V directions. This will be followed by the string "grid:" followed by a series of lines showing each point as an ordered triplet of X, Y, and Z coordinates, or the string "(null)" if undefined. Each line corresponds to a successively higher U coordinate, with points on each line in ascending order for their V coordinates. This is followed by a line containing the string "spline status", followed by lines containing the strings- (uv) if a grid point has both U and V intermediate control points defined.
- (u ) if a grid point has only U intermediate control points defined.
- ( v) if a grid point has only V intermediate control points defined.
- ( ) if a grid point has no intermediate control points defined
- (F) if a grid point's cell is filled (i.e., part of a surface.)
- ( ) if a grid point's cell is not filled (in which case it is part of a boundary.)
- Parameters:
prefix
- the prefix- Throws:
RuntimeException
- an IO error occurred
-
print
Print the points on this grid, using an Appendable for output and specifying a prefix to be printed at the start of each line.This method calls
createSplines()
if it has not already been called, but the state is restored so thatcreateSplines()
can be called subsequently. There is, however, a side effect: the intermediate control points for each spline will be set.The output will first indicate if the grid is closed in the U and V directions. This will be followed by the string "grid:" followed by a series of lines showing each point as an ordered triplet of X, Y, and Z coordinates, or the string "(null)" if undefined. Each line corresponds to a successively higher U coordinate, with points on each line in ascending order for their V coordinates. This is followed by a line containing the string "spline status", followed by lines containing the strings
- (uv) if a grid point has both U and V intermediate control points defined.
- (u ) if a grid point has only U intermediate control points defined.
- ( v) if a grid point has only V intermediate control points defined.
- ( ) if a grid point has no intermediate control points defined
- (F) if a grid point's cell is filled (i.e., part of a surface.)
- ( ) if a grid point's cell is not filled (in which case it is part of a boundary.)
- Parameters:
prefix
- the prefixout
- the output- Throws:
RuntimeException
- an IO error occurred
-
printSplines
public void printSplines()Print the sequence of indices for explicitly added splines. The output will list the splines in the sequence in which they were defined, and whether the splines are cyclic or not. Sequences of index pairs in which more than one have an index in common are separated by " ... "; otherwise by ", ".- Throws:
RuntimeException
- an IO error occurred
-
printSplines
Print the sequence of indices for explicitly added splines to an Appendable The output will list the splines in the sequence in which they were defined, and whether the splines are cyclic or not. Sequences of index pairs in which more than one have an index in common are separated by " ... "; otherwise by ", ".- Parameters:
out
- the Appendable used for output.- Throws:
RuntimeException
- an IO error occurred
-
printSplines
Print the sequence of indices for explicitly added splines to an Appendable and with a prefix The output will list the splines in the sequence in which they were defined, and whether the splines are cyclic or not. Sequences of index pairs in which more than one have an index in common are separated by " ... "; otherwise by ", ". The prefix will typically be used in cases where extra indentation is useful.- Parameters:
prefix
- a prefix to place at the start of each lineout
- the Appendable used for output.- Throws:
RuntimeException
- an IO error occurred
-
badSplines
Test if a spline was created with inappropriate values. This method is intended for debugging. Note: if the X, Y, or Z coordinate of a point on the grid has the value Double.NaN, this method may report an error. One can check the values at adjacent points on the grid to help detect this condition.This method calls
createSplines()
if it has not already been called, but the state is restored so thatcreateSplines()
can be called subsequently. There is, however, a side effect: the intermediate control points for each spline will be set.- Parameters:
out
- the output to use for printing messages- Returns:
- true if a spline was created with inconsistent values; false if the splines are acceptable
- Throws:
RuntimeException
- an IO error occurred
-
traceSplines
Trace calls to createSpline, indicating which grid points have control points added to them. This method is useful primarily for debugging. If IO errors occur, the output will be silently dropped.- Parameters:
out
- an Appendable that will store the trace.
-
createSplines
Create all splines. A standard set of splines will be created first, followed by user-defined splines. If called more than once, the additional calls are ignored unless a vertex is changed or a new spline is added.When stored, the coordinates of control points will have their values rounded to the nearest float value by first casting a value as a float and then casting the result back to a double.
- Throws:
IllegalStateException
- a spline could not be created or was ill formed
-
reverseOrientation
Set the orientation of the patches. This method affects the orientation of patches provided by iterators. It does not change the values returned by calling methods such asgetFullSplineU(int,int,double[])
,getFullSplineV(int,int,double[])
,getSplineU(int,int,double[])
, orgetSplineV(int,int,double[])
.- Parameters:
reverse
- true if the orientation is the reverse of the one that was initially defined; false if the orientation is the same as the one that was initially defined.- Returns:
- this grid
-
flip
Reverse the orientation from the current orientation. This method affects the orientation of patches provided by iterators. It does not change the values returned by calling methods such asgetFullSplineU(int,int,double[])
,getFullSplineV(int,int,double[])
,getSplineU(int,int,double[])
, orgetSplineV(int,int,double[])
.When using the method {#transpose()}, the new grid's initial orientation is opposite to the current grid's initial orientation, but if the current grid is reversed, the new grid will be reversed as well. To force the new grid to have the same orientation as the current grid,
flip()
can be used.- Returns:
- this grid
-
isReversed
public boolean isReversed()Determine if the orientation for this grid is reversed.- Returns:
- true if the orientation is reversed; false if not
-
setRegion
public void setRegion(int i, int j, int id) Set a region ID. Regions represent collections of points whose boundaries terminate the implicitly generated splines so that the curves at the border of a region may not have continuous derivatives. A region is represented by an integer ID. Implicitly generated splines have constant indices in either the U or V directions, but not both. As the varying index increases, a spline terminates either when the maximum index is reached or at the first index for which the region ID changes. That index is also the one for the start of the next spline. All grid points are initialized to be in Region 0. This method must be used to change a point's region ID from this default.- Parameters:
i
- the index for the U directionj
- the index for the V directionid
- the region id- Throws:
IllegalArgumentException
- the arguments are out of range
-
setRegion
public void setRegion(int i, int j, int width, int height, int id) Set a region ID for a rectangle of grid points. Regions represent collections of points whose boundaries terminate the implicitly generated splines so that the curves at these locations may not have continuous derivatives. A region is represented by an integer ID. A region is represented by an integer ID. Implicitly generated splines have constant indices in either the U or V directions, but not both. As the varying index increases, a spline terminates either when the maximum index is reached or at the first index for which the region ID changes. That index is also the one for the start of the next spline. All grid points are initialized to be in Region 0. This method must be used to change a point's region ID from this default.- Parameters:
i
- the index for the start of the rectangle in the U directionj
- the index for the start of the rectangle in the V directionwidth
- the number of indices in the U directionheight
- the number of indices in the V dictionid
- the region id- Throws:
IllegalArgumentException
- if an argument was out of rangeIllegalStateException
- if called on a linear BezierGrid
-
remove
public void remove(int i, int j) Remove a patch. The indices (i, j) specify the point at u=0, v=0 for the corresponding patch. When a patch is removed, the patch is not used as part of a 3D shape, but its point (u=0, v=0) is used in creating splines.- Parameters:
i
- the index for the U directionj
- the index for the V direction
-
remove
public void remove(int i, int j, int width, int height) Remove a rectangle of patches The patches removed will have indices varying from i to i+width exclusive an j to j+height exclusive. both the width and the height must be non-negative. When a patch is removed, the patch is not used as part of a 3D shape, but its point (u=0, v=0) is used in creating splines.- Parameters:
i
- the index for the start of the rectangle in the U directionj
- the index for the start of the rectangle in the V directionwidth
- the number of indices in the U directionheight
- the number of indices in the V diction
-
restore
public void restore(int i, int j) Restore a patch. The indices (i, j) specify the point at u=0, v=0 for the corresponding patch. This reverses the effect of callingremove(int,int)
.- Parameters:
i
- the index in the U directionj
- the index in the V direction
-
restore
public void restore(int i, int j, int width, int height) Restore a rectangle of patches The patches restored will have indices varying from i to i+width exclusive an j to j+height exclusive. both the width and the height must be non-negative. This reverses the effect of callingremove(int,int,int,int)
.- Parameters:
i
- the index for the start of the rectangle in the U directionj
- the index for the start of the rectangle in the V directionwidth
- the number of indices in the U directionheight
- the number of indices in the V diction
-
getSurfaceIterator
Description copied from interface:Shape3D
Get a surface iterator for this Shape3D. The surface iterator will represent the shape as a sequence of Bézier patches and Bézier triangles, with the order of the sequence arbitrary.Unless the transform is an affine transform, the transformation is not exact. In this case, the patches and triangles that constitute the surface should be small enough that the transform can be approximated by an affine transform over the region containing the control points.
- Specified by:
getSurfaceIterator
in interfaceShape3D
- Parameters:
tform
- a transform to apply to each control point; null for the identity transform- Returns:
- a surface iterator
-
getSurfaceIterator
Description copied from interface:Shape3D
Get a surface iterator for this Shape3D, subdividing the surface. The surface iterator will represent the shape as a sequence of Bézier patches and Bézier triangles, with the order of the sequence arbitrary.Unless the transform is an affine transform, the transformation is not exact. In this case, the patches and triangles that constitute the surface after each is subdivided should be small enough that the transform can be approximated by an affine transform over the region containing the control points.
- Specified by:
getSurfaceIterator
in interfaceShape3D
- Parameters:
tform
- a transform to apply to each control point; null for the identity transformlevel
- the number of levels of partitioning (each additional level splits the previous level into quarters)- Returns:
- a surface iterator
-
numberOfComponents
public int numberOfComponents()Description copied from interface:Shape3D
Get the number of components for this shape. Components are connected shapes - surfaces for which every point can connect to any other point.- Specified by:
numberOfComponents
in interfaceShape3D
- Returns:
- the number of components for this shape
-
getComponent
Description copied from interface:Shape3D
Get a component of this shape. Components are connected shapes - surfaces for which every point can connect to any other point. The components are referenced by an index, specified as an integer in the range [0,n), where n is the number of manifold components. If n is zero, no index is valid.- Specified by:
getComponent
in interfaceShape3D
- Parameters:
i
- the component's index- Returns:
- a model containing the specified component
- See Also:
-
isWellFormed
public boolean isWellFormed()Determine if the grid is well formed- Returns:
- true if the grid is well formed; false otherwise
-
isWellFormed
Determine if the grid is well formed, logging error messages to an Appendable- Parameters:
out
- an Appendable for logging error messages- Returns:
- true if the grid is well formed; false otherwise
-
createConnectionsTo
Create Bézier grids that will connect this grid to a specified grid. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes is 2. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid.- Parameters:
grid
- the grid to which this grid should be connected.- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.
-
createConnectionsTo
Create Bézier grids, with a specified number of vertices in the 'U' direction, that will connect this grid to a specified rid. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes is n. For their V axes, the number varies, with each grid matching part of a boundary of this grid.- Parameters:
grid
- the grid to which this grid should be connected.n
- the number of vertices for the connecting grids along their U axes- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.
-
createConnectionsTo
public BezierGrid[] createConnectionsTo(BezierGrid grid, boolean split) throws IllegalStateException Create Bézier grids that will connect this grid to a specified grid, optionally splitting the returned grids into multiple grids. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes is 2. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid when the argumentsplit
is false. Whensplit
is true, the number of grids is the number of splines that make up the boundary.When the 'split' argument has the value true, and intermediate control points for a grid's edges in the 'U' direction are explicitly modified, one may have to add additional B@eacute;zier patches if the grids are to be connected to each other. The typical case for setting 'split' to true is when adding such patches is desired.
- Parameters:
grid
- the grid to which this grid should be connected.split
- true if there can be multiple grids per boundary component; false otherwise- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.
-
createConnectionsTo
public BezierGrid[] createConnectionsTo(BezierGrid grid, boolean split, int... indices) throws IllegalStateException Create Bézier grids that will connect this grid to a specified grid, optionally splitting the returned grids into multiple grids, and restricting the returned grids to ones that match a specified boundary. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes is 2. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid when the argumentsplit
is false. Whensplit
is true, the number of grids is the number of splines that make up the boundary.When the 'split' argument has the value true, and intermediate control points for a grid's edges in the 'U' direction are explicitly modified, one may have to add additional Bézier patches if the grids are to be connected to each other. The typical case for setting 'split' to true is when adding such patches is desired.
The final arguments are pairs of U-V indices indicating vertices that are part of this grid's boundary. Those boundary components that match any of these pairs will be connected by the generated grids, whereas other boundary components will not be connected.
- Parameters:
grid
- the grid to which this grid should be connected.split
- true if there can be multiple grids per boundary component; false otherwiseindices
- a sequence of pairs of U and V indices respectively for vertices along components of this grid's boundary- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.
-
createConnectionsTo
Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis and optionally splitting the returned grids into multiple grids. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes must be at least 2 and is specified by this method's second argument. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid when the argumentsplit
is false. Whensplit
is true, the number of grids is the number of splines that make up the boundary.When the 'split' argument has the value true, and either the intermediate control points for a grid's edges in the 'U' direction are explicitly modified or the number of vertices in the U direction are larger than two, one may have to add additional Bézier patches if the grids are to be connected to each other. The typical case for setting 'split' to true is when adding such patches is desired.
- Parameters:
grid
- the grid to which this grid should be connected.n
- the number of vertices along the U axis for each of the grids that this method createssplit
- true if there can be multiple grids per boundary component; false otherwise- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.
-
createConnectionsTo
public BezierGrid[] createConnectionsTo(BezierGrid grid, int n, boolean split, int... indices) throws IllegalStateException, IllegalArgumentException Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis, optionally splitting the returned grids into multiple grids, and specifying pairs of indices for vertices along allowed boundaries. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes must be at least 2 and is specified by this method's second argument. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid when the argumentsplit
is false. Whensplit
is true, the number of grids is the number of splines that make up the boundary.When the 'split' argument has the value true, and either the intermediate control points for a grid's edges in the 'U' direction are explicitly modified or the number of vertices in the U direction are larger than two, one may have to add additional Bézier patches if the grids are to be connected to each other. The typical case for setting 'split' to true is when adding such patches is desired.
The final arguments are pairs of U-V indices indicating vertices that are part of this grid's boundary. Those boundary components that match any of these pairs will be connected by the generated grids, whereas other boundary components will not be connected. For each grid that is generated the 'V' index of the generated grid will increase as one traverses along the boundary from the starting point specified by the indices, and the u=0 edge of each generated grid will match its corresponding boundary.
- Parameters:
grid
- the grid to which this grid should be connected.n
- the number of vertices along the U axis for each of the grids that this method createssplit
- true if there can be multiple grids per boundary component; false otherwiseindices
- a sequence of pairs of U and V indices respectively for vertices along components of this grid's boundary- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.IllegalArgumentException
-
createConnectionsTo
public BezierGrid[] createConnectionsTo(BezierGrid grid, int n, boolean split, boolean exclude, int... indices) throws IllegalStateException, IllegalArgumentException Create Bézier grids that will connect this grid to a specified grid, specifying the number of vertices along a connecting grid's U axis and optionally splitting the returned grids into multiple grids, and specifying pairs of indices for vertices along allowed or disallowed boundaries. The indices of matching vertices on the boundaries of the two grids must be the same. The number of vertices for the connecting grids along their U axes must be at least 2 and is specified by this method's second argument. For their V axes, the number varies, with each grid matching part of a boundary of this grid. The number of grids that are returned equals the number of disjoint curves that make up the boundary of this grid when the argumentsplit
is false. Whensplit
is true, the number of grids is the number of splines that make up the boundary.When the 'split' argument has the value true, and either the intermediate control points for a grid's edges in the 'U' direction are explicitly modified or the number of vertices in the U direction are larger than two, one may have to add additional Bézier patches if the grids are to be connected to each other. The typical case for setting 'split' to true is when adding such patches is desired.
The final arguments are pairs of U-V indices indicating vertices that are either part of this grid's boundary or part of this grid's boundary that are excluded. When the 'exclude' argument is false, those boundary components that match any of these pairs will be connected to the generated grids, whereas other boundary components will not be connected. For the ones that are connected, the u=0 edge of the generated grid will match the corresponding boundary of this grid. The u=0, v= 0 corner of each generated grid will match the point on this grid's boundary corresponding to the specified pair of indices. When the 'exclude' argument is 'true', the indices indicate which component of the boundary are not connected, and in this case the starting point for the boundary is not specified and will in general be hard to predict.
- Parameters:
grid
- the grid to which this grid should be connected.n
- the number of vertices along the U axis for each of the grids that this method createssplit
- true if there can be multiple grids per boundary component; false otherwiseexclude
- true if each pair of indices denotes a vertex along a component of the boundary that is excluded; false if each pair of indices denotes a vertex along a component of the boundary that is includedindices
- a sequence of pairs of U and V indices respectively for vertices along components of this grid's boundary- Returns:
- the grids that will connect corresponding components of boundaries of this grid and the specified grid
- Throws:
IllegalStateException
- this grid is not well formed or its boundary cannot be computed.IllegalArgumentException
-
createExtensionGrid
public BezierGrid createExtensionGrid(Point3DMapper<Point3D> mapping, int[] regionChanges, int n, int uIndex, int vIndex) throws IllegalStateException, IllegalArgumentException Create an extension to a Bézier grid based on a mapping function. This method creates a new BezierGrid. The number of grid elements in the new grid's V direction are determined by a component of the boundary of this grid. That component will a closed, continuous path that passes through the grid point whose U-V indices are (uIndex, vIndex). If the point at (uIndex, vIndex) is not on the boundary, null is returned; Otherwise the boundary that is used is the component of the full boundary that contains the point corresponding to (uIndex, vIndex). This component will be shifted so that it's first segment (its SEG_MOVETO segment) has coordinates equal to the value of the grid point corresponding to the indices (uIndex, vIndex). This point will be located at indices (0,0) in the extension grid, with increasing V values following the boundary.The grid returned will be frozen. The grid points and intermediate control points in the V direction are determined by the mapping function. Splines determine the intermediate control points in the U direction. For a fixed value of V, splines in the U direction or terminated or started at U indices specified by the second argument (regionChanges).
The mapping function takes the following arguments:
- i. This argument is the index in the U direction. Its values are in the range (0, n).
- p. This argument is a grid point for which U is zero.
- p1. This argument is optional. When present, the argument p is a control point that is not end point of a segment that is part of the boundary. p1 will be the starting point of the segment containing p.
- p2. This argument is optional. When present, the argument p is a control point that is not an end point of a segment that is part of the boundary. p2 will be the ending point of the segment containing p.
- Parameters:
mapping
- the mapping functionregionChanges
- a list of indices for the U direction for which the grid that is created changes regions (this argument is an array that may be modified by sorting it into ascending order).n
- the number of grid points in the U directionuIndex
- the U-direction index for a point on this grid that is part of this grid's boundary.vIndex
- the V-direction index for a point on this grid that is part of this grid's boundary.- Returns:
- a BezierGrid; null if (uIndex, vIndex) is not on a boundary.
- Throws:
IllegalStateException
IllegalArgumentException
-
getBoundary
Description copied from interface:Shape3D
Get the boundary for this Shape3D. For a closed surface, the boundary will be an empty path.Typically, a boundary will consist of a series of distinct closed subpaths. Subpaths are separated by segments whose type is {link PathIterator3D#SEG_MOVETO}. For a closed manifold, the boundary will be an empty path.
- Specified by:
getBoundary
in interfaceShape3D
- Returns:
- the boundary of this surface; null if a boundary cannot be computed
- See Also:
-
getBoundary
Get the boundary components that pass through specific grid points. The indices that are specified are pairs of indices giving the U-index and V-index respectively for a point on the grid. The path returned will consist of a concatenation of these boundary components, each modified so it starts at the point corresponding to a pair of indices. The order of these components may not be same as the order of the index pairs.- Parameters:
indices
- the indices- Returns:
- the boundary components, concatenated into a single path
- Throws:
IllegalStateException
IllegalArgumentException
-
isClosedManifold
public boolean isClosedManifold()Description copied from interface:Shape3D
Determine if this Shape3D is a closed two-dimensional manifold.- Specified by:
isClosedManifold
in interfaceShape3D
- Returns:
- true if the surface is a closed two-dimensional manifold; false otherwise
-
getBounds
Description copied from interface:Shape3D
Get a bounding rectangular cuboid for a 3D shape. The edges will be aligned with the X, Y and Z axes. The cuboid created may not be the smallest one possible (for example, shapes defined by Bézier surfaces may just use the control points to determine the cuboid as the convex hull for the control points includes all of the surface for parameters in the normal range [0,1]). -
isOriented
public boolean isOriented()Description copied from interface:Shape3D
Determine if a surface is oriented.- Specified by:
isOriented
in interfaceShape3D
- Returns:
- true if the surface has an orientation; false if it does not
-
setColor
Set the color for all patches on this grid.- Parameters:
c
- the color; null if a color is not specified
-
setColor
Set the color for a patch on this grid. The indices must be non-negative. For an index pair (i,j), i must be less than the number of U values on the grid and j must be less than the number of V values on the grid. Indices start at 0.- Parameters:
i
- the index for the U directionj
- the index for the V directionc
- the color; null if a color is not specified- Throws:
IllegalArgumentException
- an integer argument was out of range
-
setColor
Set the color for all patches on this grid. The indices must be non-negative. For an index pair (i,j), i must be less than the number of U values on the grid and j must be less than the number of V values on the grid. Indices start at 0. Both w and h must be non-negative. In addition, the values of i+w and j+h must not exceed the number of grid points in the U and V directions respectively.- Parameters:
i
- the index for the U directionj
- the index for the V directionw
- the number of indices in the U directionh
- the number of indices in the V dictionc
- the color; null if a color is not specified- Throws:
IllegalArgumentException
- an integer argument was out of range
-