W2261 Paths

From Coder Merlin
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder

Prerequisites[edit]

Introduction[edit]

We're able to construct many graphic compositions using the tools that we've learned earlier; however, we'll need additional tools to build more complex shapes. Paths enable us to meet this need.

Lower Manhattan from Staten Island Ferry Jan 2006

Complex Shapes Using Paths[edit]

Arbitrarily complex shapes may be constructed using Paths. Paths are built of primitives enabling us to add straight lines or curves. Programmatically, there are several steps to rendering a path:

  1. Create a new path
  2. Use primitives to add lines and curves to the path
  3. Render the path


Hint.pngHelpful Hint
Practice the below using the Igis Path Demo

Try it now in a separate window.

  • You'll note that there are a series of buttons on the left hand side enabling you to add primitives to the path.
  • After clicking on the button, you'll see the new primitive added to the center of the canvas. Each primitive will have one or more control handles which you can drag to alter the parameters of the primitive.
  • On the right hand side is the actual code used to create the displayed path.
  • To begin again with a blank path, simply refresh the browser.

Adding Shapes Comprised of Straight Lines[edit]

To add a series of points forming one or more lines, we have the option to use two different primitives, moveTo and lineTo. Each of these primitives will update the current context position to the specified point.

  • To move to a new position without drawing a line, we use the moveTo() method on a path.
  • To draw a line to from the current context position to a new position we use the lineTo() method on a path.


Start button green arrow
Open your browser to Igis Path Demo
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 1

Use the moveTo(point:Point) and lineTo(point:Point) primitives to:

  • Create a horizontal line
  • Create an 'L' shape
  • Create a triangle
  • Create a rectangle
  • Create three, isolated (not connected to one another) vertical bars
  • Create a trapezoid
  • Create a rhombus


  1. What is the generalized methodology for creating straight-lined shapes?
  2. When are you required to use a moveTo primitive?


Adding Rectangles[edit]

Rather than use a moveTo() followed by four lineTo()s, we can create a rectangle with a single primitive, rect().

  • This primitive ignores the current context position and begins drawing the rectangle at the specified position (topLeft), and then updates the current context position to the same point.


Start button green arrow
Open your browser to Igis Path Demo
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 2

Use the moveTo(point:Point),lineTo(point:Point), and rect(rect:Rect) primitives to:

  • Create a rectangle
  • Create a 2D table (viewed from the side) consisting of two legs constructed with the rect() primitive and a top built using a single line constructed with the moveTo() and lineTo() primitives
  • Create a 3D table (viewed from an angle above the table)


  1. When is it useful to use the rect(rect:Rect) primitive rather than a series of moveTo(point:Point) and lineTo(point:Point)?
  2. What circumstances would cause you to opt for using a series of moveTo(point:Point) and lineTo(point:Point) rather than rect(rect:Rect)?


Adding Curves[edit]

There a several primitives available which enable us to easily draw curves. Curves rely on one or more control points and flow along the existing path from the current context position to an end point. The end point may be explicitly specified or it may be calculated as part of the curve. There are four primitives for curves: quadratic curve, Beziér curve, arc, and arcTo.

Quadratic (Beziér) Curve[edit]

A quadratic curve is technically known as a quadratic Beziér curve. The quadratic curve flows from the current context position to an explicitly specified end point. A single control point serves to pull the curve toward itself. As a starting point, consider a control point located along a straight line from the current context position to the end point:

IgisDemo-Path-QuadraticCurve-StraightLine.png

Observe what happens when we move the control point straight up:

IgisDemo-Path-QuadraticCurve-CurveUp.png

Note that the curve did not move up to the control point, but only towards the control point. To better understand how the control point influences the curve, carefully observe this annotated version which includes green lines between the control point and the other points:

IgisDemo-Path-QuadraticCurve-CurveUp-Annotated.png

Note that the curve is tangent to the annotation line between the points moveTo and control and again between control and end. Carefully observe an alternative case:

IgisDemo-Path-QuadraticCurve-CurveLeft.png

We'll draw annotation lines between the points moveTo and control and again between control and end. We again see that the curve is tangent to both of these lines.

IgisDemo-Path-QuadraticCurve-CurveLeft-Annotated.png

Here's an animated diagram demonstrating this curve:


Bézier 2 big

(Cubic) Beziér Curve[edit]

A Beziér curve is technically known as a cubic Beziér curve. It's very similar to a quadratic Beziér curve but has an additional control point:

IgisDemo-Path-CubicCurve-StraightLine.png

With additional control points, we're able to create more complex shapes. We're able to use both control points on the same side of the line:

IgisDemo-Path-CubicCurve-CurveUp.png


But we're also able to use the control points on opposite sides of the line:

IgisDemo-Path-CubicCurve-Vertical-S.png

Here's an animated diagram demonstrating this curve:


Bézier 3 big

Start button green arrow
Open your browser to Igis Path Demo
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 3

Use one or more of the moveTo(point:Point), quadraticCurveTo(controlPoint:Point, endPoint:Point) and bezierCurveTo(controlPoint1:Point, controlPoint2:Point, endPoint:Point) primitives to create the following shapes:

  • The outline of an igloo IgisDemo-Path-Igloo-Outline.png


  • The outline of a heart IgisDemo-Path-Heart-Outline.png
  1. How do you decide whether to use a quadratic Beziér curve or a cubic Beziér curve?


Arc[edit]

An arc flows from the current context position around an arc with the specified center and radius, beginning with the specified startAngle around to the specified endAngle. As an example, consider:

IgisDemo-Path-Arc.png

It's important to note that the end point is not explicitly specified but derived from the other parameters. Also, consistent with other angle specifications, angles are measured in radians from the 3 o'clock position clockwise.

ArcTo[edit]

The arcTo primitive flows from the current context position toward the first control point and then turns toward the second control point such that the specified radius of the arc is met.

IgisDemo-Path-ArcTo.png

Observe the annotated versions below and compare the different radii:

IgisDemo-Path-ArcTo-Annotated.png


IgisDemo-Path-ArcTo-Annotated3.png

Start button green arrow
Open your browser to Igis Path Demo
ObserveObserveIcon.png
Observe, Ponder, and Journal: : Section 4

Use one or more of the moveTo(point:Point), arc(center:Point, radius:Int, startAngle:Double, endAngle:Double, antiClockwise:Bool) and arc(center:Point, radius:Int, startAngle:Double, endAngle:Double, antiClockwise:Bool) primitives to create the following shapes:

  • Two circles connected with a straight line at the very top of the circles IgisDemo-Path-TwoCirclesConnectedWithStraightLine.png


  • Two circles connected with a curve between the edges at the circle center IgisDemo-Path-TwoCirclesConnectedWithCurve.png
  1. How do you decide whether to use an arc or an arcTo primitive?


Key Concepts[edit]

Key ConceptsKeyConceptsIcon.png
  • A path is built of primitives
  • The moveTo(point:Point) primitive moves the current context point to the specified location
  • The lineTo(point:Point) primitive draws a line from the current context point to the specified location
  • The rect(rect:Rect) primitive draws a rectangle as described in rect. It ignores the initial value of the current context point but does update it to topLeft.
  • The quadraticCurveTo(controlPoint:Point, endPoint:Point) primitive draws a curve which flows from the current context position to an explicitly specified end point. A single control point serves to pull the curve toward itself.
  • The bezierCurveTo(controlPoint1:Point, controlPoint2:Point, endPoint:Point) draws a curve from the current context position to an explicitly specified end point. Two control points are available to pull the curve in their direction.
  • The arc(center:Point, radius:Int, startAngle:Double, endAngle:Double, antiClockwise:Bool) draws a curve from the current context position around an arc with the specified center and radius, beginning with the specified startAngle around to the specified endAngle. The end point is not explicitly specified but derived from the other parameters.

Exercises[edit]

ExercisesExercisesIcon.png

Making use of your accumulated knowledge to date (both coding and graphics) and using only path primitives:

  1. Create a skyline (just an outline, no fill)
    1. You must include at least seven buildings
    2. At least two of the building must have a domed top
    3. You must have at least one arched bridge between buildings

Getting started:

john-williams@codermerlin:~/Projects$ git clone https://github.com/TheCoderMerlin/IgisShellD W2261

To compile:

john-williams@codermerlin:~/Projects/W2261$ ./make.sh

To execute:

john-williams@codermerlin:~/Projects/W2261$ ./run.sh

Your associated url will be: http://www.codermerlin.com/users/john-williams/dyn/index.html