net.algart.drawing3d
Class SimpleDrawer3D

java.lang.Object
  extended by net.algart.drawing3d.Drawer3D
      extended by net.algart.drawing3d.SimpleDrawer3D
All Implemented Interfaces:
Pixel3DDrawer

public class SimpleDrawer3D
extends Drawer3D

Simple full implementation of Drawer3D class, based on the traditional Z-buffer algorithm.

This implementation supports antialiasing scale α — some integer number in 1..MAX_ANTIALIASING_SCALE range. The size of the screen, where all 3D figures are drawn, can be greater than the sizes of returned BufferedImage: namely,

screenWidth = α * imageWidth,
screenHeight = α * imageHeight,

where imageWidth=getImageWidth() and imageHeight=getImageHeight() are the sizes of the really built BufferedImage. The getImage() method builds the returned image by compression of the internal picture, stored in this object and drawn by draw method, in α times. It is the simplest way provide antialiasing effect — better quality of the resulting picture, if there is enough RAM and the speed of building result is suitable.

This class is not thread-safe, but is thread-compatible and can be synchronized manually if multithread access is necessary.

AlgART Laboratory 2010

Since:
JDK 1.5
Version:
1.0
Author:
Daniel Alievsky

Field Summary
Modifier and Type Field and Description
static int MAX_ANTIALIASING_SCALE
          The maximal allowed value of antialiasingScale argument of getSimpleDrawer3D method: 2048.
 
Fields inherited from class net.algart.drawing3d.Drawer3D
screenHeight, screenWidth, zCut
 
Method Summary
Modifier and Type Method and Description
 void clearRect(int left, int top, int width, int height)
          Clears (reinitialize) the rectangular area leftx<left+width, topy<top+height.
 void drawPoint(int x, int y, double z, double nx, double ny, double nz, java.awt.Color color)
          Draws 1 pixel (point) of the surface of some 3D figure.
 int getAntialiasingScale()
          Returns the antialiasing scale α, specified while creating this object.
 java.awt.image.BufferedImage getImage()
          Transforms the current picture, built on the virtual screen by this object, into a buffered image, and returns it.
 int getImageHeight()
          Returns the height of the image, built by Drawer3D.getImage() method.
 int getImageWidth()
          Returns the width of the image, built by Drawer3D.getImage() method.
static SimpleDrawer3D getSimpleDrawer3D(int imageWidth, int imageHeight, int antialiasingScale, java.awt.Color backgroundColor, java.util.List<ShapingRule> shapingRules, java.util.List<ColoringRule> coloringRules, java.util.List<DrawingRule> drawingRules)
          Creates new instance of this class.
 
Methods inherited from class net.algart.drawing3d.Drawer3D
draw, draw, estimateContainingParallelepiped, gammaCorrection, getBackgroundColor, getColor, getColoringRules, getCoordinateSystem, getDrawingRule, getDrawingRules, getGamma, getScreenHeight, getScreenWidth, getShape, getShapingRules, getZCut, setBackgroundColor, setColoringRules, setColoringRules, setCoordinateSystem, setDrawingRules, setDrawingRules, setGamma, setShapingRules, setShapingRules, setZCut
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

MAX_ANTIALIASING_SCALE

public static final int MAX_ANTIALIASING_SCALE
The maximal allowed value of antialiasingScale argument of getSimpleDrawer3D method: 2048.

See Also:
Constant Field Values
Method Detail

getSimpleDrawer3D

public static SimpleDrawer3D getSimpleDrawer3D(int imageWidth,
                                               int imageHeight,
                                               int antialiasingScale,
                                               java.awt.Color backgroundColor,
                                               java.util.List<ShapingRule> shapingRules,
                                               java.util.List<ColoringRule> coloringRules,
                                               java.util.List<DrawingRule> drawingRules)
Creates new instance of this class.

The passed collections are copied into newly created lists: no references to them are maintained by the created object.

Parameters:
imageWidth - the width of the image screen, returned by getImage() method: result of getImageWidth(). Cannot be changed in future.
imageHeight - the height of the image screen, returned by getImage() method: result of getImageHeight(). Cannot be changed in future.
antialiasingScale - the antialiasing scale α: the (virtual) screen, where this object will build 3D image, will have sizes (α*imageWidth) x (α*imageHeight). Cannot be changed in future.
backgroundColor - the background color, which will be used by clearRect(int, int, int, int) method. After creation, all screen is filled by this color.
shapingRules - the set of shaping rules, which will be used by draw method.
coloringRules - the set of coloring rules, which will be used by draw method.
drawingRules - the set of drawing rules, which will be used by draw method.
Returns:
new instance of this class.
Throws:
java.lang.NullPointerException - if some of the arguments is null, or if one of rules in the passed collections is null.
java.lang.IllegalArgumentException - if imageWidth<0 or imageHeight<0, or if antialiasingScale=α is out of 1..MAX_ANTIALIASING_SCALE range, or if one of products imageWidth * α, imageHeight * α or imageWidth * imageHeight * α² (full size of the virtual screen) is greater than Integer.MAX_VALUE.

getAntialiasingScale

public int getAntialiasingScale()
Returns the antialiasing scale α, specified while creating this object.

Returns:
the antialiasing scale α.

getImageWidth

public int getImageWidth()
Description copied from class: Drawer3D
Returns the width of the image, built by Drawer3D.getImage() method.

Specified by:
getImageWidth in class Drawer3D
Returns:
the width of the image, built by Drawer3D.getImage() method.

getImageHeight

public int getImageHeight()
Description copied from class: Drawer3D
Returns the height of the image, built by Drawer3D.getImage() method.

Specified by:
getImageHeight in class Drawer3D
Returns:
the height of the image, built by Drawer3D.getImage() method.

clearRect

public void clearRect(int left,
                      int top,
                      int width,
                      int height)
Description copied from interface: Pixel3DDrawer
Clears (reinitialize) the rectangular area leftx<left+width, topy<top+height. After this call, this object will be in the same state, as when drawPoint was never called for integer pairs (x,y) in this area, and this area is filled by some default background color.

The implementation, provided by SimpleDrawer3D.getSimpleDrawer3D method, initializes Z-buffer for this area by default −∞ values.

If the specified area is out of ranges of the screen (i.e. some coordinates are <0 or ≥width/height of the image, which should be built as a result), the extra pixels are ignored. In particular, you can specify left=top=0, width=height=MAX_VALUE to reinitialize all drawable area. If width≤0 or height≤0, this method does nothing.

Specified by:
clearRect in interface Pixel3DDrawer
Specified by:
clearRect in class Drawer3D
Parameters:
left - the minimal x-coordinate of the cleared area.
top - the minimal y-coordinate of the cleared area.
width - the width of the cleared area.
height - the height of the cleared area.

drawPoint

public void drawPoint(int x,
                      int y,
                      double z,
                      double nx,
                      double ny,
                      double nz,
                      java.awt.Color color)
Description copied from interface: Pixel3DDrawer
Draws 1 pixel (point) of the surface of some 3D figure. It is the basic primitive, on the base of which DrawingRule.draw method is implemented.

The coordinates of the pixel are specified in the coordinate system of the computer screen: the x-axis is directed to the right (in the screen plane), the y-axis is directed downwards (in the screen plane) and the z-axis is directed from the screen to the user. The top left corner of the screen image, which should be built as a result, has coordinates x=0, y=0, z=+∞.

x and y coordinates, passed to this method, specify the pixel of the resulting image, which should be built (from 0 to the image width−1 or height−1). The resulting color of the pixel (x,y) of that image depends on the full series of calls of this method, in which these x, y coordinates were passed.

z-coordinate, passed to this method, is compared with z-coordinates of other points, which were probably drawn by this method at the same (x,y) coordinates. The simplest implementation can just overwrite the color of this pixel, if the passed z is greater than z-coordinates of all previous calls with same (x,y), or preserve the previous color if not — it is the known "Z-buffer" algorithm. But other implementations are also possible: for example, the new color can be combined with the previous color at (x,y) position, to provide an effect of translucency. The implementation, provided by SimpleDrawer3D.getSimpleDrawer3D method, uses the described simple Z-buffer algorithm.

The color argument specifies the color of the drawn point of the 3D surface. But this color is used directly only in a case, when the surface is perpendicular to the rays of the light. In other case, the color should be made darker. To provide this behavior, this method has additional arguments nx, ny, nz, equal to the components of the unit normal vector n=(nx,ny,nz) of the drawn surface. An implementation can use this information to reduce the brightness according to some lighting model. The implementation, provided by SimpleDrawer3D.getSimpleDrawer3D method, multiplies all R, G, B components of the color by Math.abs(nz) — it corresponds to the light rays, falling along z axis from the side of the user (observer). Note: the normal vector is supposed to be unit, i.e. nx²+ny²+nz²=1.0.

The alpha component of the passed color affects the transparency. It is guaranteed, that if color.getAlpha()==0, then this pixel is not drawn (the method does nothing), and if color.getAlpha()==0, then it means normal drawing. Other values 1–254 can affect the transparency, but it is not guaranteed. The implementation, provided by SimpleDrawer3D.getSimpleDrawer3D method, uses 1–254 values for mixing the passed color with previously drawn color, which partially emulates translucency. But note that this feature does not really provide correct translucency, because that implementation is based on a simple Z-buffer algorithm and does nothing if z argument is less than z-coordinates of the previously drawn pixel.

If x or y arguments are out of ranges of the screen (i.e. <0 or ≥width/height of the image), this method does nothing. Besides this, the object can support some zcut limit and ignore calls with z>zcut: it allows creating "cut sets" of a complex 3D configuration (this limit is really supported by Drawer3D class).

Specified by:
drawPoint in interface Pixel3DDrawer
Specified by:
drawPoint in class Drawer3D
Parameters:
x - x-coordinate of the point.
y - y-coordinate of the point.
z - z-coordinate of the point.
nx - x-component of the unit normal vector of the drawn surface at this point.
ny - y-component of the unit normal vector of the drawn surface at this point.
nz - z-component of the unit normal vector of the drawn surface at this point.
color - the color of drawn surface point.

getImage

public java.awt.image.BufferedImage getImage()
Description copied from class: Drawer3D
Transforms the current picture, built on the virtual screen by this object, into a buffered image, and returns it. Usually the pixels of the returned buffered image precisely corresponds to the picture, built by clearRect and drawPoint methods of this object, but some little transformation, like scaling, is possible: for example, SimpleDrawer3D implementation automatically compresses the image in getAntialiasingScale() times.

Further drawing in this object will not affect the returned image, but the further calls of this method can change it. (For example, SimpleDrawer3D implementation uses for building a buffered image the separate memory, allocated only once, and does not reallocate it in this method.)

Specified by:
getImage in class Drawer3D
Returns:
the buffered image with the picture, built in this object.
See Also:
Drawer3D.getImageWidth(), Drawer3D.getImageHeight()