gamelan
Search EarthWeb
CodeGuru | Gamelan | Jars | Wireless | Discussions
Navigate developer.com
Architecture & Design  
Database  
Java
Languages & Tools
Microsoft & .NET
Open Source  
Project Management  
Security  
Techniques  
Voice  
Web Services  
Wireless/Mobile
XML  
Technology Jobs  

   Developer.com Webcasts:
  The Impact of Coding Standards and Code Reviews

  Project Management for the Developer

  Defining Your Own Software Development Methodology

  more Webcasts...




See the Winners!


Developer Jobs

Be a Commerce Partner
PDA Phones & Cases
Web Design
Boat Donations
Promotional Gifts
Home Improvement
Car Donations
Web Hosting Directory
Memory
Best Price
Calling Cards
Promotional Pens
Imprinted Promotions
GPS
Computer Hardware

 


Hyper-V: The Killer Feature in Windows Server 2008
It's fair to say that while many of the other new features are evolutionary, Hyper-V, by contrast, is revolutionary. Paul Rubens explores Microsoft's big step into virtualization. »

 
Download the Windows Server 2008 Trial
With Windows Server 2008 you can develop, deliver, and manage rich user experiences and applications, provide a secure network infrastructure, and increase technological efficiency and value within your organization. »

 
Reduce Complexity and Costs with Microsoft Identity and Access Solutions
Your organization depends on making digital information accessible to a broad spectrum of users over range of devices and networks. Register now for free Identity and Access Solutions from Microsoft. »

 
Virtualization from the Data Center to the Desktop
Integrated virtualization solutions from Microsoft can help you meet evolving demands more effectively as you transform your IT infrastructure from a cost center to a strategic business asset. »
Related Article -
Using the Java 2D BandCombineOp Filter Class to Process Images
Writing Java Servlets to Produce XHTML Code That References External SVG Files
Using the Java 2D LookupOp Filter Class to Scramble and Unscramble Images
Using Java to Produce SVG Code in XHTML Data
Using the Java 2D AffineTransformOp Filter Class to Process Images
An Improved Approach for Creating SVG/XML Code and SVG/XML DOM Nodes using Java
Java JAXP, Creating Graphics Using Java and SVG
Developer News -
SaaS Tool Offers Custom Database Development    May 9, 2008
Microsoft’s Automated Agent: Can We Talk?    May 7, 2008
Borland Finally Sells CodeGear    May 7, 2008
Red Hat Heads For The JON 2.0    May 7, 2008
Free Tech Newsletter -

Best Practices for Developing a Web Site: Checklists, Tips, Strategies & More. Download Exclusive eBook Now.

Drawing grids, Bézier Curves and Elliptical Arcs Using Java and SVG
By Richard G. Baldwin

Java Programming Notes # 2220


Preface

General

Although Bézier is the proper spelling of Pierre Bézier's name, the use of the special character as the second character in the name makes it very difficult to compose text using a standard computer keyboard.  The name will appear dozens of times in this lesson.  Therefore, to make it easier to compose the remainder of this tutorial, I will take the liberty of spelling it Bezier.

Part of a series

This lesson is part of a series (see Resources) with the following major objectives:

  • To teach you how to write Java code that will produce SVG/XML output, which can be rendered in graphic form by an SVG graphics engine such as Firefox 1.5.
  • To teach you how to write servlets that will produce SVG/XML output, which can be rendered in graphic form by an SVG-capable browser such as Firefox 1.5.

What you have learned

In previous lessons, you have learned:

  • How to write Java code that will deposit SVG/XML code into an output file that I refer to as an SVG file.
  • How to write Java code that will deposit in-line SVG code into an XHTML file.
  • How to write Java servlet code that will deposit in-line SVG code into XHTML code in the servlet's output data stream.
  • How to write Java code that will create an output XHTML file that references an external SVG file.
  • How to write Java servlet code that will create an output XHTML data stream that references an external SVG file.
  • How to write a Java/SVG graphics library that removes much of the pain from writing Java code to produce SVG/XML output.
  • How to program and use many of the features of SVG to produce rich graphics in an SVG-capable browser window.

The servlet objective has been satisfied

At this point, I believe that I have satisfied the second objective listed above involving servlets.  However, even though I have taught you a lot about the many features of SVG, there are other important features that I have not yet covered.  Therefore, the first objective listed above has not yet been satisfied.

Will assume that you understand SVG/servlet code in general

Beginning with this lesson, most of the remaining lessons in this series will assume that once you understand how to write Java code to implement a particular SVG feature, you will already understand how to incorporate that Java code into a servlet such that the output data stream from the servlet will deposit that SVG code into an XHTML data output stream.  Consequently, I will have little to say about servlets in the remaining lessons in the series, and will concentrate on helping you to understand how to write the Java code necessary to take advantage of various SVG features.  Typically, the sample programs will produce output SVG files that can be rendered in graphic form by an SVG graphics engine such as Firefox 1.5.

What you will learn in this lesson

In this lesson you will learn how to write Java code that uses an SVG graphics library and the SVG path element to efficiently draw grid lines, geometric shapes, cubic Bezier curves, quadratic Bezier curves, and elliptical arcs.

An SVG graphics library

In earlier lessons, I taught you how write your own Java SVG graphics library to eliminate, or at least alleviate the requirement to write raw XML code or raw JAXP DOM code.  The use of the SVG graphics library makes it possible for you to produce SVG output simply by making typical Java method calls.  I updated my version of the Java SVG graphics library to contain several new methods for use in this lesson.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

  • Figure 1. The graphic output from the program.
  • Figure 2. Sample cubic Bezier curves.
  • Figure 3. Sample d attribute value for a cubic Bezier curve.
  • Figure 4. Combinations of large-arc-flag and sweep-flag.
  • Figure 5. A portion of the SVG/XML code for the grid.
  • Figure 6. A text element.
  • Figure 7. XML code for the red cubic Bezier curve.
  • Figure 8. XML code for the green cubic Bezier curve.
  • Figure 9. XML code for the blue cubic Bezier curve.

Listings

Supplementary material

I recommend that you also study the other lessons in my extensive collection of online Java tutorials.  You will find a consolidated index at www.DickBaldwin.com.

General background information

What is a path element?

Paraphrasing the information in the SVG documentation, an SVG path represents the outline of a shape.  The shape can be filled, stroked, used as a clipping path, or any combination of the three.  It can also be used to cause text to be positioned on curving lines, which will be the topic for a future lesson.

A path is described using the concept of a current point.  In an analogy with drawing on paper, the current point can be thought of as the current location of the pen. The position of the pen can be changed, and the outline of a shape can be traced by dragging the pen in either straight lines or curves.  The shape can be either open or closed.

Paths represent the geometry of the outline of a shape, defined in terms of the following commands:

  • moveto (set a new current point)
  • lineto (draw a straight line)
  • curve (draw a curve using a cubic or quadratic Bezier curve or an elliptical arc)
  • closepath (close the current shape by drawing a straight line to the last moveto point)

A path is defined in SVG using the path element.

The required d attribute

A path element can have a large number of optional attributes.  It appears from the documentation that all but two are common attributes that can be applied to many different elements such as the attributes named transform, style, etc.

It also appears from the documentation that there are at least two attributes that are specific to a path element:

  • d="path data"
  • pathLength = "number"

A required data set

The d attribute is required while the pathLength attribute is optional.  The value for the d attribute must be a data set that describes the path.  In other words, the data in the data set is the definition of the outline of the shape.

In summary, a path is defined by defining a path element, which contains a d attribute, where the d-attribute value contains the moveto, lineto, curve, and closepath commands and the associated coordinate values necessary to define the outline of the shape.

Syntax of the path data set

The syntax of the path data set is designed to minimize download time and associated bandwidth requirements for downloading and drawing the path.  The following rules generally describe the syntax of the value of the d attribute:

  • For download efficiency, all instructions (commands) are expressed using a single character.  For example, a moveto command is expressed as either M or m.
  • Superfluous white space and separators such as commas can be eliminated.  For example, "M 100 100 L 200 200" contains unnecessary spaces and could be expressed as "M100 100L200 200".
  • The command letter can be eliminated on subsequent commands if the same command is used multiple times in a row.  For example, you can drop the second "L" in "M 100 200 L 200 100 L -100 -200" and use "M 100 200 L 200 100 -100 -200" instead.
  • Relative versions of all commands are available (uppercase means absolute coordinates, lowercase means relative coordinates).
  • For the relative versions of the commands, all coordinate values are relative to the current point at the start of the command.
  • Alternate forms of the lineto command are available to optimize the special cases of horizontal and vertical lines.
  • Alternate forms of the curve command are available to optimize the special cases where the first control point on the current segment can be determined automatically from the last control point on the previous segment.
  • The path data syntax is a prefix notation (commands are followed by parameters).
  • The only allowable non-numeric characters for numeric parameter values are the minus ("-") and period (".") characters.  No other delimiter characters are allowed within the parameter value. (For example, the following is an invalid numeric value in path data: "13,000.56".)

The commands

If I counted correctly, there are twenty single-character commands that fall in four general categories.  The four categories and their single character commands are given below:

  • moveto:  M or m
  • closepath:  Z or z
  • lineto
    • L or l (general lineto, [note the lowercase L])
    • H or h (horizontal lineto)
    • V or v (vertical lineto)
  • curve:
    • Cubic Bezier: C, c, S, and s (will explain in detail later)
    • Quadratic Bezier: Q, q, T, and t (will explain in detail later)
    • Elliptical arc: A and a (will explain in detail later)

Recall that the uppercase version of each command indicates that the coordinate values following the command are to be interpreted as absolute values and the lowercase version of the command indicates that the coordinate values following the command are to be interpreted as being relative to "the current point at the start of the command."

The information in the above list is provided mainly to give you an overview.  I will discuss the different categories and their commands in much more detail later in this lesson.

The graphic output from the program

Figure 1 shows the graphic output that is produced by the program that I will present and explain in this lesson.

Figure 1. The graphic output from the program.

Figure 1 illustrates a diagonal line, grid lines that give the appearance of graph paper, a simple triangle composed of straight lines, three different cubic Bezier curves, one quadratic Bezier curve, and six elliptical arcs.  Each of the shapes in Figure 1 was designed to illustrate one or more features of the SVG path element.  I will refer back to Figure 1 frequently throughout the remainder of this lesson.

The SVG graphics library

Throughout most of the earlier lessons in this series, I have been using a Java/SVG graphics library of my own design to make it easier to generate the detailed SVG/XML code required to render SVG graphics in an SVG-capable graphics engine.  In several previous lessons, I have updated the library to add new functionality, and this lesson is no exception.

I added the following new methods to my Java SVG graphics library for this lesson.

  • makePath
  • makeGridString
  • makeText

I will present and explain the code for these methods later.  At this point, however, we are still viewing the graphics process from a somewhat higher level and we don't need to know the details of the code.

The moveto command

The moveto commands (M or m) establish a new current point. The effect is as if the "pen" were lifted from the paper and moved to a new location where it is then dropped back onto the paper.  A path data segment must begin with a moveto command. Subsequent moveto commands represent the start of a new sub-path.  (Note, however, that I don't deal with multiple sub-paths in this lesson.)

Some special cases.
If a relative moveto (m) appears as the first element of the path, it is treated as a pair of absolute coordinates. If a moveto is followed by multiple pairs of coordinates, the subsequent pairs are treated as implicit lineto commands.
The moveto command must be followed by a pair of coordinate values that specify the new current point.  Depending on whether the command is an uppercase M or a lowercase m, the coordinate values may be either absolute or relative.  The moveto command starts a new sub-path at the location specified by the coordinate values.

Working with straight lines

The lineto command

The various lineto commands draw straight lines from the current point to a new point that is specified by a pair of coordinate values following the command.

The L or l lineto command

This command draws a line from the current point to the specified coordinate which becomes the new current point.  As usual, uppercase L indicates that absolute coordinates will follow.  Lowercase l indicates that relative coordinates will follow.

A number of coordinate pairs may be specified to draw a polyline (not to be confused with a polyline element). At the end of the command, the new current point is set to the final set of coordinates provided.

The H or h lineto command

This is a special case of the lineto command that requires only a single coordinate value following the command.  The single coordinate value is a new horizontal coordinate.  This command draws a horizontal line from the current point to the new horizontal coordinate at the same vertical coordinate.  (This command was used to draw the horizontal lines in the blue background grid in Figure 1.)

The V or v lineto command

This is another special case of the lineto command that requires only a single coordinate value following the command.  The single coordinate value is a new vertical coordinate.  This command draws a vertical line from the current point to the new vertical coordinate at the same horizontal coordinate.  (This command was used to draw the vertical lines in the blue background grid in Figure 1.)

The closepath command

The closepath command (Z or z) ends the current sub-path and causes an automatic straight line to be drawn from the current point to the initial point of the current sub-path.

If a closepath is followed immediately by a moveto, then the moveto identifies the start point of the next sub-path. If a closepath is followed immediately by any other command, then the next sub-path starts at the same initial point as the current sub-path.

The light blue grid pattern

The first thing that I will call your attention to in Figure 1 is the blue grid of straight horizontal and vertical lines that causes the image to resemble a sheet of graph paper.

Why use the path element to draw straight lines?

You learned about the line and polyline elements in earlier lessons in this series (see Resources).  The reality is that the use of the path element to draw straight lines is conceptually more difficult than the use of the line element to draw straight lines.  This may cause you to wonder why you would ever use the path element to draw straight lines.  The reason is that in some cases, (such as the drawing of the background grid in Figure 1), the use of the path element can significantly reduce the size of the XML data download and the corresponding bandwidth requirements.

XML data required for a line element

Note the light blue diagonal line in Figure 1.  This line was drawn using a line element, and its only purpose for being in Figure 1 is to illustrate the improved download efficiency of the path element relative to the line element in certain cases.

The XML code required to draw this line and to set its color to light blue consisted of a total of 74 characters.  This total would not change significantly with changes in the length or the orientation of the line.

Downloading 74 characters to draw a line is not a problem if you are drawing only a few lines.  However, the light blue background grid in Figure 1 contains 45 horizontal lines and 45 vertical lines for a total of 90 lines.  If each of those 90 lines had been drawn and colored using an individual line element, approximately 6660 XML characters would have been required to draw all 90 lines.

Using a path element instead

As you will see later, I developed a method named makeGridString that uses special horizontal and vertical lineto commands of the path element to reduce the download size and attendant bandwidth requirements for drawings that contain a large number of horizontal and vertical lines in a uniform grid pattern.  This method returns a string, which is used as the value for the attribute named d for a path element that draws the lines described by the contents of the string.  Although the code to accomplish this is somewhat more complicated than would be the case for drawing the grid using simple line elements, the download size and bandwidth requirements are significantly reduced with the use of the path element.

A significant reduction in XML data volume

polyline is more efficient than line.
I also wrote a test program and determined that the amount of XML code required to draw the light blue grid using a polyline element was about 1325 characters.   Thus, the path element is also more efficient than the polyline element, but not by nearly as large a factor as when compared to the repeated use of the line element to draw the grid.
If I counted correctly, the XML code required to draw and color all 90 of the light blue horizontal and vertical grid lines in Figure 1 using a path element consists of about 1150 characters.  Thus, the use of the path element to draw the light blue background grid reduced the amount of XML data by almost a factor of 6 relative to the amount required to draw and color the grid using individual line elements.

The red and blue triangle

Next, I want to call your attention to the red triangle with the blue border in the upper left corner of Figure 1.  I used the moveto, lineto, and closepath commands to draw this triangle.  In fact, this program uses one absolute moveto command, one absolute lineto command, and one relative lineto command plus the closepath command to draw the triangle.  Once the triangle had been drawn, separate calls to the setAttribute method were made to fill the triangle with red and to give it a blue border.

The triangle was drawn solely to illustrate the use of the path element and the commands listed above.  In reality, it would probably have been easier to use simple line elements to draw this triangle than to draw it using the path element.

Working with text

The use of text in SVG is an extensive topic, one facet of which is to create a curved path and then to render the text along that path instead of simply rendering it along a straight line.  Text will be the primary topic of a future lesson.

However, I needed to put numeric labels on the graph shown in Figure 1 to make it easier to read coordinate values off the graph.  As you will see later, I added a makeText method to my SVG graphics library to make this relatively easy to accomplish.

Working with Bezier curves

When you need to draw smooth curves to connect points, the path element has a lot more to offer than just a reduction in the XML data volume, although it has that to offer also.  For this situation, the use of the path element also makes it possible to do some things relatively easily that could be very difficult to do otherwise.

Experimenting with Bezier curves.
If you would like to learn a little more about cubic Bezier curves and have some fun in the process, take a look at the interactive Bezier Curve Demo in Resources(Also see Figure 2.)
Cubic Bezier Curves

A Bezier curve is a smooth curve that is used to connect two points.  SVG supports both quadratic and cubic Bezier curves.  Initially, this discussion will be centered on cubic Bezier curves.  Then it will move to quadratic Bezier curves.

Bezier curves according to Darrel Plant

While describing cubic Bezier curves, Darrel Plant tells us, "Almost any type of curve that contains one or two changes in direction can be described by a Bézier equation."  (See "What's a Bézier Curve?" in Resources)  He goes on to describe how cubic Bezier curves can also be used to describe loops and other complex shapes.

Sample cubic Bezier curves

Figure 2 shows four different cubic Bezier curves that I created interactively using the Bezier Curve Demo in Resources.

Figure 2. Sample cubic Bezier curves.

In each of the individual images in Figure 2, the curved line is the actual Bezier curve (or Bezier segment).  The straight lines connect the start point, two control points, and the end point that I will explain in the next section.

A Bezier segment.
The SVG documentation refers to the four points and the curve that they produce as a Bezier segment.  Thus, a Bezier curve may be made up of one or more Bezier segments.
Drawing a Bezier segment

The locations of four points in coordinate space must be specified to draw a cubic Bezier segment.  There is a start point, two control points, and an end point.  The segment is drawn from the start point to the end point.  The locations of the two control points determine the shape of the curve as it winds its way from the start point to the end point.  Figure 2 shows some good examples of how the locations of the two control points, relative to the locations of the start point and the end point impact the shape of the actual Bezier curve or segment.

Special forms of the path element in SVG

With SVG, cubic Bezier segments are drawn using any one of several special forms of the path element.  There are four single-character commands that can be used in the specification of the locations of the points:  C, c, S, and s.

For example, Figure 3 shows the beginning of the XML path element that produced the red Bezier curve shown immediately down and to the right of the red and blue triangle in Figure 1.

Figure 3. Sample d attribute value for a cubic Bezier curve.
<path
 d="M100,100 C100,50 175,50 175,100 S250,150 250,100"

The C-command and the S-command are highlighted in boldface red in Figure 3 to make them easy to for you to spot.  (They would not be red in the actual XML code.)

Either absolute or relative coordinates

Keeping the text uncluttered.
To keep the text from becoming too cluttered, the remainder of this discussion on Cubic Bezier curves will use the uppercase version of the commands, although in many cases the lowercase version could also be used.
Once the start point has been established, the coordinates of the other three points can be specified either in absolute coordinates or in coordinate values that are relative to the location of the start point.  If the uppercase command is used, the coordinate values are interpreted to be absolute.  If the lowercase command is used, the coordinate values are interpreted to be relative. 

Poly-Bezier curves

The specifications for multiple Bezier segments can be strung together following a Bezier command to create a poly-Bezier curve.  For example, each of the images shown in Figure 2 is a single Bezier segment.  On the other hand, the red Bezier curve shown near the upper left in Figure 1 consists of two Bezier segments concatenated end to end and is therefore a poly-Bezier curve.

For the case of poly-Bezier curves, each group of three coordinate values following the original Bezier segment is interpreted to represent the specification of a new Bezier segment.  The start point for the new segment is assumed to be the end point from the previous segment, and hence serves as the first of the four points that are required to specify a cubic Bezier segment.

Difference between C and S Bezier commands

Of the two types of Bezier commands, (C and S), C is the more general of the two.  The C command can be used for a single Bezier segment or for the construction of a poly-Bezier curve.  However, the S command applies only to the construction of a poly-Bezier curve.

A reflected point.
In case you aren't certain what I mean when I speak of the reflection of a point, see the links to the reflection articles in Resources.
When the S command is used to specify the four required points for the next segment, only the second control point and the end point are actually specified.  As is always the case for a poly-Bezier curve, the start point for the next segment is assumed to be the end point from the previous segment.  However, when an S command is used, the first control point for the new segment is assumed to be the reflection of the second control point from the previous segment, leaving only two points that must actually be specified for the new segment.

Quadratic Bezier curves

A quadratic Bezier segment is defined by a start point, an end point, and only one control point.  As with the cubic Bezier segment, there are four commands that are used to specify the locations of the three required points:  Q, q, T and t.  The uppercase commands imply that the coordinate values are absolute while the lowercase commands imply that the coordinate values are relative to the location of the start point.

The Q and q commands for the quadratic segment have essentially the same meaning as the C and c commands for the cubic segment.  The T and t commands for a quadratic segment have essentially the same meaning as the S and s commands for the cubic segment.

The Bezier curves in Figure 1

Figure 1 contains three cubic Bezier curves colored red, green, and blue, and one quadratic Bezier curve colored red.  I will have more to say about each of these curves in conjunction with the explanation of the Java code that produced them.

Working with elliptical arcs

Seven parameters are required

An elliptical arc command is perhaps the most complex of all of the curve commands.  Each elliptical arc command requires seven parameters in the following order:

  1. rx specifies the horizontal radius of the ellipse
  2. ry specifies the vertical radius of the ellipse
  3. x-axis-rotation specifies the rotation of the ellipse relative to the current coordinate system
  4. large-arc-flag (will discuss in detail later)
  5. sweep-flag (will discuss in detail later)
  6. x specifies the horizontal location of the end point of the arc
  7. y specifies the vertical location of the end point of the arc

Behavior of the elliptical arc command

The command draws an elliptical arc beginning at the current point and ending at the location specified by x and y.

The coordinates of the center of the ellipse are calculated automatically to satisfy the constraints imposed by the other parameters.  The large-arc-flag and sweep-flag parameters contribute to the automatic calculations and help determine how the arc is drawn.

The large-arc-flag and sweep-flag parameters

Each of the parameters named large-arc-flag and sweep-flag can have a value of 0 or 1.  This results in four possible combinations of these two parameters.  Thus, there are actually four different arcs (two different ellipses, each with two different arc sweeps), only one of which can satisfy the constraints imposed by a specific combination of these two parameters. 

The rules for drawing elliptical arcs

The combination of large-arc-flag and sweep-flag indicates which one of the four arcs will be drawn according to the following rules:

  • Of the four candidate arcs, two represent an arc sweep of greater than or equal to 180 degrees.  This is a large arc.  The other two candidates represent an arc sweep of less than or equal to 180 degrees.  This is a small arc.

    If the value of large-arc-flag is 1, one of the two larger arc sweeps will be chosen.

    If the value of large-arc-flag is 0, one of the smaller arc sweeps will be chosen,
     
  • The arc is drawn by evaluating the following equations where cx and cy are the coordinates of the center of the ellipse:

    x = cx + rx*cos(theta)
    y =cy + ry*sin(theta)

    If the value of sweep-flag is 1, then the equations are evaluated such that theta starts at an angle corresponding to the current point and increases positively until the arc reaches the end point.

    If the value of sweep-flag is 0, the equations are evaluated such that theta starts at an angle value corresponding to the current point and decreases until the arc reaches the end point.

Elliptical arcs in the graphical output

Six elliptical arcs are shown in Figure 1.  The yellow arc with the red border and the red arc with the yellow border illustrate the effect of the x-axis-rotation parameter on the appearance of the arc.  The yellow arc with the red border was drawn with an x-axis-rotation parameter value of 0.  The red arc with the yellow border was drawn with an x-axis-rotation parameter value of 45 degrees.

In both cases, the start point was at the bottom of the straight-line segment on the left and the end point was at the top of the straight-line segment.

Also in both cases, the value of large-arc-flag was 1 and the value of sweep-flag was 0.  Thus, as explained above, one of the two larger arc sweeps was chosen in each case.  Also as explained above, the equations were evaluated such that theta started at an angle value corresponding to the current point and decreased until the arc reached the end point.

 Combinations of large-arc-flag and sweep-flag

Each of the other four elliptical arcs at the bottom of Figure 1 represents one of the four possible combinations of large-arc-flag and sweep-flag with an x-axis-rotation parameter value of 0.  Note that in each case, the horizontal and vertical radii were the same, causing the elliptical arc to actually be a circular arc.  Also note that in each case, the start point of the elliptical arc was at the bottom of the straight-line segment.

Figure 4 shows the different combinations of these two parameters for each elliptical arc going from left to right across Figure 1.  Hopefully a comparison of these parameter values with the images in Figure 1 will help you to understand the impact of each of the two parameters on the appearance of the elliptical arc.

Figure 4. Combinations of large-arc-flag and sweep-flag.
Case 1: Fill color = red, border = blue
 large-arc-flag = 1
 sweep-flag     = 0
    
Case 2: Fill color = green, border = red
 large-arc-flag = 1
 sweep-flag     = 1
    
Case 3: Fill color = blue, border = red
 large-arc-flag = 0
 sweep-flag     = 0
    
Case 4: Fill color = yellow, border = blue
 large-arc-flag = 0
 sweep-flag     = 1

The large-arc flag

The behavior of the large-arc-flag is pretty straightforward and easy to understand.  Basically the value of the large-arc-flag determines whether the large portion or the small portion of the ellipse will be displayed.  If the large-arc-flag has a value of 1, the large portion of the ellipse will be displayed.  If the large-arc-flag has a value of 0, the small portion will be displayed.

The sweep-flag

The behavior of the sweep-flag is not so straightforward, at least not for me anyway.  The value of the sweep-flag determines which side of the straight-line segment the portion selected by the large-arc-flag will be displayed on.  However, the difference between right and left in this case depends on the locations of the start point and the end point.  Although I haven't worked out the math, I feel reasonably confident in saying that if you stand at the start point and look toward the end point, the arc will be displayed on your right if the sweep-flag has a value of 0, and will be displayed on your left if the sweep-flag has a value of 1.

Preview

I will present and explain a program named Svg12 in this lesson.  The primary purpose of this program is to teach you how to use an SVG path element to draw straight lines, Bezier curves, and elliptical arcs.  The program produces a single SVG file as its output.  The graphic output shown in Figure 1 was produced by rendering the SVG output file using Firefox 1.5.

As is my custom, I will present and explain the program in fragments.  You can view a listing of the entire program in Listing 17 near the end of the lesson.

Discussion and sample code

Description of the program

Overall, the program creates a DOM tree that describes the graphic image shown in Figure 1 in SVG format and writes it out into an SVG file named Svg12.svg.  The output file produced by this program can be rendered by loading it into Firefox 1.5.

The path element

The main purpose of this program is to demonstrate the use of a Java method of my own design named makePath to create the SVG/XML output code necessary to produce the graphic elements shown in Figure 1.  A secondary purpose is to demonstrate the use of a second Java method of my own design named makeGridString.

I updated my SVG graphics library during the writing of this program to add several new methods, including makePath and makeGridString, and to update some of the default values for existing methods as well.

A diagonal blue line

The program uses a line element to draw a diagonal line from the top left corner of Figure 1 to the lower right corner.  The purpose of this line was to provide information about the line element that could be used to calculate the improvement in download efficiency provided by the path element relative to the line element for certain cases involving straight lines.

A background grid

What color is graph paper?
In retrospect, thinking back to the days when I actually used graph paper, I probably should have made the background grid green.  Then it would look even more like the graph paper that I remember from those days.
After taking care of all the preliminary stuff that I have explained in earlier lessons, the program uses the new method named makeGridString in conjunction with the new method named makePath to draw a light blue background grid that resembles graph paper.  The makeGridString method uses the moveto command and special versions of the horizontal and vertical lineto command to reduce the amount of SVG/XML data needed to draw the grid.

As you can see in Figure 1, there are light blue horizontal and vertical lines every 10th pixel.  There are slightly darker blue lines every 50th pixel.  There are even darker blue lines every 100th pixel.

The text labels

The program uses a new Java method of my own design named makeText to place black text labels on the blue lines that mark every 50th pixel.

A red triangle with a blue border

Then the program uses the moveto, lineto, and closepath commands to draw a triangle.  The setAttribute method is used to fill the triangle with solid red color and to give it a blue border.

Three cubic Bezier curves

The program draws three cubic Bezier curves, one red, one green, and one blue, illustrating the effect that the locations of the control points have on the shape of the curve.

One quadratic Bezier curve

Then the program overlays a red quadratic Bezier curve on the blue cubic Bezier curve, illustrating the difference in the degree to which the cubic and quadratic Bezier curves fit the same envelope, where the envelope is defined by the start point, the control point(s), and the end point.

Elliptical arc rotation

The program draws two elliptical arc curves to illustrate the effect of the x-axis-rotation parameter on the appearance of the elliptical arcs.  The yellow arc with the red border has a rotation value of zero, while the red arc with the yellow border has a rotation value of 45 degrees.  Otherwise, the two elliptical arcs were drawn with the same parameter values.

Combinations of large-arc-flag and sweep-flag parameters

Finally, the program draws four more elliptical arc curves, illustrating the difference in shape that results from all four combinations of the large-arc-flag and sweep-flag parameters.

Program testing

The program was tested using J2SE 5.0, Firefox v1.5.0.8, and WinXP.

The beginning of the class named Svg12

The class named Svg12 begins in Listing 1.

Listing 1. The beginning of the class named Svg12.
public class Svg12{

  public static void main(String[] args){
    int width = 450;
    int height = 450;

    //Begin by creating a DOM tree that represents the XML
    // code that will render to produce the image of
    // interest.

    //Get the Document object.
    Document document = SvgGraphics.getDocument();

    //Create the root node named svg and append it to the
    // document.  Specify the parent as null for the
    // special case where the parent is the document.
    Element svg = SvgGraphics.makeNode(
        document,
        null,//parent
        "svg",//node type
        new String[]{"xmlns","http://www.w3.org/2000/svg",
                     "version","1.1",
                     "width",""+ (width + 2),
                     "height","" + (height + 2),
                     "position","absolute",
                     "top","0",
                     "left","0",
                    });//end makeNode method

    //Create a node named g, which will be the parent for
    // several graphic elements. Pass null for the
    // reference to the array object for the special case
    // where the node has no attributes.
    Element g = SvgGraphics.makeNode(document,
                                     svg,//parent
                                     "g",
                                     null);

I have explained the material in Listing 1 in previous lessons, so I won't repeat that explanation here.

Draw a diagonal line

Listing 2 calls the makeLine method to draw a diagonal line from the upper left corner to the bottom right corner in Figure 1, and then calls the setAttribute method to color it blue.

Listing 2. Draw a diagonal line.
    Element diagLine = SvgGraphics.makeLine(
                                  document,g,0,0,450,450);
    diagLine.setAttribute("stroke","#8888ff");

I explained both of these methods in earlier lessons, and won't repeat that explanation here.

Draw the light blue grid lines

Listing 3 calls the makeGridString method followed by the makePath method and the setAttribute method to draw the light blue grid lines on a ten-pixel spacing in Figure 1.  This is the first of three sets of grid lines, followed by a set on 50-pixel spacing and a set on 100-pixel spacing.

Listing 3. Draw the light blue grid lines.
    //First draw light blue grid lines every 10 pixels.
    String gridData = SvgGraphics.makeGridString(
                                         width,height,10);
    //Create the path element.
    Element temp;
    temp = SvgGraphics.makePath(document,g,gridData);
    //Set the color to light blue.
    temp.setAttribute("stroke","#ccccff");

Both the makeGridString method and the makePath method are new to this lesson, so I will put the discussion of the main method on hold while I explain these two methods.  I will explain them in reverse order because, in effect, the makeGridString method is a helper method for the makePath method.  Therefore, I will explain the makePath method first.

The makePath method

The makePath method is shown in its entirety in Listing 4.

Listing 4. The makePath method.
  static Element makePath(Document document,
                          Element parent,
                          String d){
    Element path  = 
                  (Element)document.createElement("path");
    parent.appendChild(path);
    path.setAttribute("d",d);
    path.setAttribute("stroke","black");
    path.setAttribute("stroke-width","1");
    path.setAttribute("fill","none");
    return path;
  }//end makePath

Let me begin by reviewing what is going on here.  At this point in the program, I am constructing a DOM tree that represents the graphic image shown in Figure 1.  At this point, the objective is to create nodes in the DOM tree that will later be transformed into elements in the XML output code produced by the program.

With the exception of the diagonal line and some polylines, all of the shapes in Figure 1 will be created using an SVG/XML path element.  This includes the background grid lines.  Therefore, at this point, I need to create a node of type path and append it to the Dom tree.

Old stuff

There is nothing new about the first two parameters to the makePath method:   document and parent.  Almost all of the methods in my SvgGraphics library require these parameters and I have explained their use in earlier lessons.  There is also nothing new about the first statement or the last four statements in the method.  I have also explained these statements in earlier lessons.  That leaves only one interesting statement, and it is highlighted in boldface in Listing 4.

New stuff

In the earlier section titled The required d attribute, I explained that an SVG path element must have an attribute named d.  I also explained that the value of the d attribute must be a data set that describes the path.  In other words, the data in the data set is the definition of the outline of the shape represented by the path.

In the section titled Syntax of the path data set I explained the rules for constructing the string attribute value for the d attribute.  Briefly, that string must consist of uppercase and lowercase alphabetic commands and numeric coordinate values.

Establish the value of the attribute named d

After constructing the path node and appending it to the DOM tree, the makePath method in Listing 4 calls the setAttribute method on the path node, passing the third parameter to the makePath method as the only parameter to the setAttribute method.  Therefore, the string contents of the parameter named d will become the attribute value for the path element when the DOM tree is transformed to XML.  The