3.4.2 Finite Patch Primitives |
POV-Ray 3.6 for UNIX documentation 3.4.3 Infinite Solid Primitives |
3.4.4 Isosurface Object |
There are five polynomial primitive shapes that are possibly infinite and do not respond to automatic bounding.
They are plane, cubic, poly, quadric and quartic. They do have a well defined inside and may be used in CSG and inside
a clipped_by
statement. As with all shapes they can be translated, rotated and scaled.
The plane
primitive is a simple way to define an infinite flat surface. The plane is not a thin
boundary or can be compared to a sheet of paper. A plane is a solid object of infinite size that divides POV-space in
two parts, inside and outside the plane. The plane is specified as follows:
PLANE: plane { <Normal>, Distance [OBJECT_MODIFIERS...] }
The <Normal>
vector defines the surface normal of the plane. A surface normal is a
vector which points up from the surface at a 90 degree angle. This is followed by a float value that gives the
distance along the normal that the plane is from the origin (that is only true if the normal vector has unit length;
see below). For example:
plane { <0, 1, 0>, 4 }
This is a plane where straight up is defined in the positive y-direction. The plane is 4 units in that direction
away from the origin. Because most planes are defined with surface normals in the direction of an axis you will often
see planes defined using the x
, y
or z
built-in vector identifiers. The
example above could be specified as:
plane { y, 4 }
The plane extends infinitely in the x- and z-directions. It effectively divides the world into two pieces. By
definition the normal vector points to the outside of the plane while any points away from the vector are defined as
inside. This inside/outside distinction is important when using planes in CSG and clipped_by
. It is also
important when using fog or atmospheric media. If you place a camera on the "inside" half of the world, then
the fog or media will not appear. Such issues arise in any solid object but it is more common with planes. Users
typically know when they have accidentally placed a camera inside a sphere or box but "inside a plane" is an
unusual concept. In general you can reverse the inside/outside properties of an object by adding the object modifier
inverse
. See "Inverse" and "Empty
and Solid Objects" for details.
A plane is called a polynomial shape because it is defined by a first order polynomial equation. Given a plane:
plane { <A, B, C>, D }
it can be represented by the equation A*x + B*y + C*z - D*sqrt(A^2 + B^2 + C^2) = 0
.
Therefore our example plane{y,4}
is actually the polynomial equation y=4. You can think of this as a
set of all x, y, z points where all have y values equal to 4, regardless of the x or z values.
This equation is a first order polynomial because each term contains only single powers of x, y or z. A second order equation has terms like x^2, y^2, z^2, xy, xz and yz. Another name for a 2nd order equation is a quadric equation. Third order polys are called cubics. A 4th order equation is a quartic. Such shapes are described in the sections below.
Higher order polynomial surfaces may be defined by the use of a poly
shape. The syntax is
POLY: poly { Order, <A1, A2, A3,... An> [POLY_MODIFIERS...] } POLY_MODIFIERS: sturm | OBJECT_MODIFIER
sturm : off
where Order
is an integer number from 2 to 15 inclusively that specifies the order of the
equation. A1, A2, ... An
are float values for the coefficients of the equation. There are n
such terms where n = ((Order+1)*(Order+2)*(Order+3))/6.
The cubic
object is an alternate way to specify 3rd order polys. Its syntax is:
CUBIC: cubic { <A1, A2, A3,... A20> [POLY_MODIFIERS...] }
Also 4th order equations may be specified with the quartic
object. Its syntax is:
QUARTIC: quartic { <A1, A2, A3,... A35> [POLY_MODIFIERS...] }
The following table shows which polynomial terms correspond to which x,y,z factors for the orders 2 to 7. Remember cubic
is actually a 3rd order polynomial and quartic
is 4th order.
2^{nd} | 3^{rd} | 4^{th} | 5^{th} | 6^{th} | 7^{th} | 5^{th} | 6^{th} | 7^{th} | 6^{th} | 7^{th} | |||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A_{1} | x^{2} | x^{3} | x^{4} | x^{5} | x^{6} | x^{7} | A_{41} | y^{3} | xy^{3} | x^{2}y^{3} | A_{81} | z^{3} | xz^{3} |
A_{2} | xy | x^{2}y | x^{3}y | x^{4}y | x^{5}y | x^{6}y | A_{42} | y^{2}z^{3} | xy^{2}z^{3} | x^{2}y^{2}z^{3} | A_{82} | z^{2} | xz^{2} |
A_{3} | xz | x^{2}z | x^{3}z | x^{4}z | x^{5}z | x^{6}z | A_{43} | y^{2}z^{2} | xy^{2}z^{2} | x^{2}y^{2}z^{2} | A_{83} | z | xz |
A_{4} | x | x^{2} | x^{3} | x^{4} | x^{5} | x^{6} | A_{44} | y^{2}z | xy^{2}z | x^{2}y^{2}z | A_{84} | 1 | x |
A_{5} | y^{2} | xy^{2} | x^{2}y^{2} | x^{3}y^{2} | x^{4}y^{2} | x^{5}y^{2} | A_{45} | y^{2} | xy^{2} | x^{2}y^{2} | A_{85} | y^{7} | |
A_{6} | yz | xyz | x^{2}yz | x^{3}yz | x^{4}yz | x^{5}yz | A_{46} | yz^{4} | xyz^{4} | x^{2}yz^{4} | A_{86} | y^{6}z | |
A_{7} | y | xy | x^{2}y | x^{3}y | x^{4}y | x^{5}y | A_{47} | yz^{3} | xyz^{3} | x^{2}yz^{3} | A_{87} | y^{6} | |
A_{8} | z^{2} | xz^{2} | x^{2}z^{2} | x^{3}z^{2} | x^{4}z^{2} | x^{5}z^{2} | A_{48} | yz^{2} | xyz^{2} | x^{2}yz^{2} | A_{88} | y^{5}z^{2} | |
A_{9} | z | xz | x^{2}z | x^{3}z | x^{4}z | x^{5}z | A_{49} | yz | xyz | x^{2}yz | A_{89} | y^{5}z | |
A_{10} | 1 | x | x^{2} | x^{3} | x^{4} | x^{5} | A_{50} | y | xy | x^{2}y | A_{90} | y^{5} | |
A_{11} | y^{3} | xy^{3} | x^{2}y^{3} | x^{3}y^{3} | x^{4}y^{3} | A_{51} | z^{5} | xz^{5} | x^{2}z^{5} | A_{91} | y^{4}z^{3} | ||
A_{12} | y^{2}z | xy^{2}z | x^{2}y^{2}z | x^{3}y^{2}z | x^{4}y^{2}z | A_{52} | z^{4} | xz^{4} | x^{2}z^{4} | A_{92} | y^{4}z^{2} | ||
A_{13} | y^{2} | xy^{2} | x^{2}y^{2} | x^{3}y^{2} | x^{4}y^{2} | A_{53} | z^{3} | xz^{3} | x^{2}z^{3} | A_{93} | y^{4}z | ||
A_{14} | yz^{2} | xyz^{2} | x^{2}yz^{2} | x^{3}yz^{2} | x^{4}yz^{2} | A_{54} | z^{2} | xz^{2} | x^{2}z^{2} | A_{94} | y^{4} | ||
A_{15} | yz | xyz | x^{2}yz | x^{3}yz | x^{4}yz | A_{55} | z | xz | x^{2}z | A_{95} | y^{3}z^{4} | ||
A_{16} | y | xy | x^{2}y | x^{3}y | x^{4}y | A_{56} | 1 | x | x^{2} | A_{96} | y^{3}z^{3} | ||
A_{17} | z^{3} | xz^{3} | x^{2}z^{3} | x^{3}z^{3} | x^{4}z^{3} | A_{57} | y^{6} | xy^{6} | A_{97} | y^{3}z^{2} | |||
A_{18} | z^{2} | xz^{2} | x^{2}z^{2} | x^{3}z^{2} | x^{4}z^{2} | A_{58} | y^{5}z | xy^{5}z | A_{98} | y^{3}z | |||
A_{19} | z | xz | x^{2}z | x^{3}z | x^{4}z | A_{59} | y^{5} | xy^{5} | A_{99} | y^{3} | |||
A_{20} | 1 | x | x^{2} | x^{3} | x^{4} | A_{60} | y^{4}z^{2} | xy^{4}z^{2} | A_{100} | y^{2}z^{5} | |||
A_{21} | y^{4} | xy^{4} | x^{2}y^{4} | x^{3}y^{4} | A_{61} | y^{4}z | xy^{4}z | A_{101} | y^{2}z^{4} | ||||
A_{22} | y^{3}z | xy^{3}z | x^{2}y^{3}z | x^{3}y^{3}z | A_{62} | y^{4} | xy^{4} | A_{102} | y^{2}z^{3} | ||||
A_{23} | y^{3} | xy^{3} | x^{2}y^{3} | x^{3}y^{3} | A_{63} | y^{3}z^{3} | xy^{3}z^{3} | A_{103} | y^{2}z^{2} | ||||
A_{24} | y^{2}z^{2} | xy^{2}z^{2} | x^{2}y^{2}z^{2} | x^{3}y^{2}z^{2} | A_{64} | y^{3}z^{2} | xy^{3}z^{2} | A_{104} | y^{2}z | ||||
A_{25} | y^{2}z | xy^{2}z | x^{2}y^{2}z | x^{3}y^{2}z | A_{65} | y^{3}z | xy^{3}z | A_{105} | y^{2} | ||||
A_{26} | y^{2} | xy^{2} | x^{2}y^{2} | x^{3}y^{2} | A_{66} | y^{3} | xy^{3} | A_{106} | yz^{6} | ||||
A_{27} | yz^{3} | xyz^{3} | x^{2}yz^{3} | x^{3}yz^{3} | A_{67} | y^{2}z^{4} | xy^{2}z^{4} | A_{107} | yz^{5} | ||||
A_{28} | yz^{2} | xyz^{2} | x^{2}yz^{2} | x^{3}yz^{2} | A_{68} | y^{2}z^{3} | xy^{2}z^{3} | A_{108} | yz^{4} | ||||
A_{29} | yz | xyz | x^{2}yz | x^{3}yz | A_{69} | y^{2}z^{2} | xy^{2}z^{2} | A_{109} | yz^{3} | ||||
A_{30} | y | xy | x^{2}y | x^{3}y | A_{70} | y^{2}z | xy^{2}z | A_{110} | yz^{2} | ||||
A_{31} | z^{4} | xz^{4} | x^{2}z^{4} | x^{3}z^{4} | A_{71} | y^{2} | xy^{2} | A_{111} | yz | ||||
A_{32} | z^{3} | xz^{3} | x^{2}z^{3} | x^{3}z^{3} | A_{72} | yz^{5} | xyz^{5} | A_{112} | y | ||||
A_{33} | z^{2} | xz^{2} | x^{2}z^{2} | x^{3}z^{2} | A_{73} | yz^{4} | xyz^{4} | A_{113} | z^{7} | ||||
A_{34} | z | xz | x^{2}z | x^{3}z | A_{74} | yz^{3} | xyz^{3} | A_{114} | z^{6} | ||||
A_{35} | 1 | x | x^{2} | x^{3} | A_{75} | yz^{2} | xyz^{2} | A_{115} | z^{5} | ||||
A_{36} | y^{5} | xy^{5} | x^{2}y^{5} | A_{76} | yz | xyz | A_{116} | z^{4} | |||||
A_{37} | y^{4}z | xy^{4}z | x^{2}y^{4}z | A_{77} | y | xy | A_{117} | z^{3} | |||||
A_{38} | y^{4} | xy^{4} | x^{2}y^{4} | A_{78} | z^{6} | xz^{6} | A_{118} | z^{2} | |||||
A_{39} | y^{3}z^{2} | xy^{3}z^{2} | x^{2}y^{3}z^{2} | A_{79} | z^{5} | xz^{5} | A_{119} | z | |||||
A_{40} | y^{3}z | xy^{3}z | x^{2}y^{3}z | A_{80} | z^{4} | xz^{4} | A_{120} | 1 |
Polynomial shapes can be used to describe a large class of shapes including the torus, the lemniscate, etc. For
example, to declare a quartic surface requires that each of the coefficients (A1 ... A35
) be
placed in order into a single long vector of 35 terms. As an example let's define a torus the hard way. A Torus can be
represented by the equation: x^{4} + y^{4} + z^{4} + 2 x^{2} y^{2} + 2 x^{2}
z^{2} + 2 y^{2} z^{2} - 2 (r_02 + r_12) x^{2} + 2 (r_02 - r_12) y^{2} - 2
(r_02 + r_12) z^{2} + (r_02 - r_12)^{2} = 0
Where r_0 is the major radius of the torus, the distance from the hole of the donut to the middle of the ring of the donut, and r_1 is the minor radius of the torus, the distance from the middle of the ring of the donut to the outer surface. The following object declaration is for a torus having major radius 6.3 minor radius 3.5 (Making the maximum width just under 20).
// Torus having major radius sqrt(40), minor radius sqrt(12) quartic { < 1, 0, 0, 0, 2, 0, 0, 2, 0, -104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 56, 0, 0, 0, 0, 1, 0, -104, 0, 784 > sturm }
Poly, cubic and quartics are just like quadrics in that you do not have to understand one to use one. The file
shapesq.inc
has plenty of pre-defined quartics for you to play with.
Polys use highly complex computations and will not always render perfectly. If the surface is not smooth, has
dropouts, or extra random pixels, try using the optional keyword sturm
in the definition. This will cause
a slower but more accurate calculation method to be used. Usually, but not always, this will solve the problem. If
sturm does not work, try rotating or translating the shape by some small amount.
There are really so many different polynomial shapes, we cannot even begin to list or describe them all. We suggest you find a good reference or text book if you want to investigate the subject further.
The quadric
object can produce shapes like paraboloids (dish shapes) and hyperboloids (saddle or
hourglass shapes). It can also produce ellipsoids, spheres, cones, and cylinders but you should use the sphere
,
cone
, and cylinder
objects built into POV-Ray because they are faster than the quadric
version.
Note: do not confuse "quaDRic" with "quaRTic". A quadric is a 2nd order polynomial while a quartic is 4th order.
Quadrics render much faster and are less error-prone but produce less complex objects. The syntax is:
QUADRIC: quadric { <A,B,C>,<D,E,F>,<G,H,I>,J [OBJECT_MODIFIERS...] }
Although the syntax actually will parse 3 vector expressions followed by a float, we traditionally have written the
syntax as above where A
through J
are float expressions. These 10 float
that define a surface of x, y, z points which satisfy the equation A x^{2} + B y^{2} + C z^{2}
+ D xy + E xz + F yz + G x + H y + I z + J = 0
Different values of A, B, C, ... J
will give different shapes. If you take any three
dimensional point and use its x, y and z coordinates in the above equation the answer will be 0 if the point is on the
surface of the object. The answer will be negative if the point is inside the object and positive if the point is
outside the object. Here are some examples:
X^{2} + Y^{2} + Z^{2} - 1 = 0 | Sphere |
X^{2} + Y^{2} - 1 = 0 | Infinite cylinder along the Z axis |
X^{2} + Y^{2} - Z^{2} = 0 | Infinite cone along the Z axis |
The easiest way to use these shapes is to include the standard file shapes.inc
into your program. It
contains several pre-defined quadrics and you can transform these pre-defined shapes (using translate, rotate and
scale) into the ones you want. For a complete list, see the file shapes.inc
.
3.4.2 Finite Patch Primitives | 3.4.3 Infinite Solid Primitives | 3.4.4 Isosurface Object |