Skip to main content

DPoodle Graphics

Section 1. Introduction

DPoodle is a graphics library written in ReasonML at DePauw University during Spring 2020. DPoodle is based on the Doodle graphics library from Creative Scala.

Section 2. image type

The basic type of a drawing in DPoodle is image. Seven built-in functions used to construct geometric shapes are ellipse, circle, rectangle, square, triangle, polygon, and regularPolygon. The size arguments for all of these functions are of type float, plus the regularPolygon function also takes the number of sides as an int. Every image in DPoodle has a bounding box, which is a minimal rectangle that can cover the image. The center of the bounding box by default is at (0, 0). The built-in triangle function creates an isoceles triangle with the base on the bottom edge of the bounding box and the vertex in the middle of the top edge. Detail about the built-in functions to create geometric shape images in DPoodle are in the following table:

FunctionArgument(s)Bounding box size
ellipse(w, h)Horizontal axis (w) and Vertical axis (h)w×hw\times h
circle(r)Radius (r)2r×2r2r\times 2r
rectangle(w, h)Width (w) and Height (h)w×hw\times h
square(w)Side length (w)w×ww\times w
triangle(w, h)Base (w) and Height (h)w×hw\times h
polygon(points)List of vertex pointsSmallest rectangle containing all points
regularPolygon(n, s, a)Number of sides (n), Distance from center to vertex (s), and Initial angle (a)2s×2s2s\times 2s (roughly)

Function draw(image) is used to visualize the image:

An empty value is use to create an empty image whose bounding box is (0., 0., 0., 0.); it is often useful as a default image when there is nothing to draw, and it is an identity element for the image combination operations described below. The polyline function is closely related to polygon. A polyline is a non-closed polygon:

We can also construct a shape by specifying a colection of points and the connections between these points (using straight line or curve). These shapes can be:

  • Open-path: using openPath(pathElements) function.
  • Close-path: using closedPath(pathElements) function.

These two functions take a list of pathElement values as input. A pathElement may be created by the following functions:

  • moveXY(x, y): move to point (x, y), without drawing a line.
  • moveP(p): move to point p.
  • lineXY(x, y): draw a line from the current point to point (x, y).
  • lineP(p): draw a line from the current point to point p.
  • curveXY(c1x, c1y, c2x, c2y, px, py): draw a curve from the current point to point (px, py). The points (c1x, c1y) and (c2x, c2y) are called control points; the intuition is that the curve will start out headed toward the first control point, and then approach its destination as if coming from the second control point.
  • curveP(c1, c2, p): draw a curve from the current point to point p, with control points c1 and c2.

Here is an example to help you visualize the control points:

In the following example, we draw an AND gate using the closedPath function, on top of input and output wires drawn with openPath:

Here are corresponding definitions of OR and NOT gates. Note how the NOT gate is built from other primitive geometric shapes:

Information about the bounding box (bbox) of an image can be retrieved by following functions, which take an image as input. The first 4 functions return a float and the rest return a point, which is equivalent to a pair of floats.

FunctionReturn
left(image)Minimum x-coordinate of corresponding bbox
right(image)Maximum x-coordinate of corresponding bbox
top(image)Minium y-coordinate of corresponding bbox
bottom(image)Maximum y-coordinate of corresponding bbox
topLeft(image)Top left point of corresponding bbox
topRight(image)Top right point of corresponding bbox
bottomLeft(image)Bottom left point of corresponding bbox
bottomRight(image)Bottom right point of corresponding bbox

Here are some examples:

We can also visuallize the bounding box and its center using the showBounds function, which takes an image as input:

Elements in an image can also be text. The function text(string) is used to create a text image. This function return an image with 0 by 0 bounding box (this is a limitation of the way fonts are handledthe DPoodle library is not able to calculate an accurate bounding box on its own). Since the draw(image) function only renders the area inside of the bounding box, we often need to reset the size of the bounding box for text: setBounds(left, right, top, bottom, text(string)). You may have to play around with showBounds a bit to choose the correct values for the bounds. Here is an example:

Section 3. Position and Manipulation

We can combine two images and control their relative positions using the following functions:

FunctionReturnAlternative operation
beside(a, b)Image a is on the left of image b. The centers of a and b are aligneda ||| b
above (a, b)Image a is vertically above image b. The centers of a and b are aligneda --- b
on(a, b)Image a on top of image b. The centers of a and b are superimposeda +++ b

The operator symbols should remind you of how a and b are arranged; imagine either drawing a line between them (| or -) or centering one on the other (+).

We can also scale, rotate, and translate the image:

FunctionArgumentsEffect
rotate(a, img)Angle a (degrees) and image imgRotate img by angle a clockwise.
translate(dx, dy, img)Changes in x- and y-coordinates dx and dy, image imgTranslate the points of img from (x, y) to (x + dx, y + dy).
translateP(p, img)Point p and image imgTranslate the origin of img to point p.
scalexy(sx, sy, img)Horizontal and vertical scale factors sx and sy, image imgScale image horizontally by sx and vertically by sy.
scale(s, img)Scale factor s and image imgScale img in both directions by factor s.
setBounds(l, r, t, b, img)Min x, max x , min y, max y of the new bounding box respectively, and the image imgCreate a new image that looks just like img, except its bounding box has the specified coordinates. The origin is unchanged.

For example:

Focus(position, img) is a special case of the translate(dx, dy, img) function. It produce a new image based on image img with the origin at the specified point on its bounding box. position is a type that has the nine following cases: TL (top left), TC (top center), TR (top right), ML (middle left), MC (middle center), MR (middle right), BL (bottom left), BC (bottom center), BR (bottom right).

Every image has a bounding box and a reference point. At the begining when the image is created, the reference point of the image is at the center. Translating an image (via the translate, translateP, or focus functions) translates the whole image but leaves the reference point behind. Think of the reference point as a spot on a table, and the image starts off as a piece of paper centered over that spot. Translating amounts to shifting the paper so that a different point is over the spot. Putting two images together with ||| or --- is like pushing two tables next to each other, lining up their spots horizontally or vertically. The papers come along for the ride and overlap as the tables are shifted. When you're done, you imagine a new combined table with a new spot underneath the overlapped (and now merged) papers.

Section 4. Format

The image type can be formatted using the following functions:

FunctionsArgumentsEffect
fill(c, img)Color c (color) and image imgFill img with color c.
stroke(c, img)Color c (color) and image imgChange the border of img to color c.
solid(c, img)Color c (color) and image imgChange the border of img and fill it with color c.
strokeWidth(w, img)Thickness w (float) and image imgChange the thickness of img's border to w.
dashed(img)image imgDraw the border of img with dashed lines.
withFont(fontSize, fontFamily, fontWeight, fontStyle, img) Font size (float), font family (fontFamily), font weight (fontWeight), font style (fontStyle), and image imgFormat the text in img as specified.

The type color can be generated by one of the following functions:

  • color(c): Takes a named CSS Level 4 color (see list below) as its string argument.
  • rgb(r, g, b): Create a color with the given red, green, and blue components. All arguments should be integers between 0 and 255.
  • rgba(r, g, b, a): Similar to the rgb(r, g, b) function but also have a fourth argument which is the alpha level. Alpha level determines the opacity of the color and it should be a float between 0 and 1. An alpha of 1.0 is fully opaque, while 0.0 is fully transparent.
  • hsl(h, s, l): Create a color with the given hue, saturation, and lightness components. The first argument (hue) should be a float from 0 to 360, representing an angle in the color wheel (0 is red, 120 is green, and 240 is blue). The second argument (saturation) should be a float from 0 to 1, measuring how pure the hue is (1 is fully pure, while 0 is a shade of gray). The third argument (lightness) should be a float from 0 to 1, measuring how close to white (1) or black (0) it is. For example, a fully pure blue is represented by (hue, saturation, lightness) numbers (240., 1., 0.5).
  • hsla(h, s, l, a): similar to the hsl(h, s, l) function, but also have the alpha level as the rgba(r, g, b, a) function.

Here are the known named colors:

transparentaliceBlueantiqueWhiteaqua
aquamarineazurebeigebisque
blackblanchedAlmondblueblueViolet
brownburlyWoodcadetBluechartreuse
chocolatecoralcornflowerBluecornSilk
cyandarkBluedarkCyandarkGoldenrod
darkGraydarkGreydarkGreendarkKhaki
darkMagentadarkOliveGreendarkOrangedarkOrchid
darkReddarkSalmondarkSeaGreendarkSlateBlue
darkSlateGraydarkSlateGreydarkTurquoisedarkViolet
deepPinkdeepSkyBluedimGraydimGrey
dodgerBluefireBrickfloralWhiteforestGreen
fuchsiagainsboroghostWhitegold
goldenrodgraygreygreen
greenYellowhoneydewhotpinkindianRed
indigoivorykhakilavender
lavenderBlushlawngreenlemonChiffonlightBlue
lightCorallightCyanlightGoldenrodYellowlightGray
lightGreylightGreenlightPinklightSalmon
lightSeaGreenlightSkyBluelightSlateGraylightSlateGrey
lightSteelBluelightYellowlimelimeGreen
linenmagentamaroonmediumAquamarine
mediumBluemediumOrchidmediumPurplemediumSeaGreen
mediumSlateBluemediumSpringGreenmediumTurquoisemediumVioletRed
midnightBluemintCreammistyRosemoccasin
navajoWhitenavyoldLaceolive
oliveDraborangeorangeRedorchid
paleGoldenrodpaleGreenpaleTurquoisepaleVioletRed
papayaWhippeachPuffperupink
plumpowderBluepurplerebeccaPurple
redrosyBrownroyalBluesaddleBrown
salmonsandyBrownseaGreenseaShell
siennasilverskyBlueslateBlue
slateGrayslateGreysnowspringGreen
steelBluetantealthistle
tomatoturquoisevioletwheat
whitewhiteSmokeyellowyellowGreen

Arguments for the withFont(fontSize, fontFamily, fontWeight, fontStyle, img) function have the following values:

  • fontSize is a float, where 1.0 gives the default size (about 16.0 units from the top of a capital letter to the bottom of a descending stroke).
  • fontFamily is a type that has 3 cases: Mono, Sans, and Serif.
  • fontWeight is a type that has 2 cases: Bold and Regular.
  • fontStyle is a type that has 2 cases: Italic and Normal.

Here are some examples:

Here is an example of text formatting:

Section 5. Some Demonstrations

Here is an arrow using openPath. This also shows examples of using focus and showBounds.

Using the arrow, here is a function to visualize a linked list:

The second list is smaller because the draw function will adjust the scale so that the entire bounding box is displayed on screen.