Generating a Sine-Based Wire Frame Effect

   



Multi-Fixed Point Mesh Pattern and Archimedean Spirals

Consider the image in Figure 14.3.

click to expand
Figure 14.3: Multi-fixed point mesh pattern and Archimedean spirals.

The SVG document in Listing 14.3 demonstrates how to define an ECMAScript function in order to dynamically generate multiple Archimedean spirals with a mesh pattern generated with multiple fixed points.

Listing 14.3 multiArchimedesEllipses2FP4.svg

start example
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"   "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg width="100%" height="100%" onload="init(evt)"      xmlns="http://www.w3.org/2000/svg">   <script type="text/ecmascript">     <![CDATA[     var basePointX    = 400.;     var basePointY    = 250.;     var currentX      = 0.;     var currentY      = 0.;     var offsetX       = 0.;     var offsetY       = 0.;     var fpCount       = 4.;     var fixedPointsX  = Array(fpCount);     var fixedPointsY  = Array(fpCount);     var index         = 0.;     var radius        = 0.;     var minorAxis     = 4.;     var majorAxis     = 8.;     var spiralCount   = 4.;     var constants     = Array(spiralCount);     var angle         = 0.;     var maxAngle      = 720.;     var angleDelta    = 2.;     var shortPause    = 0.;     var eStrokeWidth  = 1.;     var lStrokeWidth  = 1.;     var fillColor     = "";     var style         = "";     var ellipseColors = ['red','green',                         'blue','yellow'];     var colorCount    = 4;     var ellipseNode   = null;     var svgDocument   = null;     var target        = null;     var gcNode        = null;     function init(event)     {        target = event.getTarget();        svgDocument = target.getOwnerDocument();        gcNode = svgDocument.getElementById("gc");        initializeFixedPoints();        drawSpiral();     }     function initializeFixedPoints()     {        fixedPointsX[0] = 700.;        fixedPointsY[0] = 100.;        fixedPointsX[1] = 100.;        fixedPointsY[1] = 100.;        fixedPointsX[2] = 100.;        fixedPointsY[2] = 400.;        fixedPointsX[3] = 700.;        fixedPointsY[3] = 400.;     } // initializeFixedPoints     function drawSpiral()     {        constants[0] = 0.25;        constants[1] = 0.50;        constants[2] = 0.75;        constants[3] = 1.00;        for(angle=0; angle<maxAngle; angle+=angleDelta)        {           for(var c=0; c<spiralCount; c++)           {              radius = constants[c]*angle;              offsetX = radius*Math.cos(                           angle*Math.PI/180);              offsetY = radius*Math.sin(                           angle*Math.PI/180);              currentX = basePointX+offsetX;              currentY = basePointY-offsetY;              ellipseNode = svgDocument.createElement(                                             "ellipse");              fillColor = ellipseColors[                                 (c+angle)%colorCount];              style  = "fill:"+fillColor;              style += ";stroke:red;";              style += "stroke-width:"+eStrokeWidth;              ellipseNode.setAttribute("style",style);              ellipseNode.setAttribute("cx", currentX);              ellipseNode.setAttribute("cy", currentY);              ellipseNode.setAttribute("rx", majorAxis);              ellipseNode.setAttribute("ry", minorAxis);              gcNode.appendChild(ellipseNode);           }           for(var v=0; v<fpCount; v++)           {              addLineFP(currentX,                        currentY,                        fixedPointsX[v],                        fixedPointsY[v]);           }        }        function addLineFP(currentX, currentY, fpX, fpY)        {           index = Math.abs(currentX+currentY);           fillColor = ellipseColors[index%2];           style  = "stroke:"+fillColor;           style += ";stroke-width:"+lStrokeWidth;           lineNode = svgDocument.createElement("line");           lineNode.setAttribute("style",style);           lineNode.setAttribute("x1", fpX);           lineNode.setAttribute("y1", fpY);           lineNode.setAttribute("x2", currentX);           lineNode.setAttribute("y2", currentY);           gcNode.appendChild(lineNode);        } // addLineFP     } // drawSpiral   ]]> </script> <!-- ============================ --> <g  transform="translate(10,10)">   <rect x="0" y="0"         width="800" height="500"         fill="none" stroke="none"/> </g> </svg>
end example

Remarks

The SVG code in Listing 14.3 starts with a block of global ECMAScript variables, followed by the ECMAScript function init() that initializes the global variables svgDocument, target, and gcNode.

The init() function also invokes the function initializeFixedPoints(), which contains the code for populating the arrays fixedPointsX and fixedPointsY with the x-coordinate and the y-coordinate of four fixed points, respectively. The function initializeFixedPoints() is listed below:

function initializeFixedPoints() {    fixedPointsX[0] = 700.;    fixedPointsY[0] = 100.;    fixedPointsX[1] = 100.;    fixedPointsY[1] = 100.;    fixedPointsX[2] = 100.;    fixedPointsY[2] = 400.;    fixedPointsX[3] = 700.;    fixedPointsY[3] = 400.; } // initializeFixedPoints

The preceding function stores the x-coordinates of four fixed points in one array and the y-coordinates of the fixed points in another array. You can create your own variations of this example by using a different technique for assigning values to these fixed points. One variant involves generating random values as follows:

function initializeFixedPoints() {    for(var v=0; v<4; v++)    {       fixedPointsX[v] = 700*Math.random();       fixedPointsY[v] = 700*Math.random();    } } // initializeFixedPoints

The first part of the ECMAScript function drawSpiral() initializes four constants that are used as coefficients for four different Archimedean spirals:

constants[0] = 0.25; constants[1] = 0.50; constants[2] = 0.75; constants[3] = 1.00;

Since the values in the array constants are constant values, you can obviously perform the initialization of this array in the init() function or in some other convenient location.

Next, the function drawSpiral() contains a nested loop that first calculates the values of radius, offsetX, and offsetY that are used for determining the x-coordinate and the y-coordinate of the center of each new circle. These variables are calculated in a manner that is similar to the code in Listing 14.1, as shown below:

radius  = constants[c]*angle; offsetX = radius*Math.cos(angle*Math.PI/180); offsetY = radius*Math.sin(angle*Math.PI/180); currentX = basePointX+offsetX; currentY = basePointY-offsetY;

Now that values for the x-coordinate and the y-coordinate of the current point have been calculated, drawSpiral() dynamically creates a new ellipse and assigns values to the attributes style, cx, cy, rx, and ry, as shown below:

ellipseNode = document.createElement("ellipse"); fillColor = ellipseColors[(c+angle)%colorCount]; style  = "fill:"+fillColor; style += ";stroke:red;"; style += "stroke-width:"+eStrokeWidth; ellipseNode.setAttribute("style",style); ellipseNode.setAttribute("cx", currentX); ellipseNode.setAttribute("cy", currentY); ellipseNode.setAttribute("rx", majorAxis); ellipseNode.setAttribute("ry", minorAxis); gcNode.appendChild(ellipseNode);

The last portion of the ECMAScript function drawSpiral() contains a loop that is inside the outer loop (but outside the nested loop) that adds line segments by invoking the ECMAScript function addLineFP():

for(var v=0; v<fpCount; v++) {    addLineFP(currentX,              currentY,              fixedPointsX[v],              fixedPointsY[v]); }

The ECMAScript function addLineFP() contains the code for creating a new SVG line element and assigning values to the line-related attributes style, x1, y1, x2, and y2:

function addLineFP(currentX, currentY, fpX, fpY) {    index = Math.abs(currentX+currentY);    fillColor = ellipseColors[index%2];    style  = "stroke:"+fillColor;    style += ";stroke-width:"+lStrokeWidth;    lineNode = document.createElement("line");    lineNode.setAttribute("style",style);    lineNode.setAttribute("x1", fpX);    lineNode.setAttribute("y1", fpY);    lineNode.setAttribute("x2", currentX);    lineNode.setAttribute("y2", currentY);    gcNode.appendChild(lineNode); } // addLineFP

The last portion of the SVG document renders a rectangle whose id attribute has the value gc, which is used for adding the ellipses and the line segments:

<!-- ============================ --> <g  transform="translate(10,10)">   <rect x="0" y="0"         width="800" height="500"         fill="none" stroke="none"/> </g>

This example concludes the discussion of ECMAScript functions for this chapter, and you'll probably be happy to know that you are now able to understand virtually all the code samples on the CD-ROM!



   



Fundamentals of SVG Programming. Concepts to Source Code
Fundamentals of SVG Programming: Concepts to Source Code (Graphics Series)
ISBN: 1584502983
EAN: 2147483647
Year: 2003
Pages: 362

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net