summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-11-05 01:49:19 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-11-05 01:49:19 +0000
commitdcdcd798c9609a740e457077ea9d5ecc2df898e0 (patch)
tree57f73d47321bfeaf42261bff9a2645332977aca8
parentaddc698fd51a9d99527cf008dc34a085142c7e91 (diff)
downloadnetpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.tar.gz
netpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.tar.xz
netpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.zip
miscellaneous update
git-svn-id: http://svn.code.sf.net/p/netpbm/code/userguide@3981 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--pamarith.html4
-rw-r--r--pamtris.html221
2 files changed, 124 insertions, 101 deletions
diff --git a/pamarith.html b/pamarith.html
index 17bb4558..0f300048 100644
--- a/pamarith.html
+++ b/pamarith.html
@@ -271,6 +271,8 @@ number of bit positions to shift.
 <p>Note that the maxval (see <a href="#maxval">Maxval</a>) determines
 the width of the frame within which you are shifting.
 
+</dl>
+  
 <h3 id="otheroptions">Other</h3>
   
 <dl compact>
@@ -279,8 +281,6 @@ the width of the frame within which you are shifting.
 <dd>This changes the meaning of <b>-equal</b>.  It is not valid with any
 other function.  See the description of <b>-equal</b>.
 
-</dt>
-
 </dl>
 
 <h2 id="seealso">SEE ALSO</h2>
diff --git a/pamtris.html b/pamtris.html
index 1e2bf7fa..8538e5b3 100644
--- a/pamtris.html
+++ b/pamtris.html
@@ -2,8 +2,8 @@
 <html><head><title>Pamtris User Manual</title></head>
 <body>
 <h1>pamtris</h1>
-Updated: 15 June 2019
-<br>
+Updated: 05 November 2020
+<p>
 <a href="#index">Table Of Contents</a>
 
 <h2>NAME</h2>
@@ -64,9 +64,10 @@ as a (potentially multi-image) PAM stream on Standard Output.
     </code>
   </pre>
   
-<p>produces this: 
+<p>produces this:
 
-<img src="pamtris_fan.png" alt="Example Pamtris output for fan mode">
+<p>
+<img src="pamtris_fan.png" alt="Example pamtris output for FAN mode">
   
 <p>The input file gives triangle data by setting the appropriate drawing mode,
 if necessary, and then providing a list of vertices. Each vertex is also
@@ -76,8 +77,8 @@ values between 0 and a given maxval. In the most common usage, you use
 are an RGB specification of a color.  Such attribute lists may be provided on
 a per-vertex basis.
 
-<p>Before images can be effectively written to Standard Output, <b>pamtris</b>
-gradually rasterizes them on an internal frame buffer which consists of an
+<p>Prior to effectively writing a PAM image to Standard Output, <b>pamtris</b>
+first rasterizes it onto an internal frame buffer, which consists of an
 "image buffer" and a "depth buffer." The image buffer consists of a sequence
 of <i>height</i> rows containing a sequence of <i>width</i> tuples. There is
 one sample for each vertex attribute in every tuple plus an opacity (alpha)
@@ -182,7 +183,7 @@ and process it with:
   
 to yield:
 <p>
-<img src="pamtris_strip.png" alt="Example Pamtris output for strip mode">
+<img src="pamtris_strip.png" alt="Example pamtris output for STRIP mode">
 
 <h3 id="examples_triangles">Triangle Mode</h3>
 
@@ -220,7 +221,7 @@ and process it with:
 
 to yield:
 <p>
-<img src="pamtris_pierce.png" alt="Example Pamtris output for triangle mode">
+<img src="pamtris_pierce.png" alt="Example pamtris output for TRIANGLES mode">
 
 
 <h3 id="pamtris_c">Meta-programming</h3>
@@ -230,10 +231,16 @@ directly for any serious drawing; you will probably want to use a general
 purpose programming language to generate a temporary <b>pamtris</b> command
 file.
 
-<p>For example, the following C program generates <b>pamtris</b> instructions
-to produce a picture of NAMCO's Pac-Man.  It generates dozens of
-<b>vertex</b> commands tracing around the perimeter of a circle.
+<p>For example, the <b>draw_pacman</b> procedure in the following C program
+generates <b>pamtris</b> instructions to produce a picture of NAMCO's Pac-Man,
+with custom colors, position, radius, orientation and mouth opening angle. It
+generates dozens of <b>vertex</b> commands tracing around the perimeter of a
+circle. (Note: The PAM image produced by piping the output of the below program
+into <b>pamtris</b> was subsequently downscaled through
+<b>pamscale&nbsp;-linear&nbsp;-xscale&nbsp;0.5&nbsp;-yscale&nbsp;0.5</b> to achieve
+an <a href="#antialias">anti-aliased</a> effect.)
 
+<p>
 <img alt="Pac-Man" src="pamtris_pacman.png">
 
 <pre>
@@ -245,62 +252,85 @@ to produce a picture of NAMCO's Pac-Man.  It generates dozens of
  * tupletyple  = RGB_ALPHA
  * --------------------------------- */
 
+#include &lt;stdint.h&gt;
 #include &lt;stdio.h&gt;
 #include &lt;math.h&gt;
 
-#define PI      3.141592
-#define PI2     (2.0 * PI)
+#define PI 3.14159265358979323844
+
+struct rgb_spec { uint8_t r, g, b; };
+
+void draw_pacman (
+  int const center_x,
+  int const center_y,
+  int const radius,
+  int const depth,
+  struct rgb_spec const inner_color,
+  struct rgb_spec const outer_color,
+  int const orientation,      /* &lt;-- Angle of mouth's horizontal axis, in
+                               * degrees. */
+  int const mouth_half_angle  /* &lt;-- Half angle between mouth's top and
+                               * bottom, in degrees. Use something between 0
+                               * and 180. */
+) {
+    double const ori_rad = PI*orientation/180;
+    double const mha_rad = PI*mouth_half_angle/180;
+
+    printf("mode fan\n"
+           "attr %d %d %d\n"
+           "vert %d %d %d\n"
+           "attr %d %d %d\n",
+           inner_color.r, inner_color.g, inner_color.b,
+           center_x,      center_y,              depth,
+           outer_color.r, outer_color.g, outer_color.b
+    );
+
+    {
+        double angle;
+
+        for(angle = mha_rad; angle &lt;= 2*PI - mha_rad; angle += 2*PI/360)
+        {
+            int const x = round(center_x + cos(ori_rad + angle) * radius);
+            int const y = round(center_y - sin(ori_rad + angle) * radius);
 
-#define WIDTH   256
-#define HEIGHT  WIDTH
+            printf("vertex %d %d %d\n", x, y, depth);
+        }
+    }
+}
 
 int main(void)
 {
-        int const center_x = 0.5 * WIDTH;
-        int const center_y = 0.5 * HEIGHT;
-
-        double const radius = 0.48 * WIDTH;
-        
-        int const sectors = round(0.125 * PI * radius + 1);
-
-        puts("mode triangles");
-
-        printf("vertex %d %d 0\n", center_x, center_y);
-        printf("vertex %d %d 0\n", WIDTH, 0);
-        printf("vertex %d %d 0\n", WIDTH, HEIGHT);
+    struct rgb_spec const inner_colors[3] = {
+        {255, 255, 0}, {  0, 200, 255}, {0, 255, 80}
+    };
+    struct rgb_spec const outer_colors[3] = {
+        {255,  25, 0}, {200,   0, 255}, {0, 100, 10}
+    };
 
-        puts("clear image");
-        puts("mode fan");
-        puts("attribs 255 255 0");
-        printf("vertex %d %d 1\n", center_x, center_y);
-        puts("attribs 255 128 0");
+    int i;
 
-        double const angle_step = PI2 / (sectors - 1);
+    for(i = 0; i &lt; 3; i++)
+        draw_pacman(128 + cos(i*2*PI/3)*72, 128 - sin(i*2*PI/3)*72,
+                    58                    , 0                     ,
+                    inner_colors[i]       , outer_colors[i]       ,
+                    i*120                 , (3-i)*15
+        );
 
-        unsigned int i;
+    puts("!");
 
-        for (i = 0; i &lt; sectors; i++)
-        {
-                double const angle = angle_step * i;
-                int const x = round(cos(angle) * radius + center_x);
-                int const y = round(sin(angle) * radius + center_y);
-
-                printf("vertex %d %d 1\n", x, y);
-        }
-
-        puts("print");
-
-        return 0;
+    return 0;
 }
+
 </code>
 </pre>
 
-<p>Below are two other examples which, although not as trivial, demonstrate
-what else can be feasibly obtained through this meta-programming approach,
-especially when combining <b>pamtris</b> with other Netpbm programs (Earth
-texture from
-<a href="https://visibleearth.nasa.gov/view.php?id=73580">nasa.gov</a>):
+<p>Below are two other examples which demonstrate what else can be feasibly
+obtained through this meta-programming approach, especially when combining
+<b>pamtris</b> with other Netpbm programs (Earth texture from
+<a href="https://visibleearth.nasa.gov/view.php?id=73580" target="_tab">
+nasa.gov</a>):
 
+<p>
 <img alt="Isometric Rainbow Waves" src="pamtris_isowaves.gif">
 <img alt="Rotating Earth" src="pamtris_earth.gif">
 
@@ -328,11 +358,11 @@ the closed range [1, 8192].
 <p>This option is mandatory.</dd>
 
 <dt><b>-num_attribs=</b><i>attributes_per_vertex</i></dt>
-<dd>This is the number of attributes per vertex and, by extension, the depth
-of the output PAM images, which is equal to this value plus one (to accomodate
-the alpha plane). The argument must be an integer in the closed range [1, 20].
+<dd>This is the number of attributes per vertex. The depth of the output
+PAM images equals this value plus one (to accomodate the alpha plane). The
+argument must be an integer in the closed range [1, 20].
 
-<p>The input instruction sequence may override this with a <b>reset</b>
+<p>The input instruction stream may override this with a <b>reset</b>
 command.
 
 <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>,
@@ -343,7 +373,7 @@ and <b>-grayscale</b>.
 <dd>This is the tuple type for the output PAM images. The argument is a string
 which may be no longer than 255 characters.
 
-<p>The input instruction sequence may override this with a <b>reset</b>
+<p>The input instruction stream may override this with a <b>reset</b>
 command.
 
 <p>The default is an empty (null) string.
@@ -362,7 +392,7 @@ RGB(_ALPHA) color images directly, and the three vertex attributes are the
 red, green and blue levels of the color associated with the vertex, in that
 order.
 
-<p>The input instruction sequence may override this with a <b>reset</b>
+<p>The input instruction stream may override this with a <b>reset</b>
 command.
 
 <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>,
@@ -376,7 +406,7 @@ Another convenience option, similar to <b>-rgb</b>; except this one is an
 alias for <b>-num_attribs=</b>1 <b>-tupletype=GRAYSCALE_ALPHA</b>. The one
 vertex attribute is the gray level associated with the vertex.
 
-<p>The input instruction sequence may override this with a <b>reset</b>
+<p>The input instruction stream may override this with a <b>reset</b>
 command.
 
 <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>,
@@ -391,15 +421,15 @@ closed range [1, 65535].
 
 <p>The default value is 255.
 
-<p>The input instruction sequence may override this with a
+<p>The input instruction stream may override this with a
 <b>reset</b> command.
 </dd>
 </dl>
 
 <h2 id="instruction_code">INSTRUCTION CODE</h2>
 
-<p>The input for <b>pamtris</b> consists of a sequence of text lines sent to
-it through the Standard Input mechanism.
+<p>The input for <b>pamtris</b> consists of a stream of text lines read from
+Standard Input.
 
 <p>Empty lines or lines that contain only white space characters are called
 blank lines and are ignored.
@@ -409,14 +439,14 @@ along with every character after it. In other words, everything from the
 <b>#</b> until the end of the line receives the same treatment as white
 space.
 
-<p>Lines which are not blank must contain a sequence of strings separated by
-white space, called tokens.  The first such token must be one of the
+<p>Lines which are not blank must contain a sequence of strings, called
+tokens, separated by white space.  The first such token must be one of the
 commands recognized by <b>pamtris</b>, and all further tokens are interpreted
 as the arguments for that command, if it takes any. When an insufficient
 number of arguments is provided for a command, the line is considered invalid
-and is given the same treatment as a blank line. The same happens when an
-out of range argument or one of a kind different of what is expected is given
-(for example, when you give a string of letters where a numerical value is
+and is given the same treatment as a blank line. The same happens when an out
+of range argument or one of a kind different of what is expected is given (for
+example, when you give a string of letters where a numerical value is
 expected), or when an unrecognized command/argument is found. When a number of
 arguments greater than that required for a particular command is provided,
 only the portion of the line up to the last required argument is considered
@@ -498,7 +528,8 @@ means that every <i>N</i><sup>th</sup> triangle is specified by vertices
 </dd>
 
 <dt>
-<b>attribs</b> <i>a<sub>0</sub></i> ... <i>a<sub>num_attribs - 1</sub></i>
+<b>attribs</b> <i>a<sub>0</sub></i> <i>a<sub>1</sub></i>
+<i>a<sub>2</sub></i> ... <i>a<sub>num_attribs - 1</sub></i>
 </dt>
 <dd>
 <p>This updates the current attribute values list. This command takes as
@@ -571,34 +602,26 @@ perspective, you must provide an appropriate value for this parameter,
 otherwise the output images might look very wrong.  <i>w</i> was new in Netpbm
 10.85 (December 2018).
 
-<p>One way to compute <i>w</i> for a vertex in a image which is
-intended to look as in perspective is as follows. First, consider the
-<a href="https://en.wikipedia.org/wiki/Viewing_frustum">typical model</a>
-of the so-colled "viewing frustum" used to project vertices in 3D
-"world space" onto a planar "image space." The value of <i>w</i> for a
-vertex is simply the
-<a id="vertex_note_link" href="#vertex_note">dot product*</a> between the 3D
-vector <b>r</b> and the 3D unit vector <b>n</b> (i.e. the length of the
-orthogonal projection of <b>r</b> on the line determined by <b>n</b>) in
-pixels; where <b>r</b> is the vector which goes from the projection reference
-point (PRP, or "eye") to the vertex, and <b>n</b> is a view-plane normal
-(VPN) of unit length which points away from the PRP.
-
-<p>In case you are performing a mere multiplication of a 4D vector with
-x, y, z and w components by a so-called perspective projection 4x4 matrix
-in order to compute the projection of a vertex onto the image plane,
-then you may supply for <i>w</i> a value which is directly proportional
-to the absolute value of the w component of the resulting vector.
-
-<p>[<a id="vertex_note" href="#vertex_note_link">*</a>]:
-For any two 3D vectors <b>a</b> and <b>b</b>, with respective
-real scalar components a<sub>x</sub>, a<sub>y</sub>, a<sub>z</sub> and
-b<sub>x</sub>, b<sub>y</sub>, b<sub>z</sub>, the dot product between
-<b>a</b> and <b>b</b> is simply
-a<sub>x</sub> * b<sub>x</sub> +
-a<sub>y</sub> * b<sub>y</sub> +
-a<sub>z</sub> * b<sub>z</sub>.
-
+<p>Consider the
+<a href="https://en.wikipedia.org/wiki/Viewing_frustum" target="_tab">
+typical model</a> of the so-called "viewing frustum" used to project vertices
+in 3D "world space" onto a planar "image space." If we adopt the convention
+that a "z-plane" means any plane parallel to the view-plane (a.k.a. picture
+plane, a.k.a. near plane), the value of <i>w</i> for a vertex should then be
+the (smallest/euclidean/orthogonal) distance in pixels between the projection
+reference point (PRP, or "eye") and the z-plane containing the vertex. One
+way to compute this value amounts to simply taking the dot product between
+the 3D vector <b>r</b> and the 3D unit vector <b>n</b>, where <b>r</b> is
+the vector which goes from the projection reference point (PRP, or "eye") to
+the vertex, and <b>n</b> is a view-plane normal (VPN) of unit length which
+points away from the PRP. In other words, this is equal to the length of the
+orthogonal projection of <b>r</b> on the line "determined" by <b>n</b>.
+
+<p>(Note: For any two 3D vectors <b>a</b> and <b>b</b>, with respective real
+scalar components a<sub>x</sub>, a<sub>y</sub>, a<sub>z</sub> and
+b<sub>x</sub>, b<sub>y</sub>, b<sub>z</sub>, the dot product between <b>a</b>
+and <b>b</b> is simply
+a<sub>x</sub>*b<sub>x</sub>&nbsp;+&nbsp;a<sub>y</sub>*b<sub>y</sub>&nbsp;+&nbsp;a<sub>z</sub>*b<sub>z</sub>.)
 </dd>
 
 <dt><b>print</b></dt>
@@ -710,14 +733,14 @@ the images produced by <b>pamtris</b> are perspective-correct.
 inteded to be "repeated" along triangle meshes.
 
 
-<h3>Anti-aliased edges</h3>
+<h3 id="antialias">Anti-aliased edges</h3>
 
 <p><b>pamtris</b> performs no anti-aliasing on triangle edges by itself.
 However, it is possible to obtain anti-aliased images through a
 "super-sampling" approach: draw your image(s) at a size larger than
-the desired final size, and then, when all post-processing is done,
-down-scale the final image(s) to the desired size. Drawing images with
-twice the desired width and height, then down-scaling them to the intended
+the desired final size, and then, when all postprocessing is done,
+downscale the final image(s) to the desired size. Drawing images with
+twice the desired width and height, then downscaling them to the intended
 size while disregarding gamma (i.e. what <b>pamscale&nbsp;-linear</b> does)
 often produces good enough results.