net.algart.drawing3d
Class ConvexPlanePolygon3DDrawingRule

java.lang.Object
  extended by net.algart.drawing3d.ConvexPlanePolygon3DDrawingRule
All Implemented Interfaces:
DrawingRule

public class ConvexPlanePolygon3DDrawingRule
extends java.lang.Object
implements DrawingRule

Algorithm of drawing convex plane polygon, placed in 3D space (PlanePolygon3D object). This algorithm visits all pixels (X, Y) of the projection of this polygon to the screen plane and calls Pixel3DDrawer.drawPoint method for the point of intersection of the plane of the polygon ax+by+cz=d and the straight line x=X, y=Y, −∞<z<+∞. This algorithm works normally only if the polygon is convex.

This class is immutable and thread-safe: there are no ways to modify settings of the created instance.

AlgART Laboratory 2010

Since:
JDK 1.5
Version:
1.0
Author:
Daniel Alievsky

Constructor Summary
Constructor and Description
ConvexPlanePolygon3DDrawingRule()
           
 
Method Summary
Modifier and Type Method and Description
 void draw(Shape3D shape, Pixel3DDrawer pixelDrawer, CoordinateSystem3D coordinateSystemOfModel, java.awt.geom.Rectangle2D screenArea, double zCut, java.awt.Color color)
          Draws the specified 3D figure (shape), i.e. calls pixelDrawer.drawPoint method for every screen pixel and all corresponding points of the surface ot this figure.
 void estimateContainingParallelepiped(double[] result, Shape3D shape, CoordinateSystem3D coordinateSystemOfModel)
          Returns, in first 6 elements of result argument, the minimal and maximal x-coordinate, the minimal and maximal y-coordinate, the minimal and maximal z-coordinate of all drawable points of the specified 3D figure (shape), in the specified order.
 boolean isApplicable(Shape3D shape, java.lang.Object item)
          Checks whether this drawing rule is applicable to the given figure (shape), i.e. this drawing rule "knows" how to draw it.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ConvexPlanePolygon3DDrawingRule

public ConvexPlanePolygon3DDrawingRule()
Method Detail

isApplicable

public boolean isApplicable(Shape3D shape,
                            java.lang.Object item)
Description copied from interface: DrawingRule
Checks whether this drawing rule is applicable to the given figure (shape), i.e. this drawing rule "knows" how to draw it. If this method returns false, you should not call other methods of this interface for this shape: they can throw an exception. If this method returns true, you can freely use other methods with the same shape.

This method is used by Drawer3D.draw(java.util.Collection) for choosing the algorithm for drawing every object.

The item argument contains the reference to the source object (item), which was transformed to Shape3D by some shaping rule for drawing by this algorithm. It can be used to restrict the set of objects, to which this drawing algorithm should be applied: this method can return false for some kind of items, so the draw method of this instance will not be called for them. The implementations of this interface, provided by this package, ignore this argument.

Both arguments of this method can be null. If shape argument is null, this method returns false.

Specified by:
isApplicable in interface DrawingRule
Parameters:
shape - the 3D figure which you want to draw; can be null, then this method returns false.
item - the source object which you want to draw as the given figure; can be null.
Returns:
true if this drawing rule can be used for this object.

draw

public void draw(Shape3D shape,
                 Pixel3DDrawer pixelDrawer,
                 CoordinateSystem3D coordinateSystemOfModel,
                 java.awt.geom.Rectangle2D screenArea,
                 double zCut,
                 java.awt.Color color)
Description copied from interface: DrawingRule
Draws the specified 3D figure (shape), i.e. calls pixelDrawer.drawPoint method for every screen pixel and all corresponding points of the surface ot this figure. All coordinates, describing the real surface of the figure, are supposed to be given in the specified coordinateSystemOfModel: see comments to the interface.

While calling drawPoint(int x, int y, double z, double nx, double ny, double nz, Color color) method, this method passes to it the coordinates x, y, z of each surface point in the screen coordinate system. More precisely, let's consider some screen pixel with integer coordinates X, Y and an infinite prism X−½<x<X, Y−½<y<Y, −∞<z<+∞. The intersection of this prism and the surface of the drawn figure (shape) consists of 0 or more connected "pieces" — little surfaces σ1, σ2, ..., σm. There is a guarantee that this method calls drawPoint at least 1 time (but maybe several times) for each such "piece" σk with arguments x=Math.round(x)=X, y=Math.round(y)=Y, z=z, where (x, y, z)∈σk is some point of that "piece". If the central straight line x=X, y=Y of the prism does not intersects the figure, drawPoint method can be not called for the given (X, Y) pair at all, even if the prism little intersects the figure.

The nx, ny, nz arguments of drawPoint are equal to the components of the unit normal vector n=(nx,ny,nz) of the drawn surface at the corresponding point (x, y, z)∈σk, for which it is called. The color argument of drawPoint is equal to the color argument of this method.

The described algorithm is the simplest way of drawing 3D surface. A concrete way, how the surface will be drawn, for example, how the light falls to the surface, depends on Pixel3DDrawer implementation. For example, the standard Z-buffer algorithm, offered by SimpleDrawer3D.getSimpleDrawer3D method, draws only the "top" part of the surface (nearest to the observer), i.e. from all points with given integer X, Y only the one with maximal z-coordinate is really drawn, and it is supposed that the light falls along z axis from the side of the user — the color is multiplied by Math.abs(nz).

The drawn area is restricted by screenArea rectangle: only pixels, lying inside the area screenArea.getMinX()xscreenArea.getMaxX(), screenArea.getMinY()yscreenArea.getMaxY(), should be drawn. But it is not a strict requirement: this method may draw pixels outside this area, if the drawn figure does not fully lie inside it. This argument should be used for optimization needs: for example, it allows quickly returning if the figure lies fully outside the required area.

This method must draw only the part of the 3D figure, lying (in terms of the screen coordinate system) "behind" the plane z=zcut (i.e. in area zzcut), specified by zCut argument. In other words, this argument allows to "dissect" drawn object by some plane and to see only parts "behind" this plane, and to hide (not to draw at all) the objects which are fully "in front of" this plane (z>zcut). Usually, this feature is used by GUI to allow seeing a cut set of a complex 3D configuration. You can specify zCut=Double.POSITIVE_INFINITY, if you don't want to use this feature.

The pixels of the "dissected" figure can be drawn with maximal brightness (1.0 value of the brightness argument of drawPoint method) — it corresponds to showing a plane section of a solid 3D body. But also the drawing rule can show the internal surface of the figure "behind" this place — if corresponds to dissection of a hollow 3D body. The first variant ("solid body") is used by Sphere3DDrawingRule, the second one (drawing surface only) is used by ConvexPlanePolygon3DDrawingRule.

This method works normally, only if this object "knows", how to draw this kind of 3D figures. You can be sure that it is true, if DrawingRule.isApplicable(Shape3D, Object) method returns true for this shape and some 2nd argument. In this case, this method does not throw any exceptions, excepting NullPointerException (when one of the arguments is null). But if this object does not "know", how to draw this kind of 3D figures, this method can throw ClassCastException or other unexpected runtime exceptions.

Specified by:
draw in interface DrawingRule
Parameters:
shape - the drawn 3D figure.
pixelDrawer - the object which will be used for drawing each pixel.
coordinateSystemOfModel - the coordinate system of the model, in which the passed 3D figure is represented.
screenArea - the screen area, inside which the figure should be drawn (for optimization needs only).
zCut - z-coordinates of the section plane: only points with zzCut should be drawn.
color - the color of the drawn figure.
See Also:
Drawer3D.draw(java.util.Collection)

estimateContainingParallelepiped

public void estimateContainingParallelepiped(double[] result,
                                             Shape3D shape,
                                             CoordinateSystem3D coordinateSystemOfModel)
Description copied from interface: DrawingRule
Returns, in first 6 elements of result argument, the minimal and maximal x-coordinate, the minimal and maximal y-coordinate, the minimal and maximal z-coordinate of all drawable points of the specified 3D figure (shape), in the specified order. In other words, this method estimates a circumscribed parallelepiped of this figure. The resulting coordinates are returned in the screen coordinate system, and coordinateSystemOfModel argument is used for conversion of coordinates from the model coordinate system, as described in the comments to the interface.

There is no guarantee that the returned coordinate limits will be precise: they can be just an estimation. But, in any case, the returned parallelepiped fully contains the specified figure. Usually, this method helps GUI modules to determine a suitable range of possible zCut arguments for draw method.

This method works normally, only if this object "knows", how to draw this kind of 3D figures. You can be sure that it is true, if DrawingRule.isApplicable(Shape3D, Object) method returns true for this shape and some 2nd argument. But if this object does not "know", how to draw this kind of 3D figures, this method can throw ClassCastException or other unexpected runtime exceptions.

Specified by:
estimateContainingParallelepiped in interface DrawingRule
Parameters:
result - Java-array for storing results.
shape - the 3D figure (that should be probably drawn by draw method).
coordinateSystemOfModel - the coordinate system in which the figure should be drawn.
See Also:
Drawer3D.estimateContainingParallelepiped(double[], java.util.Collection)