# My God, It's Full of Stars!

Let's use our new tools to draw some stars. For the purpose of this exercise let's assume that a star is a polygon with p points. However, instead of connecting each point to its neighbours, we'll connect them to the nth point around the circumference.

For example, Figure sequences:stars shows stars with p=11 and n=1 to 5. n=1 produces a regular polygon while values of n from 2 upwards produce stars with increasingly sharp points:

Write code to draw the diagram above. Start by writing a method to draw a star given p and n:

def star(p: Int, n: Int, radius: Double): Image =
???

Hint: use the same technique we used for polygon previously.

<div class="solution"> Here's the star method. We've renamed p and n to points and skip for clarity:

def star(sides: Int, skip: Int, radius: Double): Image = {
import Point._
import PathElement._

val rotation = 360.degrees * skip / sides

val elements = (1 until sides).toList map { index =>
val point = polar(radius, rotation * index)
lineTo(point)
}

Image.path(ClosedPath(start :: elements)).strokeWidth(2)
}

</div>

Using structural recursion and beside write a method allBeside with the signature

def allBeside(images: List[Image]): Image =
???

We'll use allBeside to create the row of stars. To create the picture we only need to use values of skip from 1 to sides/2 rounded down. For example:

allBeside(
(1 to 5).toList map { skip =>
star(11, skip, 100)
}
)

<div class="solution"> We can use the structural recursion skeleton to write this method.

def allBeside(images: List[Image]): Image =
images match {
case Nil => ???
case hd :: tl => ???
}

Remembering the recursion gives us

def allBeside(images: List[Image]): Image =
images match {
case Nil => ???
case hd :: tl => /* something here */ allBeside(tl)
}

Finally we can fill in the base and recursive cases.

def allBeside(images: List[Image]): Image =
images match {
case Nil => Image.empty
case hd :: tl => hd.beside(allBeside(tl))
}

</div>

When you've finished your row of stars, try constructing a larger image from different values of p and n. There is an example in Figure sequences:all-star. Hint: You will need to create a method allAbove similar to allBeside.

<div class="solution"> To create the image in Figure sequences:stars2 we started by creating a method to style a star.

def style(img: Image, hue: Angle): Image = {
img.
strokeColor(Color.hsl(hue, 1.0, 0.25)).
fillColor(Color.hsl(hue, 1.0, 0.75))
}

We then created allAbove, which you will notice is very similar to allBeside (wouldn't it be nice if we could abstract this pattern?)

def allAbove(imgs: List[Image]): Image =
imgs match {
case Nil => Image.empty
case hd :: tl => hd above allAbove(tl)
}

The updated scene then becomes:

allAbove((3 to 33 by 2).toList map { sides =>
allBeside((1 to sides/2).toList map { skip =>
style(star(sides, skip, 20), 360.degrees * skip / sides)
})
})

</div>