home *** CD-ROM | disk | FTP | other *** search
/ Hot Shareware 32 / hot34.iso / ficheros / DGRAF / FRAIN196.ZIP / PHCTUTOR.TXT < prev    next >
Text File  |  1997-05-04  |  22KB  |  656 lines

  1.  
  2.  
  3.  
  4.                     * * * * * * * * * * * * * * * *
  5.                     *                             *
  6.                     *   PHC  and  PTC  tutorial   *
  7.                     *                             *
  8.                     *            v 2.0            *
  9.                     *                             *
  10.                     *           May 1997          *
  11.                     *                             *
  12.                     * * * * * * * * * * * * * * * *
  13.  
  14.  
  15.  
  16.  
  17.     1 - PHC Method: Overlaying two fractals ("16-bit PHC")
  18.         1-1 - Assignment statements
  19.         1-2 - Bailout tests
  20.         1-3 - Examples
  21.               1-3-1 - Mandel and Julia types
  22.               1-3-2 - Mandel and Newton types
  23.     2 - First PTC Method: Overlaying three fractals ("24-bit PTC")
  24.     3 - Second PTC Method: Overlaying four fractals ("32-bit PTC")
  25.     4 - Speed ups
  26.         4-1 - Avoid exponentiation...
  27.         4-2 - Avoid unnecessary calculations...
  28.         4-3 - Use the algebraic rules...
  29.     5 - How to write or modify PHC and PTC formulas
  30.     6 - Conversion of existing formulas
  31.         6-1 - Example 1
  32.         6-2 - Example 2
  33.         6-3 - Example 3
  34.         6-4 - Example 4: bailout tests
  35.     7 - Notes about the formula parser
  36.         7-1 - Calculation modes
  37.         7-2 - What's wrong with 3 * trunc(cr / 3) ?
  38.         7-3 - Precedence
  39.     8 - Limitations of PHC and PTC
  40.     9 - Conclusion
  41.  
  42.  
  43.  
  44.  
  45.     This document is Copyright (c) 1996-1997 by Sylvie Gallet.
  46.     I encourage you to copy and distribute it, so long as you leave it
  47.     unchanged.  It may NOT be used for commercial purposes without my
  48.     explicit prior permission.
  49.  
  50.     Any comments, questions, corrections... are welcome.
  51.     My addresses are:
  52.  
  53.              CompuServe:  Sylvie_Gallet  [101324,3444]
  54.                Internet:  sylvie_gallet@compuserve.com
  55.  
  56.  
  57.  
  58.     Pseudo-HiColor (PHC) was co-discovered by Jim Deutch who wrote the
  59.     very first PHC formula and Lee Skinner who realized the enormous
  60.     possibilities that this technique offers.  Given the great interest
  61.     aroused by PHC, the Fractint developers decided to implement three
  62.     new variables that make formulas much simpler; a big thank you to
  63.     Tim Wegner, Jonathan Osuch and George Martin for doing this!
  64.  
  65.     And a MEGA thanks for the IF..ELSE instruction they implemented in
  66.     Fractint 19.6.  This very powerful instruction considerably improves
  67.     the readability of the formulas that use conditional statements and
  68.     makes them generally faster.
  69.  
  70.     In this second version of the PHC and PTC tutorial, I have rewritten
  71.     both the explanatory material and the formulas to take advantage
  72.     of the express branching instructions available now with Fractint 19.6.
  73.     Some historical perspective may be helpful. Branching instructions have
  74.     evolved from the technique described by Bradley Beacham in his formula
  75.     tutorial, to the more direct conditional assignments commonly seen now,
  76.     to the new IF..ELSE instructions. PHC formulas originally contained
  77.     rather complex calculations to achieve the checkerboard effect required,
  78.     but were much simplified when the "whitesq", "scrnpix", and "scrnmax"
  79.     predefined variables were added to the formula parser.
  80.  
  81.     Because of these developments, the same PHC formula may be found in
  82.     different formula files with much different instructions, depending on
  83.     the "state of the art" when the particular version of the formula was
  84.     written. I have included samples of formulas written in the previous
  85.     style in the accompanying phctutor.frm. This should help the Fractint
  86.     user to understand how the old formulas worked and make easier the
  87.     conversion of existing formulas written in the prior old formats.
  88.  
  89.     Pseudo-TrueColor (PTC) is an extension of the PHC concept.  All the
  90.     PHC and PTC formulas included in this document are by the author of
  91.     these lines.
  92.  
  93.     Thanks to Lee Skinner and George Martin for their help, suggestions
  94.     and encouragements.
  95.  
  96.  
  97.  
  98.  
  99. 1 - PHC Method: Overlaying two fractals ("16-bit PHC")
  100. ======================================================
  101.  It is possible to combine two fractals (say fractal_0 and fractal_1) in
  102.  one image.  Imagine that alternate screen pixels form a checkerboard
  103.  pattern (represented by 0's and 1's) as follows:
  104.  
  105.                           0 1 0 1 0 . .
  106.                           1 0 1 0 1 . .
  107.                           0 1 0 1 0 . .
  108.                           1 0 1 0 1 . .
  109.                           . . . . . . .
  110.  
  111.  If one fractal is drawn on the "white squares" (the 1's) and the other
  112.  on the black squares (the 0's), the separate fractals will be visible,
  113.  and at higher screen resolutions you will not be able to see the way the
  114.  individual pixels intermesh with the others.  The effect is as if the two
  115.  fractals were drawn on separate transparent sheets and overlaid.
  116.  
  117.  Fractint v. 19.5 provides a predefined variable "whitesq", which is
  118.  automatically set to 1 prior to the calculation of a white square pixel,
  119.  and to 0 prior to calculation of a black square pixel.  Let's see how to
  120.  use this variable in a formula.
  121.  
  122. 1-1 - Assignment statements
  123. -+-+-+-+-+-+-+-+-+-+-+-+-+-
  124.  Suppose that fractal_0 and fractal_1 have the following assignment statements:
  125.  
  126.           fractal_0
  127.             var = something
  128.  
  129.           fractal_1
  130.             var = somethingelse
  131.  
  132.  To overlay the two fractals in PHC fashion, you can use the following
  133.  IF..ELSE instruction in a formula:
  134.  
  135.      IF (whitesq == 0)         ; "whitesq == 0" is TRUE
  136.        var = something
  137.      ELSE                      ; "whitesq == 0" is FALSE
  138.        var = somethingelse
  139.      ENDIF
  140.  
  141.  or, even more simple:
  142.  
  143.      IF (whitesq)              ; "whitesq == 1" is TRUE
  144.        var = somethingelse
  145.      ELSE                      ; "whitesq == 1" is FALSE
  146.        var = something
  147.      ENDIF
  148.  
  149. 1-2 - Bailout tests
  150. -+-+-+-+-+-+-+-+-+-
  151.  Suppose that fractal_0 and fractal_1 use the bailout tests bailout_0 and
  152.  bailout_1.  What will be the PHC bailout test?
  153.  
  154.  Remember that if the answer of a bailout test is "TRUE" (the real portion
  155.  of the complex number is nonzero), the loop must be performed again;
  156.  otherwise, it is time to quit iterating.
  157.  
  158.  The bailout test of the PHC formula must be the translation in the parser
  159.  language of the following rule:
  160.  
  161.  PHC_bailout is TRUE only in two cases:
  162.  
  163.      when (whitesq == 0) and (bailout_0 == TRUE)
  164.    or
  165.      when (whitesq == 1) and (bailout_1 == TRUE)
  166.  
  167.   Under Fractint 19.6, this expression becomes:
  168.   --------------------------------------------
  169.  
  170.      IF (whitesq)
  171.        PHC_bailout = bailout_1
  172.      ELSE
  173.        PHC_bailout = bailout_0
  174.      ENDIF
  175.      PHC_bailout
  176.  
  177.  You'll notice that the IF block is followed by the name of a variable.
  178.  Omitting the last line will produce an error message from Fractint.
  179.  
  180. 1-3 - Examples
  181. -+-+-+-+-+-+-+
  182.  
  183. 1-3-1 - Mandel and Julia types
  184. ------------------------------
  185.  This is the easiest case: both fractal use the same iteration instruction
  186.  and the same bailout test.
  187.  
  188.    mandel { ; Mandel set of z^2 + c
  189.      z = c = pixel :
  190.       z = z*z + c
  191.        |z| <= 4
  192.      }
  193.    julia { ; Julia set of z^2 + (-0.75,0.1234)
  194.      z = pixel , c = (-0.75,0.1234) :
  195.       z = z*z + c
  196.        |z| <= 4
  197.      }
  198.  
  199.  Since the only difference is the initial value of c, the PHC formula will
  200.  use whitesq only in the init section:
  201.  
  202.    phc_mj { ; overlay the Mandel set of z^2 + c with
  203.             ; the Julia set of z^2 + (-0.75,0.1234)
  204.             ; Modified for if..else logic, April 1997
  205.      z = pixel
  206.      IF (whitesq)
  207.        c = (-0.75,0.1234)
  208.      ELSE
  209.        c = pixel
  210.      ENDIF
  211.      :
  212.      z = z*z + c
  213.      |z| <= 4
  214.      }
  215.  
  216. 1-3-2 - Mandel and Newton types
  217. -------------------------------
  218.  Here, except "z = pixel", everything is different.
  219.  
  220.    mandel { ; Mandel set of z^2 + c
  221.      z = c = pixel :
  222.       z = z*z + c
  223.        |z| <= 4
  224.      }
  225.    newton { ; Julia set of Newton's method applied to z^3 - 1 = 0
  226.      z = pixel :
  227.       n = z^3 - 1 , d = 3*z^2
  228.       z = z - n/d
  229.        |n| >= 0.000001
  230.      }
  231.  
  232.  The resulting PHC formula is:
  233.  
  234.    phc_mn_A { ; overlay the Mandel set of z^2 + c with the Julia
  235.               ; set of Newton's method applied to z^3 - 1 = 0
  236.               ; Modified for if..else logic, April 1997
  237.      z = pixel :
  238.      IF (whitesq)
  239.        n = z^3 - 1 , d = 3*z^2 , z = z - n/d
  240.        PHC_bailout = |n| >= 0.000001
  241.      ELSE
  242.        z = z*z + pixel , PHC_bailout = |z| <= 4
  243.      ENDIF
  244.      PHC_bailout
  245.      }
  246.  
  247.  
  248. 2 - First PTC Method: Overlaying three fractals ("24-bit PTC")
  249. ==============================================================
  250.  Overlaying three fractals can be done with the following pattern:
  251.  
  252.                           0 1 2 0 1 2 . .
  253.                           1 2 0 1 2 0 . .
  254.                           2 0 1 2 0 1 . .
  255.                           0 1 2 0 1 2 . .
  256.                           . . . . . . . .
  257.  
  258.  Fractint v. 19.5 provides a predefined variable "scrnpix", which is set
  259.  to (column, row) prior to calculation of each pixel.  The upper left hand
  260.  corner of the screen is (0,0); at resolution 1024x768, the lower right
  261.  hand corner is therefore (1023,767).
  262.  
  263.  Here, we'll use scrnpix to assign the value 0, 1 or 2 to a variable r
  264.  (as you can see, I choose a very explicit name!).
  265.  
  266.  With col = real(scrnpix) and row = imag(scrnpix), the value of r should
  267.  be:
  268.      r = (col + row) modulo 3
  269.  or, using the parser language:
  270.      cr = real(scrnpix) + imag(scrnpix)
  271.      r = cr - 3 * trunc(cr / 3)
  272.  
  273.  But this instruction doesn't work (see section 7-2).
  274.  
  275.  The following instruction does work:
  276.      r = cr - 3 * trunc(cr / real(3))
  277.  
  278. Now, let's see an example:
  279. --------------------------
  280.  Suppose you want to overlay the three following fractals:
  281.  
  282.    mandel { ; Mandel set of z^2 + c
  283.      z = c = pixel :
  284.       z = z*z + c
  285.        |z| <= 4
  286.      }
  287.    julia { ; Julia set of z^2 + (-0.75,0.1234)
  288.      z = pixel , c = (-0.75,0.1234) :
  289.       z = z*z + c
  290.        |z| <= 4
  291.      }
  292.    newton { ; Julia set of Newton's method applied to z^3 - 1 = 0
  293.      z = pixel :
  294.       n = z^3 - 1 , d = 3*z^2
  295.       z = z - n/d
  296.        |n| >= 0.000001
  297.      }
  298.  
  299.  We can merge them in the following way:
  300.  
  301.    ptc_mjn_A { ; overlay the Mandel set of z^2 + c with the Julia set
  302.                ; of z^2 + (-0.75,0.1234) and the Julia set of Newton's
  303.                ; method applied to z^3 - 1 = 0
  304.                ; Modified for if..else logic, April 1997
  305.      cr = real(scrnpix) + imag(scrnpix)
  306.      r = cr - 3 * trunc(cr / real(3))
  307.      z = pixel
  308.      IF (r == 0)
  309.        c = pixel
  310.      ELSEIF (r == 1)
  311.        c = (-0.75,0.1234)
  312.      ENDIF
  313.      :
  314.      IF (r == 2)
  315.        n = z^3 - 1 , d = 3*z^2 , z = z - n/d
  316.        PTC_bailout = |n| >= 0.000001
  317.      ELSE
  318.        z = z*z + c
  319.        PTC_bailout = |z| <= 4
  320.      ENDIF
  321.      PTC_bailout
  322.      }
  323.  
  324.  
  325. 3 - Second PTC Method: Overlaying four fractals ("32-bit PTC")
  326. ==============================================================
  327.  The best dithering is produced by the following pattern:
  328.  
  329.                           0 1 2 3 0 1 . .
  330.                           2 3 0 1 2 3 . .
  331.                           0 1 2 3 0 1 . .
  332.                           2 3 0 1 2 3 . .
  333.                           . . . . . . . .
  334.  
  335.  and r is given by the formula:
  336.      r = (col + 2*row) modulo 4
  337.  or, using the parser language:
  338.      cr = real(scrnpix) + 2 * imag(scrnpix)
  339.      r = cr - 4 * trunc(cr / 4)
  340.  
  341.  and r can then be used as in the previous examples, to combine four
  342.  fractals in one image.
  343.  
  344. Here is an example:
  345. -------------------
  346.    mand_0 {                        mand_1 {
  347.      z = c = sin(pixel) :            z = c = pixel :
  348.       z = z*z + c                     z = z*z + c
  349.        |real(z)| <= 4                  |z| <= 4
  350.      }                               }
  351.    mand_2 {                        mand_3 {
  352.      z = c = 1/pixel :               z = c = -pixel :
  353.       z = z*z + c                     z = z*z + c
  354.        |imag(z)| <= 4                  |real(z)+imag(z)| <= 4
  355.      }                               }
  356.  
  357.    ptc_4m_A { ; overlay four Mandels with different initializations
  358.               ; and bailout tests
  359.               ; Isn't it terrific???
  360.               ; Modified for if..else logic, April 1997
  361.      cr = real(scrnpix) + 2 * imag(scrnpix)
  362.      r = cr - 4 * trunc(cr / 4)
  363.      IF (r == 0)
  364.        z = c = sin(pixel)
  365.      ELSEIF (r == 1)
  366.        z = c = pixel
  367.      ELSEIF (r == 2)
  368.        z = c = 1/pixel
  369.      ELSE
  370.        z = c = -pixel
  371.      ENDIF
  372.      :
  373.      z = z*z + c
  374.      IF (r == 0)
  375.        PTC_bailout = |real(z)| <= 4
  376.      ELSEIF (r == 1)
  377.        PTC_bailout = |z| <= 4
  378.      ELSEIF (r == 2)
  379.        PTC_bailout = |imag(z)| <= 4
  380.      ELSE
  381.        PTC_bailout = |real(z)+imag(z)| <= 4
  382.      ENDIF
  383.      PTC_bailout
  384.      }
  385.  
  386.  
  387. 4 - Speed ups
  388. =============
  389.  The best way to make your formulas run a little faster would be to read or
  390.  reread Bradley Beacham's FRMTUTOR.TXT (that'll save me having to plagiarize
  391.  his work <g>).
  392.  
  393. 4-1 - Avoid exponentiation...
  394. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  395.  In the newton formula, we can replace
  396.      n = z^3 - 1 , d = 3*z^2
  397.  with
  398.      z2 = z*z , n = z2*z - 1 , d = 3*z2
  399.  
  400.  This gives:
  401.  
  402.    newton_B { ; Julia set of Newton's method applied to z^3 - 1 = 0
  403.      z = pixel :
  404.       z2 = z*z , n = z2*z - 1 , d = 3*z2
  405.       z = z - n/d
  406.        |n| >= 0.000001
  407.      }
  408.  
  409. 4-2 - Avoid unnecessary calculations...
  410. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  411.  
  412.   Look at this formula:
  413.  
  414.   mandelvariation {
  415.     z = c = pixel:
  416.     z = z*z + sin(c) - 0.2
  417.     |z| < 4
  418.   }
  419.  
  420.   Once you notice that the expression sin(c) - .2 is the same value every
  421.   time it is calculated for a pixel (which could be many thousands of times)
  422.   you will get in the habit of writing formulas like this one as follows:
  423.  
  424.   mandelvariation {
  425.     z = pixel
  426.     c = sin(pixel) - 0.2:
  427.     z = z*z + c
  428.     |z| < 4
  429.   }
  430.  
  431.   By moving the constant expression into the initialization section, the
  432.   calculation is made only once per pixel.
  433.  
  434.  
  435. 4-3 - Use the algebraic rules...
  436. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  437.  
  438.   An expression such as
  439.  
  440.   z = (3.5 * a + 3.5 * b) / (10.5 * c)
  441.  
  442.   is reduced to the simpler
  443.  
  444.   z = (a + b) / (3 * c)
  445.  
  446.   While this example seems trivial, cases where such speedups are possible
  447.   abound in existing formulas; in more complicated formulas, the algebraic
  448.   reductions may not be as obvious.
  449.  
  450.  
  451. 5 - How to write or modify PHC and PTC formulas
  452. ===============================================
  453.  As we've seen earlier, the PHC or PTC dithering is based on the value of
  454.  a variable initialized by Fractint (whitesq) or in the formula (r).
  455.  
  456.  To write a PHC formula, you just have to use "whitesq" at least once.
  457.  A PTC formula will start with these lines:
  458.      cr = real(scrnpix) + imag(scrnpix)
  459.      r = cr - 3 * trunc(cr / real(3))
  460.  or these ones:
  461.      cr = real(scrnpix) + 2 * imag(scrnpix)
  462.      r = cr - 4 * trunc(cr / 4)
  463.  
  464.  For a good dithering, it's essential to leave the variables "whitesq", "cr"
  465.  and "r" intact.
  466.  For example, if you change:
  467.      r = cr - 3 * trunc(cr / real(3))
  468.  to:
  469.      r = cr - 3 * trunc(cr / real(3.5))
  470.  the values of r will be:
  471.      0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4, ...
  472.  
  473.  and the result will be quite disappointing.  Also, it will be helpful if
  474.  you use the templates (including the variable names "r" and "cr") in
  475.  exactly the form shown above.  This will make it easier to identify and
  476.  update formulas using PHC and PTC if future changes to Fractint's formula
  477.  parser would make such updating desirable.
  478.  
  479.  
  480. 6 - Conversion of existing formulas
  481. ===================================
  482.  The following examples show typical old style PHC statements and their
  483.  translation for Fractint 19.6.
  484.  
  485. 6-1 - Example 1
  486. +-+-+-+-+-+-+-+
  487.  z = z*z + sin(z)*whitesq + pixel
  488.  
  489.    IF (whitesq)
  490.       z = z*z + sin(z) + pixel
  491.    ELSE
  492.       z = z*z + pixel
  493.    ENDIF
  494.  
  495. 6-2 - Example 2
  496. +-+-+-+-+-+-+-+
  497.  z = z^(z + whitesq - (whitesq == 0))
  498.  
  499.    IF (whitesq)
  500.       z = z^(z + 1)
  501.    ELSE
  502.       z = z^(z - 1)
  503.    ENDIF
  504.  
  505. 6-3 - Example 3
  506. +-+-+-+-+-+-+-+
  507.  z = (z*z + pixel)*whitesq + (exp(z) + c)*(whitesq == 0) + p1
  508.  
  509.    IF (whitesq)
  510.       z = z*z + pixel + p1
  511.    ELSE
  512.       z = exp(z) + c + p1
  513.    ENDIF
  514.  
  515. 6-4 - Example 4: bailout test
  516. +-+-+-+-+-+-+-++-+-+-+-+-+-+-
  517.  The best way to translate a bailout test that uses whitesq is to assign its
  518.  value to a variable and to end the formula with this variable.
  519.  For example:
  520.  
  521.    (|z| <= 4 && whitesq == 0) || (|n| >= 0.000001 && whitesq)
  522.  
  523.  will read as follow:
  524.  
  525.    IF (whitesq)
  526.       PHC_bailout = |n| >= 0.000001
  527.    ELSE
  528.       PHC_bailout = |z| <= 4
  529.    ENDIF
  530.    PHC_bailout
  531.  
  532.  Of course, if the iterated section already has an IF block controlled by
  533.  whitesq, we can put the "PHC_bailout =" statements in this block as in the
  534.  example below:
  535.  
  536.    phc_mn_A { ; overlay the Mandel set of z^2 + c with the Julia
  537.               ; set of Newton's method applied to z^3 - 1 = 0
  538.      z = c = pixel :
  539.       n = z^3 - 1 , d = 3*z^2
  540.       z = (z*z + c) * (whitesq == 0) + (z - n/d) * whitesq
  541.        (|z| <= 4 && whitesq == 0) || (|n| >= 0.000001 && whitesq)
  542.    }
  543.  
  544.    phc_mn_A { ; overlay the Mandel set of z^2 + c with the Julia
  545.               ; set of Newton's method applied to z^3 - 1 = 0
  546.               ; Modified for if..else logic, April 1997
  547.       z = pixel :
  548.       IF (whitesq)
  549.          n = z^3 - 1 , d = 3*z^2 , z = z - n/d
  550.          PHC_bailout = |n| >= 0.000001
  551.       ELSE
  552.          z = z*z + pixel , PHC_bailout = |z| <= 4
  553.       ENDIF
  554.       PHC_bailout
  555.       }
  556.  
  557.  
  558. 7 - Notes about the formula parser
  559. ==================================
  560.  
  561. 7-1 - Calculation modes
  562. -+-+-+-+-+-+-+-+-+-+-+-
  563.  Fractint provides two calculation modes: integer math and floating point
  564.  math.
  565.  
  566.  Though it often produces very nice images, integer math has an important
  567.  limitation: you can't use numbers greater than 255.999... In integer mode,
  568.  when you *think* you're using say 372, Fractint uses 116 (372-256=116).
  569.  For this reason, the Fractint developers decided to force the floating
  570.  point mode when the formula parser detects the use of one of the predefined
  571.  variables "scrnpix", "scrnmax" and "maxit".
  572.  
  573. 7-2 - What's wrong with 3 * trunc(cr / 3) ?
  574. -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  575.  When you run a formula in floating point mode, the formula parser uses
  576.  some tricks to optimize the code.  Trunc(cr / 3) is the victim of one of
  577.  these tricks.
  578.  
  579.  The problem is this: trunc(cr/3) is replaced by trunc(cr*(1/3)), but since
  580.  1/3 is represented internally as .33333..., cr*(1/3) is slightly less than
  581.  cr/3.  If cr is a multiple of 3, trunc(cr/3) therefore returns one less
  582.  than you would expect.  For example trunc(6/3) calculates as
  583.  trunc(6*.3333333...) or trunc(1.9999...), which in turn evaluates to 1
  584.  instead of the expected result of 2.
  585.  
  586.  Replacing 3 with real(3) circumvents this problem and yields the desired
  587.  result.
  588.  
  589. 7-3 - Precedence
  590. -+-+-+-+-+-+-+-+
  591.  Precedence is a way to make mathematical expressions more readable by using
  592.  less parentheses.  For a better comprehension of this section, you might
  593.  want to look at the table of precedence in the Fractint documentation.
  594.  
  595.  The following expressions are mathematically equivalent because division and
  596.  multiplication have a higher precedence than addition and subtraction (this
  597.  means that divisions and multiplications will be performed before additions
  598.  and subtraction):
  599.  
  600.                 2+(3*((5*3)+(4/5))*(7-5))
  601.                 2 + 3 * (5*3 + 4/5) * (7 - 5)
  602.  
  603.  (they both evaluate to 96.8)
  604.  I must confess that I tend to prefer the second one... (OK, I'm cheating,
  605.  I just added a few white spaces... <g>).
  606.  
  607.  Now, let's see another example:
  608.  -------------------------------
  609.  In this expression:
  610.                (|z| <= 4) && (whitesq == 0)
  611.  
  612.  the parentheses mean that the comparisons must be performed before the
  613.  logical AND.  Comparisons have a higher precedence than logical operators
  614.  thus, we can remove the parentheses:
  615.                |z| <= 4 && whitesq == 0
  616.  
  617.  However, with
  618.  
  619.        (|z| <= 4 && whitesq == 0) || (|n| >= 0.000001 && whitesq)
  620.  
  621.  Can we remove the parentheses?  The answer is: no!  Without parentheses,
  622.  and since we know that comparisons are performed first, this expression has
  623.  the following format:
  624.                 A && B || C && D
  625.  
  626.  "&&" and "||" have the same precedence and in such a case, the expression
  627.  must be calculated from the left to the right.  Just look at this:
  628.                 (1 && 1) || (1 && 0) =
  629.                    1     ||    0     = 1
  630.  
  631.                   1 && 1 || 1 && 0 =
  632.                     1    || 1 && 0 =
  633.                          1    && 0 = 0
  634.  
  635.  
  636. 8 - Limitations of PHC and PTC
  637. ==============================
  638.  With the new variables introduced in Fractint 19.5, PHC and PTC formulas
  639.  are now resolution independent and the image can be interrupted, saved and
  640.  restored.  Panning an even number of pixels for PHC images or multiples of
  641.  3 for "24-bit PTC's" and multiples of 4 for "32-bit PTC's is possible
  642.  without artifacts.
  643.  
  644.  All PHC and PTC formulas require passes=1.
  645.  
  646.  The use of symmetry in PHC or PTC formulas or par files is not recommended
  647.  since symmetry alters the pattern along the axes and results in horizontal
  648.  or vertical lines.
  649.  
  650.  
  651. 9 - Conclusion
  652. ==============
  653.  That's all for now!  I hope you found this text interesting and useful.
  654.  I'm planning an update of Bradley Beacham's Formula Tutorial which could
  655.  include this text and any subject you'd like to see treated.
  656.