Math 421  •  Fall 2010

Drawing geometric objects in the complex plane
with Presentations

26 September 2010

Based in part upon documentation written by David Park; edited and amended by Murray Eisenberg.

Explanation:  In the section "Initialization" below, there's an Input cell consisting of the expression
	<<Presentations`
and I made that cell into an "initialization cell".  When you answered yes, that cell was evaluated automatically, and this in effect loaded the Presentations application packages.

This notebook is a tutorial on doing complex graphics using the Presentations application. You may want to consult it before tackling the notebook nthRoots.nb. The latter provides additional examples.

Prerequisites

Mathematica

Most of this notebook requires that you have David Park’s Presentations add-on for Mathematica available on the computer where you are using Mathematica. (See notebook AboutPresentations.nb.)

In order to reproduce graphics output from this notebook, you must have loaded Presentations by evaluating the expression:
	<<Presentations`
That initialization is done below, in the Initialization section, below.

You should already know some of the basics about Mathematica: basic syntax; how to navigate around a Mathematica notebook; how to create an Input cell and type input into it; and how to evaluate an Input cell.

It’s a good idea to use this notebook as additional reference as you work through a notebook more substantial mathematical content, such as nthRoots.nb.

Mathematics

You should already know the basics of the algebra of complex numbers—how to add and multiply them—and the representation of complex numbers by points in the plane.

Initialization

When you opened this notebook, it should have prompted you whether you want to evaluate Initialization Cells. You should have answered “yes.”
Check now whether you did so by looking at the Input cell that follows. At its left it should have a label such as In[1].
If you do not see such a label, then evaluate the following Input cell now. (Even if the cell was already evaluated, it won’t hurt if you evaluate it again.)

<<Presentations`

Forming Complex Graphics objects

The basic method for plotting graphical objects with Mathematica is to use a Graphics[{…}] expression. Within the braces, you include commands that set the graphics directives to be used (such as color or line thickness) along with the graphics primitives that actually draw the objects (such as Point and Line). In this way, you can build up a rather complicated graphics.

The Complex Graphics part of Presentations contains a number of complex primitives that mirror the ordinary Mathematica graphics primitives, but allow complex numbers to be used instead of real coordinate pairs.

To construct a complex point use the Presentations function ComplexPoint. For example:

ComplexPoint[1+I]

The result is an ordinary Mathematica Point graphics primitive expression.

Similarly,  to construct a polygonal curve—a "broken line"—use the Presentations function ComplexLine. For example, to construct the polygonal curve that goes from 0 to 1 to 1+i to i and back to 0, you may use:

ComplexLine[{0,1,1+I,I,0}]

The result is an ordinary Mathematica Line graphics primitive expression.

The Complex Graphics primitives of this type include:  ComplexArrow, ComplexCircle, ComplexDisk, ComplexLine, ComplexPoint, ComplexPolygon, and ComplexText. Also available is the graphics primitive ComplexCurve, which draws a curve in the complex plane that is parameterized by a real variable.

Exercise . Use Complex Graphics primitives to form the triangle with vertices -1, 1, and i along with the (circumference of the) circle that passes through its vertices.

Displaying Complex Graphics: Draw2D

Just forming ordinary Mathematica graphics objects such as Point[{1,1}] or Line[{{0,0},{1,0},{1,1},{0,1},{0,0}}] does not display them. Rather, you have to include them in a Graphics[{…}] expression. For example:

Graphics[{
Point[{1,1}],Line[{{0,0},{1,0},{1,1},{0,1},{0,0}}]
}]

Likewise, forming Complex Graphics primitives such as ComplexPoint[1+i] or  ComplexLine[{0,1,1+i,i,0}] does not actually display the graphics!

To display complex graphics objects, include them within a Draw2D expression. The Presentations function Draw2D is essentially a “cover” for the built-in Mathematica function Graphics.

For example, draw a point at +1+i and the polygonal line—a square—with vertices  0, 1, 1+i, and i:

Draw2D[{
ComplexPoint[1+I],ComplexLine[{0,1,1+I,I,0}]
}]

To make the point more visible against the square, you may use color, size, or some other treatment. And to do that, use a graphics directive. A directive overrides the Draw2D default settings for drawing size, point size, line thickness, etc.

For example, make the point at 1+i large and blue, and the polygonal line red:

Draw2D[
{
(* Set color and size for drawing point *)
Blue,PointSize[Large],
(* Draw point *)
ComplexPoint[1+I],
(* Set color for plotting polygon *)
Red,
(* Draw polygon *)
ComplexLine[{0,1,1+I,I,0}]
}
]

The commands within the Draw2D expression above are broken into separate lines in order to show how to specify the directives and draw one item after another. (That’s not required, just a good style to make reading and writing code easier.) Comments, enclosed in (* … *) pairs, were included in order to make each action clear.

Normally, such “obvious” comments will not be included. It’s a good idea, though, to use a separate line of code for each object to be drawn, and a separate line of code for each set of graphics directives that affect the subsequent objects.

See what happens if you make the square thick, too:

Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[1+I],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}]
}
]

Now the point is harder to see. And one reason is that later items in the Draw3D list are drawn on top of the earlier items. If you look closely above, you will see the corner of the red square drawn on top of the blue point at +1+i.

Exercise . Make it easier to see the blue point by experimenting with the effects of:
	(a) reversing the order of the objects;
	(b) changing the point size—try, for example, PointSize[0.0275];
	(c) changing the thickness of the line—instead of Thick, try, for example, Thickness[0.005].

There are several ways to select a color, including:
	• By name, if you already know it. For example, Red, Blue, Orange, White, …. (This works only for colors in the Mathematica “System” color scheme.)
	• By selecting a color from the Mathematica Color Schemes palette.
	• By using the Presentations function Legacy. For example, Legacy[IndianRed] or, in prefix form, Legacy@IndianRed. This is just a shortcut for ColorData[“Legacy”, “IndianRed”].There are similar Presentations shortcuts for other Mathematica color schemes, for example, HTML.

To see what Legacy colors are available, evaluate:

ColorData["Legacy","ColorNames"]

For more about selecting colors, see “How to Use Colors in Mathematica” in the Documentation Center.

Exercise . (a) Change the colors of the point and line to other System colors.
(b) Change them to the Legacy colors DodgerBlue and IndianRed.
(c) Try some other colors.

Exercise . (a) Use Complex Graphics primitives to draw the figure consisting of triangle with vertices -1, 1, and i along with the (circumference of the) circle that passes through its vertices. Use suitable colors and thickness.
(b) Mark the vertices by using by using Point.
(c) Enhance marking of the vertices by using CirclePoint instead of Point.
(d) Draw the figure again, but now with the circle filled in.

Including drawing options

Draw2D automatically sets some graphics options, such as aspect ratio (of height to width), background color, and whether to include axes or a frame. You may override any of these defaults that affect the overall appearance of the entire drawing.

For example, add the plot option ImageSize. You specify the size in printer's points, and there are supposed to be 72 points to the inch. (But that depends upon the details of your graphics display and the magnification of the notebook.)

Draw2D[
{
Red,Thick,
ComplexLine[{0,1,1+I,I,0}],
Blue,PointSize[Large],
ComplexPoint[1+I]
},
ImageSize->3 72]

Because an option such as ImageSize affects the entire drawing, not just individual object, it goes after the list of graphics objects and directives:
	Draw2D[{…}, opts]

The last drawing does not give a very good feel for what the objects are and where they are. To enhance it:
	• add axes with tick marks and coordinates (by default Draw2D suppresses them);
	• use the PlotRange option to enlarge the plot "window", so that the objects may be seen in a larger view;
	• put a Legacy color Honeydew background behind the plot to better set it off from the rest of the notebook; and
	• add a descriptive plot label.

Draw2D[
{
Legacy@IndianRed,Thick,
ComplexLine[{0,1,1+I,I,0}],
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+I]
},
Axes->True,
PlotRange->{{-1.5,1.5},{-1.5,1.5}},
Background->Legacy@HoneyDew,
PlotLabel->"Point and line in the complex plane",
ImageSize->3 72]

That looks better. It will be improved further in the next section.

The PlotRange option, used above, specifies the "window" used for plotting. To specify a window consisting of points z=x+y i with (Subscript[x, min])≤x≤(Subscript[x, max]) and (Subscript[y, min])≤y≤(Subscript[y, max]), use the form PlotRange->{{(Subscript[x, min]),(Subscript[x, max])},{(Subscript[y, min]),(Subscript[y, max])}}.

Exercise . Copy the preceding input cell. Then change it so as to use a different window, a different background color (White, for example), and a different label for the plot. And make the drawing’s overall size much bigger, say 6 inches.

Exercise . For the same drawing, use a frame (with coordinates labeling its sides) instead of axes. (Hint: Look up Frame in the Documentation Center.)

If you use the Axes->True option without a PlotRange option, you may not get axes through the origin. For example:

Draw2D[
{
Red,Thick,
ComplexLine[{1+I/2,2+I/2,2+I,1+I,1+I/2}]
},
Axes->True,
ImageSize->3 72]

The remedy is to include an explicit AxesOrigin->0 option:

Draw2D[
{
Red,Thick,
ComplexLine[{1+I/2,2+I/2,2+I,1+I,1+I/2}]
},
Axes->True,AxesOrigin->0,
ImageSize->3 72]

Exercise . Redraw the rectangle from the preceding display but with the origin of axes at the center of the rectangle.

Annotating Complex Graphics displays

To further annotate a Complex Graphics drawing, you may want to include text within the drawing. To insert text at any location, invoke the Presentations function ComplexText. This function is used in the form
	ComplexText[txt,z]
where txt is the text you want to display and z is the complex number in the plane where (the center of) the text is to be displayed.

For example, enhance the same drawing as before but now also:
	• use a ComplexText expression to label the plane as the complex plane;
	• label the point.

Draw2D[
{
Legacy@IndianRed,Thick,
ComplexLine[{0,1,1+I,I,0}],
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+I],
Black,
ComplexText["1+I",1.15+1.15I],
Legacy@DimGray,ComplexText[Style["complex plane",FontFamily->"Helvetica",FontSize->10],-1-I]
},
Axes->True,
PlotRange->{{-1.5,1.5},{-1.5,1.5}},
Background->Legacy@HoneyDew,
PlotLabel->Style["Point and line in the complex plane",FontWeight->Bold],
ImageSize->3 72]

Notice that the 1+i text labeling the point is automatically typeset in traditional mathematical format, since the text used for the input already includes the typeset form i rather than I. This would not have happened had you used instead ComplexText[“1+I”, 1.15+ 1.15i].

Exercise . Draw a square with vertices at 1, i, -1, and -i and label its vertices in the drawing.

Sometimes you want to label a point or other object with an expression involving complex numbers but you want the form of that expression to display, not its numerical value.  For example, suppose you had calculated the point 1+i from…

(1 + 3I)/(2 + I)

…but you want to label the point with the actual expression ((1 + 3i)/(2 + i)).  Try it:

Draw2D[
{
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+I],
Black,
ComplexText["(1 + 3I)/(2 + I)",1.15+1.15I]
},
PlotRange->{{-1.5,1.5},{-1.5,1.5}},
ImageSize->3 72]

It’s tempting to omit the quotations marks in the text “(1 + 3I)/(2 + I)”. But see what happens if you do:

Draw2D[
{
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+I],
Black,
ComplexText[(1 + 3I)/(2 + I),1.15+1.15I]
},
PlotRange->{{-1.5,1.5},{-1.5,1.5}},
ImageSize->3 72]

Mathematica evaluates the argument (1+3I)/(2+I) inside ComplexText before forming the ComplexText graphics primitive object. To prevent that evaluation, wrap the argument with HoldForm (and prevent the fractional label from displaying on top of the point by adjusting the coordinates for center of the text):

Draw2D[
{
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+I],
Black,
ComplexText[HoldForm[(1 + 3I)/(2 + I)],1.2+1.2I]
},
PlotRange->{{-1.5,1.5},{-1.5,1.5}},
ImageSize->3 72]

It is especially important to use HoldForm when the expression involves a variable and you do not want the value of that variable to be used instead of the variable's name.  Look first at this display:

(Subscript[z, 0])= (1+3I)/(2+I);
Draw2D[
{
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[1+ I],
Black,
ComplexText[z=(Subscript[z, 0]),1.15+1.15I]
},
PlotRange ->{{-1.5,1.5},{-1.5,1.5}},
ImageSize -> 3 72]

Probably you had intended that the label for the point would be, literally, z=(Subscript[z, 0]) rather than the value of (Subscript[z, 0]). What’s worse, the Draw2D expression had a possibly unfortunate and unintended side-effect: it set z to be the value of (Subscript[z, 0]):

z

So first clear that value z…

Clear[z]

… and then compare the following display:

(Subscript[z, 0])= (1+3I)/(2+I);
Draw2D[
{
Legacy@MediumBlue,PointSize[Large],
ComplexPoint[(Subscript[z, 0])],
Black,
ComplexText[HoldForm[z=(Subscript[z, 0])],1.15+1.15I]
},
PlotRange ->{{-1.5,1.5},{-1.5,1.5}},
ImageSize -> 3 72]

Now not only is the point labeled as intended, but the side-effect of setting a value for z has been avoided:

Using Mathematica's Drawing Tools to annotate drawings

A "quick-and-dirty" way to annotate and otherwise edit drawings—for example, to add text, insert arrows to point to particular things, and insert other curves and shapes—is to use Mathematica's Drawing Tools palette. This palette works much the same way that similar palettes or buttons do in various drawing and paint programs.
For help about using those tools, see the Documentation Center Drawing Tools Tutorial.

It is often much quicker to use Drawing Tools than to construct Presentations code to accomplish the same thing, especially when you can visually place objects in the drawing without having to figure out what the objects locations are in terms of coordinates.

On the other hand, if you alter the code that produced the drawing and evaluate the new code, you will have to go about applying the Drawing Tools modifications all over again.

Drawing arrows: ComplexArrow

To construct an arrow with specified complex numbers as its tail and head, use the Presentations function ComplexArrow. The syntax, as you can discover from inserting a template for it from PresentationsPalette, is:
	ComplexArrow[{z1,z2}]
There z1 is the tail and z2 the head of the arrow.

Draw2D[{
Blue,
ComplexArrow[{0,1+I}]
},
Axes->True,Ticks->{{0,1},{0,1}},
ImageSize->2 72
]

As you can see, the arrow head is rather small and hard to see—especially if, as below, you specify a non-default thickness. So you may want to change the dimensions of the arrow head with the Mathematica directive Arrowheads.

Draw2D[{
Thick,Blue,Arrowheads[Large],
ComplexArrow[{0,1+I}]
},
Axes->True,Ticks->{{0,1},{0,1}},
ImageSize->2 72
]

Exercise . Pick two non-real complex numbers z and w. Make a drawing that shows the points z, w, and z+w as well as arrows from the origin to each of these points. Include some lines to illustrate that, as vectors, complex numbers add by the parallelogram rule.

Making dynamic drawings: Manipulate

To move graphics objects around interactively,  change constants appearing in the complex graphics objects to variables—parameters—and wrap the entire Draw2D expression in a Mathematica Manipulate expression.

For example, here again is a drawing of a point and a square.

Draw2D[
{
Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[{0,1,1+I,I,0}]
},
Axes->True,ImageSize->3 72,
]

Let's first interactively scale of the square, so that it keeps its vertex at the origin and two of its sides on the axes. So change the fixed list {0,1,1+i,i,0} of points to the variable list c{0,1,1+i,i,0} and let the value of the parameter c vary between 0.1 and 2.

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
Axes->True,ImageSize->3 72
],
{c,0.1,2}
]

Move the slider at the top of the display to change the size of the square. Or click the little + sign at the end of the slider to open the "video controls" and then use the ▸ button to move the slider automatically.

The results are probably not what you expect: while the range along the axes changes, the square keeps the same physical size on-screen. To fix that, use a fixed PlotRange option for Draw2D:

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
PlotRange->{{-2,2},{-2,2}},
Axes->True,ImageSize->3 72
],
{c,0.1,2}
]

Let's allow scaling the square by negative numbers as well by changing the lower bound on c from 0.1 to -2:

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
PlotRange->{{-2,2},{-2,2}},
Axes->True,ImageSize->3 72
],
{c,-2,2}
]

Enhancing dynamic drawings: initial values and labels

But set the initial value of the scale c at 0.1, say, so that the square starts out in the first quadrant. To do so, change the form of the control expression {c,-2,2} to {{c, 0.1}, -2,2}:

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
PlotRange->{{-2,2},{-2,2}},
Axes->True,ImageSize->3 72
],
{{c,0.1},-2,2}
]

To display the current value of the control variable, include the option Appearance->"Labeled" at the end of the control expression. (Note that "Labeled" must be a string, in quotes.)

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
PlotRange->{{-2,2},{-2,2}},
Axes->True,ImageSize->3 72
],
{{c,0.1},-2,2,Appearance->"Labeled"}
]

To change the name appearing next to the slider, change the form of the control expression as shown below.

Manipulate[
Draw2D[
{Blue,PointSize[Large],ComplexPoint[1+I],
Red,Thick,ComplexLine[c{0,1,1+I,I,0}]
},
PlotRange->{{-2,2},{-2,2}},
Axes->True,ImageSize->3 72
],
{{c,0.1,"Scale"},-2,2,Appearance->"Labeled"}
]

Exercise . Instead of a square and a point at one of its vertices, make an interactive drawing of a triangle whose scale can vary.

Two-dimensional controls

Rather than vary the square, let's move the point around. As things stand now, its position is fixed at the constant 1+i. Change that constant to a variable, say pt. The control expression {pt,start,end} will specify the lower-left corner start and upper-right corner of where pt can vary; let's use -2-2i and 2+2i. But since Manipulate expects the values of start and end to be Cartesian coordinates for the points, you must convert them. You may do that manually yourself or let Presentations do it for you by means of ToCoordinates.

Manipulate[
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I]}
]

You obtain a 2D slider control. Move around the little point in the control at the top to move the point displayed in the drawing.

Instead of using ComplexPoint[ToComplex[pt]], you could substitute simply Point[pt]. And instead of ToCoordinates[-2+2i] you could substitute {-2,2}, etc. I chose to keep everything possible in terms of complex numbers.

Locators

It may seem silly to move a point around in a square region at the top just in order to move a corresponding point around in the drawing at the bottom. There is a another way of moving the point directly within the drawing, by changing the default 2D slider control to a Locator control.

Manipulate[
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

Now just move the point at the "cross-hairs" around directly with the mouse. Or click anywhere inside the drawing, and the locator point will move to there.

Add a text label for the point that moves along with the point:

Manipulate[
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}],
Black,Text[ToComplex[pt],pt+{0.2,0.2}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

The text label for the point gets clipped when you move the point near the top or right edges. It's hard to fix that directly. An easy work-around is to make the entire Draw2D expression an item of a Column (or Row) and then include as an additional item the complex value for the current position of the point:

Manipulate[
Column[{
ToComplex@pt,
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
]
}],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

Or get even fancier:

Manipulate[
Column[{
Row[{"Point = ",TraditionalForm@ToComplex@pt}],
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[{0,1,1+I,I,0}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
]
}],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

Exercise . Create a dynamic drawing consisting of: a point z in the complex plane together with an arrow from the origin to z; the multiple i z of z together with an arrow from the origin to i z. Control the whole drawing by putting a locator at z.

Exercise . (a) Repeat Exercise  but instead of the multiple i z of z, use the sum z+1.
(b) Repeat Exercise  but instead of the multiple i z of z, use the sum z+i.

Exercise . Repeat Exercise  but instead of the multiple i z of z, use the square (z^2) of z.

Multiple controls

Next, scale the square and move the point around. Just use two controls. With sliders, do it like this:

Manipulate[
Draw2D[
{
Blue,PointSize[Large],
ComplexPoint[ToComplex[pt]],
Red,Thick,
ComplexLine[c{0,1,1+I,I,0}]
},
Axes->True,
PlotRange->{ToCoordinates[-2+2I],ToCoordinates[-2+2I]},
ImageSize->3 72
],
{c,-2,2},
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I]}
]

You may use the larger + button at the extreme upper-right corner of the output to run both controls automatically,  or to take "snapshots" of the situation for particular values of the controls and then to use those snapshots as "frames" in a video.

Exercise . Make an interactive drawing consisting of an equilateral triangle with one vertex at the origin and a second vertex on the x-axis and whose scale can be varied. Include points at the vertices that move with the triangle as the latter is scaled.

Exercise . Make a new Manipulate expression that combines a slider control for the scale of the square and a locator for the point. Label both the scale and the point somehow (with names to indicate their meaning). Include a legend on the entire drawing.

To use several locators in Manipulate output, you could just add additional control variables for locators. A neater way is to use a single control variable that is a list of points. For example:

Manipulate[
Draw2D[{
Red,PointSize[Large],ComplexPoint/@ToComplex/@pts,
Blue,Thick,ComplexLine[ToComplex/@pts]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],
{{pts,{ToCoordinates[1+I],ToCoordinates[-1-I]}},Locator}
]

In the preceding output, you may independently move either of the two locators; the line joining the two points will move correspondingly.

Look carefully at the control expression in the preceding input:
	{{pts,lis}, Locator}
The list lis of locators is an initialization for pts, and so both pts and lis are enclosed in the list
	{pts,lis}
that in turn is nested inside the overall control expression list.

Exercise . Make a dynamic drawing of a filled-in polygon whose vertices you can move around interactively.

Exercise . Make your drawing from Exercise  dynamic, so that you can interactively move the two points z and w. and so that, as you move them, their sum z+w and the rest of the drawing correspondingly moves with z, w, and z+w.

Interactively creating and destroying locators: the LocatorAutoCreate option

An intriguing possibility is to allow additional locators to be created and destroyed interactively. To do so, be sure that the initial value of the control variable for the locator is a list of one or more points, and then include the LocatorAutoCreate->True option for the locator control.

For example, begin with a line segment each of whose ends can be independently varied by means of a locator:

Manipulate[
Draw2D[{
Thick,Red,ComplexLine[ToComplex/@pts]
},
Axes->True,PlotRange->ToCoordinates/@{-2+2I,-2+2I},
ImageSize->3 72],
{{pts,ToCoordinates/@{-1-I,1+I}},Locator}
]

(Move one or another of the locators in the preceding output to see what happens.)

Now add the  LocatorAutoCreate->True option for the locator control.

Manipulate[
Draw2D[{
Thick,Red,ComplexLine[ToComplex/@pts]
},
Axes->True,PlotRange->ToCoordinates/@{-2+2I,-2+2I},
ImageSize->3 72],
{{pts,ToCoordinates/@{-1-I,1+I}},Locator,LocatorAutoCreate->True}
]

In the preceding output, each time you Alt-click (or Ctrl-click) somewhere in the drawing, a new locator will be created there and that new point will be included in the polygonal line. To destroy a locator, put the cursor on it and  Alt-click (or Ctrl-click) it.

Exercise . Make a dynamic drawing of a filled-in polygon whose vertices you can move interactively and in which you can interactively include or remove additional vertices.

Drawing circles and disks: ComplexCircle and ComplexDisk

To draw a circle
	(Subscript[C, r])((Subscript[z, 0]))={z∈ℂ:|z-(Subscript[z, 0])|=r} 
with specified center (Subscript[z, 0]) (as a complex number) and radius r>0, use the Presentations function ComplexCircle.  For example:

Draw2D[
{
Red,Thick,
ComplexCircle[I/2,1]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},ImageSize->3 72]

Exercise . Let (Subscript[z, 0])=1+ i and r=1/2. Draw the circle of radius r centered at (Subscript[z, 0]). In your drawing, label its center and its circumference, the latter in the form |z-(Subscript[z, 0])|=r.

And to draw an open disk 
	(Subscript[D, r])((Subscript[z, 0]))={z∈ℂ:|z-(Subscript[z, 0])|<r}
—without the boundary circle—use the Presentations function ComplexDisk.  For example:

Draw2D[
{
Pink,ComplexDisk[I/2,1]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},ImageSize->3 72]

To indicate that an open disk is really open, you could superimpose on it, dashed, its bounding circle:

Draw2D[
{
Lighter@Pink,ComplexDisk[I/2,1],
Red,Thick,Dashed,ComplexCircle[I/2,1]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},ImageSize->3 72]

To represent a closed disk 
	(Subscript[(OverBar[D]), r])((Subscript[z, 0]))={z∈ℂ:|z-(Subscript[z, 0])|≤ r}
(including its bounding circle), you could use both a ComplexDisk and a ComplexCircle object. See the next paragraph for a simpler way.

To indicate whether a disk is open or closed, a more direct way is to include an EdgeForm graphics directive:

Draw2D[
{
Lighter@Pink,
EdgeForm[{Thick,Dashed,Legacy@IndianRed}],ComplexDisk[I/2,1]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},ImageSize->3 72]

Notice that when the EdgeForm argument includes more than one graphics directive, as above, that argument must be a list. Or, alternatively, a Directive expression.

Draw2D[
{
Lighter@Pink,
EdgeForm[Directive[Thick,Dashed,Legacy@IndianRed]],ComplexDisk[I/2,1]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},ImageSize->3 72]

Exercise . Draw the closed disk of radius 1 centered at i with its open disk lavender and its bounding circle blue.

Exercise . Make a dynamic drawing of a complex disk as well as its center and bounding circle so that you can interactively move its center and vary its radius.

Exercise . How might you represent graphically a punctured disk—a set of the form (SuperStar[(Subscript[(OverBar[D]), r])])={z∈ℂ:0<|z-(Subscript[z, 0])|<r} ? Do this for the punctured disk of radius 1 centered at (1/2)i. (Hint: To make it easier, use ComplexCirclePoint.)

Exercise . Let (Subscript[z, 0])=i. Draw the closed disk of radius 1 centered at (Subscript[z, 0]) along with an arrow from its center to some point of the bounding circle. Label the center and that arrow.

Exercise . Pick a non-real complex number z. Make a drawing that shows the points z and i z as well as arrows from the origin to each of these points. Include an arc of a circle between the arrows, with appropriate labeling, to suggest the geometric effect of multiplying by i.

Exercise . Make your drawing from Exercise  dynamic, so that as you interactively vary the point z, the point i z as well as the arrows and arc correspondingly change.

Drawing regions: ComplexPolygon and RegionDraw

To form a circular region, simply use ComplexDisk (perhaps with a solid or dashed boundary to indicate whether the disk is closed or open, respectively). See the preceding section.

To form a filled-in polygonal set, use the Presentations function ComplexPolygon. For example:

Draw2D[
{
LightBlue,
ComplexPolygon[{1,I,-1,-I}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->2 72
]

When you form a closed polygonal curve by using ComplexLine, you must repeat the initial vertex at the end of the list of vertices. By contrast, when you form a polygonal region, you do not need to repeat at the end of the argument to ComplexPolygon the initial point. (But it doesn't hurt if you do.)

To indicate whether the polygonal set is closed or open, you could include a ComplexLine that is solid or dashed, respectively. Another way to accomplish the same thing is to use the EdgeForm graphics directive:

Draw2D[
{
LightBlue,
EdgeForm@Directive[Thick,Dashed,Legacy@IndianRed],
ComplexPolygon[{1,I,-1,-I}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->2 72
]

Exercise. Draw the open hexagonal region centered at the origin and one of whose vertices is 1. Treat the boundary appropriately to indicate that the set is open.

To form other filled-in sets, you may use the Presentations function RegionDraw. Unfortunately, RegionDraw does not directly accept complex numbers z in the relations defining the set; instead, you must resort to expressing z in Cartesian x+y i form. And you must as usual tell Mathematica to treat x and y as real by using ComplexExpand. For example, to draw the region defined by the inequality Im(z)>1:

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1,{x,-2,2},{y,-2,2}]
},
Axes->True,
ImageSize->2 72]

Notice the use of ComplexExpand in the inequality relation.

The preceding drawing is unsatisfactory in that it does not show anything below the line Im(z)=1. That's because Mathematica placed the axes so as to exclude points in the plane that are below the set of interest. One way to fix that is to specify explicitly the origin of axes:

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1,{x,-2,2},{y,-2,2}]
},
Axes->True,AxesOrigin->{0,0},
ImageSize->2 72]

To change the color of the filled-in region, use the PlotStyle option to RegionDraw:

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1,{x,-2,2},{y,-2,2},
PlotStyle->LightGray]
},
Axes->True,AxesOrigin->{0,0},
ImageSize->2 72]

Exercise . Draw the open region Im(z)>1 again but now also display its boundary line Im(z)=1 as thick and dashed.

To indicate whether

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1,{x,-2,2},{y,-2,2},
PlotStyle->LightGray,BoundaryStyle->Directive[Thick,Dashed,Red]]
},
Axes->True,AxesOrigin->{0,0},
ImageSize->2 72]

To use more than a single condition to define the set, combine them with && (which is an abbreviation for the logical And function).

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1&&(-1/2<ComplexExpand@Re[x+y I]<1/2),{x,-2,2},{y,-2,2}]
},
Axes->True,AxesOrigin->{0,0},
ImageSize->2 72]

That doesn't look right: the lower corners are rounded a bit, whereas they should really be squared-off. Mathematica simply did not sample enough points near those corners to give a good enough picture. Fix that by including Mathematica's PlotPoints option to RegionDraw:

Draw2D[
{
RegionDraw[ComplexExpand@Im[x+y I]>1&&(-1/2<ComplexExpand@Re[x+y I]<1/2),{x,-2,2},{y,-2,2},PlotPoints->25]
},
Axes->True,AxesOrigin->{0,0},
ImageSize->2 72]

Here's a similar example, but now with a bounded set:

Draw2D[
{
RegionDraw[1/2<ComplexExpand@Im[x+y I]<3/2&&-1<ComplexExpand@Re[x+y I]<1,{x,-2,2},{y,-2,2},PlotPoints->25]
},
Axes->True,AxesOrigin->{0,0},PlotRange->2,
ImageSize->2 72]

To indicate whether a bounded set is closed or open, you may include a BoundaryStyle option to RegionDraw to make the boundary solid or dashed, etc.

Draw2D[
{
RegionDraw[1/2<ComplexExpand@Im[x+y I]<3/2&&-1<ComplexExpand@Re[x+y I]<1,{x,-2,2},{y,-2,2},

PlotStyle->LightGray,
BoundaryStyle->Directive[Thick,Dashed,Red]]
},
Axes->True,AxesOrigin->{0,0},PlotRange->2,
ImageSize->2 72]

(Note that, unlike ComplexDisk and ComplexPolygon, the function RegionDraw ignores an EdgeForm directive preceding it.)

Exercise . (a) Draw alongside one another the open region, and the corresponding closed set, consisting of all points in the upper half-plane that are inside the unit circle.
(b) Repeat (a) but now the region is to consist of all points that are outside the unit circle.

Drawing curves: ComplexCurve

Some examples in this section use the complex exponential function f(z)=exp(z), represented in Mathematica by Exp. All you need to know about this function here is that, for real a and b:
	exp(a+b i)=(e^a)(cos b+i sin b)

A curve in the complex plane is a continuous function
	γ: [a,b]->ℂ
with domain some closed interval [a,b]. For each t∈[a,b], the complex number γ(t) has the form
	γ(t)=z(t)=x(t)+i y(t)
where the functions
	x:[a, b]->ℝ,     y:[a,b]->ℝ
are real-valued. Then the trace of the curve—its set of values—is the parametric plot of the pair of functions (x(t),y(t)).

The Presentations function ComplexCurve facilitates drawing curves in the complex plane.

?ComplexCurve

Consider, for example, the upper semicircle of radius 2 with center the origin:

γ[θ_]:=2Exp[I θ]

Draw2D[
{
Blue,
ComplexCurve[γ[θ],{θ,0,π}]
},
Frame->True,FrameTicks->Automatic,ImageSize->4 72]

Another example is a spiral:

Draw2D[
{
Blue,
ComplexCurve[Exp[(1+2I)t],{t,-2,3}]
},
PlotRange->All,Axes->True,
ImageSize->4 72]

The option PlotRange->All in the preceding input ensures that all points on the curve, from t=-2  to t=3 are actually displayed. Try the same drawing but without that option to see what happens.

Of course ComplexCurve objects may be combined with other Complex Graphics primitive objects. For example:

Draw2D[
{
Blue,
ComplexCurve[Exp[(1+2I)t],{t,-2,3}],
Red,Dashed,
ComplexLine[{Exp[-2-4I],Exp[3+6I]}]
},
PlotRange->All,
ImageSize->4 72]

Exercise . Draw the line segment from 1 to 1+i in two different ways:
	(a) By using ComplexLine.
	(b) By using ComplexCurve. (Hint: How can you parameterize a line segment from a point A to a point B?)
Then evaluate just your ComplexLine and then your ComplexCurve expression alone—without the enclosing Draw2D function—so as to see what each gives to Mathematica to display.

What you see in the displays produced from (a) and (b) in the preceding exercise should be the same. However, there is a critical difference in what's actually happening "behind the scenes":
	• your ComplexLine expression gives Mathematica just the two endpoints 1=(1,0) and 1+i=(1,1) of the line segment, and then the Draw2D expression causes Mathematica to draw the line segment connecting those two points; however,
	• your ComplexCurve expression gives Mathematica a whole bunch of points along that line segment, and then the Draw2D expression causes Mathematica to "connect the dots", each one to the next, with very short line segments, to obtain the entire line segment.
To see that this is so, look again at the result you obtained in the preceding exercise when you evaluated your ComplexCurve[…] expression by itself.

This little discussion may seem pointless right now. But later, when you try to visualize what happens to a line segment when it is transformed by a function f:ℂ->ℂ, it will be crucial to use ComplexCurve rather than ComplexLine to form the segment.

Exercise . Draw the circle with center 1+i and radius 2 in two different ways:
	(a) By using ComplexCircle.
	(b) By using ComplexCurve. (Hint: How can you parameterize a circle with given center and radius?)
Then evaluate just your ComplexCircle and then your ComplexCurve expression alone—without the enclosing Draw2D function—so as to see what each gives to Mathematica to display.

Exercise . Make a dynamic drawing of the same spiral as in a previous example but whose terminal end (the one not the origin) can be changed interactively, and the dashed line from the origin to the terminal end correspondingly changes too. In other words, as you move the slider forward, you see the spiral "unroll", getting longer and longer.
(Hint: You do not want a locator or 2D slider control. Rather, you want to vary how high the parameter values in the ComplexCurve can go.)

Syntax of the Draw2D function

The template for Draw2D that you can insert from the PresentationsPalette is
	Draw2D[{primitives},options]

Thus the general form of a Draw2D expression is
	Draw2D[{primitives},opts]	
where:
	•  the argument {primitives} is a list consisting of one or more complex graphics objects (ComplexPoint, ComplexLine, ComplexCircle, ComplexDisk, ComplexCurve, ComplexText, etc., expressions) together with zero or more graphics directives (PointSize and Thickness expressions, color specifications, etc.), in any order; and
	• opts, if present, is a sequence of graphics options (ImageSize-> …, PlotRange->…, Background->…, PlotLabel-> …, Axes->True , etc., options).

As usual, you may find out what options are available for Draw2D by looking at the function's reference page in the Documentation Center. And to get a quick list of the options and their default values, in your notebook evaluate:
	Options[Draw2D]

Another, handy way to find out the options for Draw2D—indeed, for any function—is to use the Presentations OptionsFinder. See notebook AboutPresentations.nb for details.

Lists of graphics objects

Instead of individual Complex Graphics objects, you can use lists of such objects, too. For example:

Draw2D[
{
Red,
ComplexLine[{0,1,1+I,I,0}],
PointSize[Large],Blue,
{ComplexPoint[0],ComplexPoint[1],ComplexPoint[1+I],ComplexPoint[I],ComplexPoint[0]}
},
ImageSize->3 72]

Of course in a situation like that, it’s easier to Map the primitive ComplexPoint onto the list of complex numbers:

Draw2D[
{
Red,
ComplexLine[{0,1,1+I,I,0}],
PointSize[Large],Blue,
ComplexPoint/@{0,1,1+I,I,0}
},
ImageSize->3 72]

Using names in place of graphics primitives

In the final example of the preceding subsection, the list {0,1,1+i,i,0} of complex numbers is used twice. In such a case, it’s often a good idea to assign a name to the list and then use that name within the Draw2D expression:

vertices={0,1,1+I,I,0};

Draw2D[
{
Red,
ComplexLine[vertices],
PointSize[Large],Blue,
ComplexPoint/@vertices
},
ImageSize->3 72]

Other situations where you may want to use names as above, instead of using their values directly, are: (1) you are going to need the same Complex Graphics object in several drawings; or (2) you merely want to shorten the code within the Draw2D expression. For example:

vertices={0,1,1+I,I,0};
pts=ComplexPoint/@vertices;
square=ComplexLine[vertices];
labels={
ComplexText[Style[0,16,FontWeight->Bold],0.05+0.05I],
ComplexText[Style[1,16,FontWeight->Bold],0.95+0.05I],
ComplexText[Style[1+I,14,FontWeight->Bold],0.95+1.05I],
ComplexText[Style[I,16,FontWeight->Bold],0.05+1.05I]
};

Draw2D[{
Red,square,
PointSize[Large],Blue,pts,
Black,labels
},
PlotLabel->Style["A square"],
Axes->True,AxesLabel->{"x","y"},
ImageSize->3.5 72]

Actually, there’s no reason to use a Style argument to each separate ComplexText object above. If you want to use the same style for all text appearing in the drawing—including plot labels, axes labels, etc.—then you may use a single BaseStyle graphics option for Draw2D. For example:

vertices={0,1,1+I,I,0};
pts=ComplexPoint/@vertices;
square=ComplexLine[vertices];
labels={
ComplexText[0,0.05+0.05I],
ComplexText[1,0.95+0.05I],
ComplexText[1+I,0.95+1.05I],
ComplexText[I,0.05+1.05I]
};

Draw2D[{
Red,square,
PointSize[Large],Blue,pts,
Black,labels
},
PlotLabel->Style["A square"],
Axes->True,AxesLabel->{x,y},
BaseStyle->{16,FontWeight->Bold},
ImageSize->3.5 72]

Isolating the scope of a graphics directive

Just as you may use a list defined names of Complex Graphics objects, instead of individual objects, within the first (list) argument {…} of Draw2D , so you may use a list consisting of both graphics directives and Complex Graphics objects. This is another way to make the meaning of code more apparent. For example:

Draw2D[
{
{Red,Thick,ComplexLine[{0,1,1+I,I,0}],ComplexLine[{0,1+I}],ComplexText["diagonal",0.55+0.7I]},
{Blue,PointSize[Large],ComplexPoint[1/2(1+I)]}
},
ImageSize->3 72]

It is important to understand the scope of graphics directives. A graphics directives within a Draw2D expression will affect all subsequent Complex Graphics objects formed within that expression and to which it is relevant—unless the directive is: 
	• overridden by a subsequent directive;  or 
	• buried within a list nested inside the {…} list argument to Draw2D.
Thus, compare the two drawings below:

unnested=Draw2D[
{
Red,Thick,ComplexLine[{0,1,1+I,I,0}],
PointSize[Large],ComplexPoint[1/2(1+I)]
},
ImageSize->3 72];
nested=Draw2D[
{
{Red,Thick,ComplexLine[{0,1,1+I,I,0}]},
PointSize[Large],ComplexPoint[1/2(1+I)]
},
ImageSize->3 72];
Row[{unnested,Spacer[5],nested}]

Look again at input for the last output. As the code for the drawing at the right illustrates, you may isolate the effects of a graphics directive by using nested lists, as in the definition of nested above.

Exercise . Copy and suitably edit the code for the last output in order to put a frame around the entire row of drawings and to give the whole thing a different background color.

When you have several graphics directives in a row that are to effect subsequent graphics objects, you can sometimes make the code easier to read or write by combining the directives into arguments of a Directive expression. (In itself, this does nothing to alter the scope of the directives.) For example:

Draw2D[
{
Directive[Red,Thick],ComplexLine[{0,1,1+I,I,0}],
Directive[Blue,PointSize[Large]],ComplexPoint[1+I]
},
ImageSize->3 72
]

Displaying several drawings together

Look at the output of the following input:

square=Draw2D[
{
Red,Thick,ComplexLine[{0,1,1+I,I,0}],
Blue,PointSize[Large],
ComplexPoint[1/2(1+I)]
},
Axes->True,
ImageSize->3 72];
circle=Draw2D[
{
Blue,Thick,ComplexCircle[(1/2)+(1/2)I,(1/2)(Sqrt[2])],
Red,PointSize[Large],
ComplexPoint[1/2(1+I)]
},
Axes->True,
ImageSize->3 72];
Row[{square,Spacer[5],circle}]

The two drawings are displayed next to one another—by putting them into a list that is the argument to Mathematica's Row. You could also use GraphicsRow instead of Row; that would automatically take care of the intermediate spacing for you. Similarly you could use Column or GraphicsColumn to display two outputs stacked vertically. And you could use Grid or GraphicsGrid if you want to create a multi-row, multi-column display.

Exercise . Create four different complex graphics drawings. Then display them arrayed in two rows and two columns.

Exercise . Copy and edit the code from either Exercise  or Exercise  so as to put a caption under the entire output (not jut under individual drawings in the display).

Dynamically controlling several drawings together

When you've created a Row or Grid or Column with two (or more) Draw2D drawings, you can make corresponding objects in the two drawings change dynamically together by putting everything inside a Manipulate and changing corresponding constants for the two drawings into controlled variables.

For example, begin with a point on one set of axes and an arrow from the origin to that point on another set of axes:

Row[{
Draw2D[{
Red,PointSize[Large],ComplexPoint[1+I]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],

Spacer[20],

Draw2D[{
Blue,Thick,Arrowheads[0.1],ComplexArrow[{0,1+I}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72]
}]

In the first drawing, change the constant point 1+i to a variable point, initially 1+i, that can move along the circle with equation |z|=1.

Manipulate[
Draw2D[{
Red,PointSize[Large],ComplexPoint[(Sqrt[2])Exp[I θ]]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],
{{θ,π/4},0,2π}
]

Now make the corresponding change in the endpoint of the arrow and put both dynamic drawings together in a single Manipulate expression:

Manipulate[
Row[{
Draw2D[{
Red,PointSize[Large],ComplexPoint[(Sqrt[2])Exp[I θ]]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],
Spacer[20],
Draw2D[{
Blue,Thick,Arrowheads[0.1],ComplexArrow[{0,(Sqrt[2])Exp[I θ]}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72]
}],
{{θ,π/4},0,2π}
]

Rather than constrain the point to the circle, allow it to be moved freely throughout the drawing region—in other words, use a Locator control:

Manipulate[
Row[{
Draw2D[{
Red,PointSize[Large],ComplexPoint[ToComplex@pt]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],
Spacer[20],
Draw2D[{
Blue,Thick,Arrowheads[0.1],ComplexArrow[{0,ToComplex@pt}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72]
}],
{pt,ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

As usual there, by default the control value is initially the first point in the window you specified, namely, ToCoordinates[-2 - 2 i]. You may initialize the pointer's location in the usual way:

Manipulate[
Row[{
Draw2D[{
Red,PointSize[Large],ComplexPoint[ToComplex@pt]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72],
Spacer[20],
Draw2D[{
Blue,Thick,Arrowheads[0.1],ComplexArrow[{0,ToComplex@pt}]
},
Axes->True,PlotRange->{{-2,2},{-2,2}},
ImageSize->3 72]
}],
{{pt,ToCoordinates[1+I]},ToCoordinates[-2-2I],ToCoordinates[2+2I],Locator}
]

⚠ Caution: Such a Manipulate with a locator will not work correctly if you use GraphicsRow instead of Row. (Try it!) That is due to the way that GraphicsRow resizes its individual graphics items.

Exercise . Create a dynamic display of two drawings the first of which shows a point z in the complex plane together with an arrow from the origin to it, and the second shows the multiple i z together with an arrow from the origin to it. In the first drawing, use a locator for z.

What's next?

For visualizing how a function f: ℂ -> ℂ maps the plane, the next things to learn are how to form a grid in the plane and how to place two separate Draw2D displays—one for the domain and the other for the image—next to one another. See the notebooks VisualizingFunctions.nb and RiemannSphere.nb.