Documentation Talk:Reference Section 4.2

From POV-Wiki
Revision as of 10:52, 19 May 2011 by Jholsenback (talk | contribs) (add isosurface section for user editting)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Next is the updated section about poly & polynomial, from 2 to 35 --Le Forgeron 18:22, 21 December 2010 (UTC)


Poly, Cubic and Quartic

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

Poly default values:

sturm : off

where Order is an integer number from 2 to 35 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.


2nd 3rd 4th 5th 6th 7th 5th 6th 7th 6th 7th
A1 x2 x3 x4 x5 x6 x7 A41 y3 xy3 x2y3 A81 z3 xz3
A2 xy x2y x3y x4y x5y x6y A42 y2z3 xy2z3 x2y2z3 A82 z2 xz2
A3 xz x2z x3z x4z x5z x6z A43 y2z2 xy2z2 x2y2z2 A83 z xz
A4 x x2 x3 x4 x5 x6 A44 y2z xy2z x2y2z A84 1 x
A5 y2 xy2 x2y2 x3y2 x4y2 x5y2 A45 y2 xy2 x2y2 A85 y7
A6 yz xyz x2yz x3yz x4yz x5yz A46 yz4 xyz4 x2yz4 A86 y6z
A7 y xy x2y x3y x4y x5y A47 yz3 xyz3 x2yz3 A87 y6
A8 z2 xz2 x2z2 x3z2 x4z2 x5z2 A48 yz2 xyz2 x2yz2 A88 y5z2
A9 z xz x2z x3z x4z x5z A49 yz xyz x2yz A89 y5z
A10 1 x x2 x3 x4 x5 A50 y xy x2y A90 y5
A11 y3 xy3 x2y3 x3y3 x4y3 A51 z5 xz5 x2z5 A91 y4z3
A12 y2z xy2z x2y2z x3y2z x4y2z A52 z4 xz4 x2z4 A92 y4z2
A13 y2 xy2 x2y2 x3y2 x4y2 A53 z3 xz3 x2z3 A93 y4z
A14 yz2 xyz2 x2yz2 x3yz2 x4yz2 A54 z2 xz2 x2z2 A94 y4
A15 yz xyz x2yz x3yz x4yz A55 z xz x2z A95 y3z4
A16 y xy x2y x3y x4y A56 1 x x2 A96 y3z3
A17 z3 xz3 x2z3 x3z3 x4z3 A57   y6 xy6 A97 y3z2
A18 z2 xz2 x2z2 x3z2 x4z2 A58 y5z xy5z A98 y3z
A19 z xz x2z x3z x4z A59 y5 xy5 A99 y3
A20 1 x x2 x3 x4 A60 y4z2 xy4z2 A100 y2z5
A21 y4 xy4 x2y4 x3y4 A61 y4z xy4z A101 y2z4
A22 y3z xy3z x2y3z x3y3z A62 y4 xy4 A102 y2z3
A23 y3 xy3 x2y3 x3y3 A63 y3z3 xy3z3 A103 y2z2
A24 y2z2 xy2z2 x2y2z2 x3y2z2 A64 y3z2 xy3z2 A104 y2z
A25 y2z xy2z x2y2z x3y2z A65 y3z xy3z A105 y2
A26 y2 xy2 x2y2 x3y2 A66 y3 xy3 A106 yz6
A27 yz3 xyz3 x2yz3 x3yz3 A67 y2z4 xy2z4 A107 yz5
A28 yz2 xyz2 x2yz2 x3yz2 A68 y2z3 xy2z3 A108 yz4
A29 yz xyz x2yz x3yz A69 y2z2 xy2z2 A109 yz3
A30 y xy x2y x3y A70 y2z xy2z A110 yz2
A31 z4 xz4 x2z4 x3z4 A71 y2 xy2 A111 yz
A32 z3 xz3 x2z3 x3z3 A72 yz5 xyz5 A112 y
A33 z2 xz2 x2z2 x3z2 A73 yz4 xyz4 A113 z7
A34 z xz x2z x3z A74 yz3 xyz3 A114 z6
A35 1 x x2 x3 A75 yz2 xyz2 A115 z5
A36 y5 xy5 x2y5 A76 yz xyz A116 z4
A37 y4z xy4z x2y4z A77 y xy A117 z3
A38 y4 xy4 x2y4 A78 z6 xz6 A118 z2
A39 y3z2 xy3z2 x2y3z2 A79 z5 xz5 A119 z
A40 y3z xy3z x2y3z A80 z4 xz4 A120 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: x4 + y4 + z4 + 2 x2 y2 + 2 x2 z2 + 2 y2 z2 - 2 (r_02 + r_12) x2 + 2 (r_02 - r_12) y2 - 2 (r_02 + r_12) z2 + (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
  }

If you are afraid of messing up with the numerous coefficients, an alternative syntax is available as polynomial which does not care about the order of the coefficients (as long as you do not define one more than once, otherwise only the value of the last definition is kept) and default with all coefficients to 0 (so you can hopefully also save some typing if you have a lot of 0):

POLYNOMIAL:
  polynomial {
    Order, [COEFFICIENTS...]
    [POLY_MODIFIERS...]
    }
COEFFICIENTS:
  xyz(<x_power>,<y_power>,<z_power>):<value>[,]
POLY_MODIFIERS:
  sturm | OBJECT_MODIFIER

Same torus as above, with the polynomial syntax:

// Torus having major radius sqrt(40), minor radius sqrt(12)
polynomial { 4,
  xyz(4,0,0):1,   
  xyz(2,2,0):2,  
  xyz(2,0,2):2,
  xyz(2,0,0:-104,  
  xyz(0,4,0):1,
  xyz(0,2,2):2,
  xyz(0,2,0):56,
  xyz(0,0,4):1,
  xyz(0,0,2):-104, 
  xyz(0,0,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.

Isosurface Object

Details about many of the things that can be done with the isosurface object are discussed in the isosurface tutorial section. Below you will only find the syntax basics:

isosurface {
  function { FUNCTION_ITEMS }
  [contained_by { SPHERE | BOX }]
  [threshold FLOAT_VALUE]
  [accuracy FLOAT_VALUE]
  [max_gradient FLOAT_VALUE]
  [evaluate P0, P1, P2]
  [open]
  [max_trace INTEGER] | [all_intersections]
  [OBJECT_MODIFIERS...]
  }

Isosurface default values:

contained_by : box{-1,1}
threshold    : 0.0
accuracy     : 0.001
max_gradient : 1.1


function { ... } This must be specified and be the first item of the isosurface statement. Here you place all the mathematical functions that will describe the surface.

contained_by { ... } The contained_by object limits the area where POV-Ray samples for the surface of the function. This container can either be a sphere or a box, both of which use the standard POV-Ray syntax. If not specified a box {<-1,-1,-1>, <1,1,1>} will be used as default.

contained_by { sphere { CENTER, RADIUS } }
contained_by { box { CORNER1, CORNER2 } }

threshold This specifies how much strength, or substance to give the isosurface. The surface appears where the function value equals the threshold value. The default threshold is 0.

function = threshold

accuracy The isosurface finding method is a recursive subdivision method. This subdivision goes on until the length of the interval where POV-Ray finds a surface point is less than the specified accuracy. The default value is 0.001.
Smaller values produces more accurate surfaces, but it takes longer to render.

max_gradient POV-Ray can find the first intersecting point between a ray and the isosurface of any continuous function if the maximum gradient of the function is known. Therefore you can specify a max_gradient for the function. The default value is 1.1. When the max_gradient used to find the intersecting point is too high, the render slows down considerably. When it is too low, artefacts or holes may appear on the isosurface. When it is way too low, the surface does not show at all. While rendering the isosurface POV-Ray records the found gradient values and prints a warning if these values are higher or much lower than the specified max_gradient:

Warning: The maximum gradient found was 5.257, but max_gradient of
the isosurface was set to 5.000. The isosurface may contain holes!
Adjust max_gradient to get a proper rendering of the isosurface.
Warning: The maximum gradient found was 5.257, but max_gradient of
the isosurface was set to 7.000. Adjust max_gradient to
get a faster rendering of the isosurface.

For best performance you should specify a value close to the real maximum gradient.

evaluate POV-Ray can also dynamically adapt the used max_gradient. To activate this technique you have to specify the evaluate keyword followed by three parameters:

  •   P0: the minimum max_gradient in the estimation process,
  •   P1: an over-estimating factor. This means that the max_gradient is multiplied by the P1 parameter.
  •   P2: an attenuation parameter (1 or less)

In this case POV-Ray starts with the max_gradient value P0 and dynamically changes it during the render using P1 and P2. In the evaluation process, the P1 and P2 parameters are used in quadratic functions. This means that over-estimation increases more rapidly with higher values and attenuation more rapidly with lower values. Also with dynamic max_gradient, there can be artefacts and holes.

If you are unsure what values to use, start a render without evaluate to get a value for max_gradient. Now you can use it with evaluate like this:

  • P0 : found max_gradient * min_factor
    min_factor being a float between 0 and 1 to reduce the max_gradient to a minimum max_gradient. The ideal value for P0 would be the average of the found max_gradients, but we do not have access to that information.
    A good starting point is 0.6 for the min_factor
  • P1 : sqrt(found max_gradient/(found max_gradient * min_factor))
    min_factor being the same as used in P0 this will give an over-estimation factor of more than 1, based on your minimum max_gradient and the found max_gradient.
  • P2 : 1 or less
    0.7 is a good starting point.

When there are artifacts / holes in the isosurface, increase the min_factor and / or P2 a bit. Example: when the first run gives a found max_gradient of 356, start with

#declare Min_factor= 0.6;
isosurface {
  ...
  evaluate 356*Min_factor,  sqrt(356/(356*Min_factor)),  0.7
  //evaluate 213.6, 1.29, 0.7
  ...
  }

This method is only an approximation of what happens internally, but it gives faster rendering speeds with the majority of isosurfaces.

open When the isosurface is not fully contained within the contained_by object, there will be a cross section. Where this happens, you will see the surface of the container. With the open keyword, these cross section surfaces are removed. The inside of the isosurface becomes visible.

Note: Using open slows down the render speed, and it is not recommended to use it with CSG operations.

max_trace Isosurfaces can be used in CSG shapes since they are solid finite objects - if not finite by themselves, they are through the cross section with the container.
By default POV-Ray searches only for the first surface which the ray intersects. But when using an isosurface in CSG operations, the other surfaces must also be found. Therefore, the keyword max_trace must be added to the isosurface statement. It must be followed by an integer value. To check for all surfaces, use the keyword all_intersections instead.
With all_intersections POV-Ray keeps looking until all surfaces are found. With a max_trace it only checks until that number is reached.