We're going to be drawing things. So first, let's choose how we're going to represent points, lines and figures.

We choose to represent a point in the plane as a list `[x, y]`

containing the x and y coordinates of the point. For example the point A = (3, 4) in the plane will be represented by the list `[3,4]`

in python.

We choose to represent a line as a list of two points `[p, q]`

containing the endpoints of the line. So for example the segment AB between points A = (0,0) and B = (1,1) would be represented in python as the list `[[0,0], [1,1]]`

.

In the following exercice, you'll be asked to return a list of lines.

The dragon curve is a figure that appeared on the chapter covers of Jurassic Parc. It looks like this :

The 0-dragon curve between two points P and Q is a simple line between the points:

The 1-dragon curve between two points P and Q looks like this :

To build the n-dragon curve between points P and Q, you need to define an intermediary point R. Here is how you get R.
You build a circle with diameter PQ. If you pick any point A on that circle, the triangle PAQ will be a right triangle.
There are two points on that circle that will not only give you a right triangle, but also an isoscele triangle. Pick one of those points call it R and write a function `gimmeR(P, Q)`

that returns the point R. Look at the figure below to better understand.

<img src = "pqr.png" width = "300px">

In [ ]:

```
def gimmeR(P, Q):
pass
gimmeR([0,0], [1, 1]) # should return [1, 0]
gimmeR([0,0], [0,1]) # should return [0.5, 0.5]
```

The n-dragon curve between the points P and Q is defined as the concatenation of the (n-1)-dragon curve between P and R and the (n-1)-dragon curve between Q and R. Using `gimmeR`

, write a recusive function `dragon(n, P, Q)`

that returns the list of segments in the n-dragon curve between P and Q.

In [ ]:

```
def dragon(n, P, Q):
pass
```

The function `draw(L)`

takes a list of lines and draws it. Check that your function works by calling it.

In [62]:

```
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Polygon
from matplotlib.collections import PatchCollection, LineCollection
def draw(L):
plt.style.use('ggplot')
f, ax = plt.subplots()
lc = LineCollection(L)
ax.add_collection(lc)
ax.autoscale()
ax.set_aspect('equal')
plt.axis('off')
plt.show()
```

Dragon curves start looking nice and pretty after 10. Here is what a 13-dragon curve looks like :

<img src = "d13.png" width = "300px">

We choose to represent a triangle as a list of three points `[p, q, r]`

. The following exercice asks you to return a list of triangles, you should return a list containing lists of three points.

Here are examples of the Sierpinsky triangles :

`sierpinsky(p, q, r, n)`

that takes three points `p, q, r`

(the endpoints of an equilateral triangle), an integer `n`

and returns the list of triangles that make up the n-th sierpinsky triangle.
In [ ]:

```
import numpy as np
import matplotlib.pyplot as plt
def sierpin(p, q, r, n):
pass
### p, q and r below are the endpoints of an equilateral triangle, use them to test your code
p = np.array([0,0])
q = np.array([2,0])
r = np.array([1, 3**0.5])
L = sierpin(p, q, r, 4)
def drawTriangles(L):
triangles = []
for a, b, c in L:
triangles += [Polygon([a, b, c], True)]
f, ax = plt.subplots()
ax.add_collection(PatchCollection(triangles))
ax.autoscale()
ax.set_aspect('equal')
plt.axis('off')
plt.show()
drawTriangles(L)
```

The Ethiopian-Orthodox cross can be approximated by a fractal. We're going to try drawing this :

<img src = "etcr.png" width = "500px">

The base figure for the cross looks like this :

<img src = "base.png" width = "200px">

You are provided with a function that gives the set of lines that make up this figure. `base_figure(scale)`

returns the base figure centered at the origin (0,0) and scaled by a factor of `scale`

.

The n-cross is composed of 8 (n-1)-crosses. Look at the figures below and try finding how you should combine the 8 crosses :

You are provided with the functions :

- `rotfigure(figure, angle)` that rotates a given figure
- `shiftfigure(figure, angle, dist)` that shifts a given figure by a value of `dist` in the direction given by `angle`
- `rescale(figure, factor)` that rescales a figure

Use these function to draw the ethiopian cross. (Use trial and error to figure out scaling and shifting parameters)

In [64]:

```
import numpy as np
import matplotlib.pyplot as plt
def rot(angle, x):
O = np.array([[np.cos(angle), -1*np.sin(angle)], [np.sin(angle), np.cos(angle)]])
return np.dot(O, x)
def shift(angle, dist, x):
vect = dist * np.array([np.cos(angle), np.sin(angle)])
return np.array(x) + vect
def rotfigure(figure, angle):
return [[rot(angle, p[0]), rot(angle, p[1])] for p in figure]
def shiftfigure(figure, angle, dist):
return [[shift(angle, dist, p[0]), shift(angle, dist, p[1])] for p in figure]
def rescale(figure, factor):
return [[factor*np.array(p[0]), factor*np.array(p[1])] for p in figure]
def base_figure(scale):
origin = np.array([0,0])
pi = np.pi
r = 4
v_id = np.array([1,1])
up = np.array([0,1])
right = np.array([1,0])
lst = []
lst.append([origin, origin+scale*v_id])
lst.append([origin+scale*v_id, origin+scale*v_id + r*scale*right])
lst.append([origin+scale*v_id + r*scale*right, origin+scale*v_id + r*scale*right + scale*rot(-pi/2, v_id)])
lst.append([origin+scale*v_id + r*scale*right, origin+scale*v_id + r*scale*right + r*scale*up])
lst.append([origin+scale*v_id + r*scale*right + r*scale*up, origin+scale*v_id + r*scale*right + r*scale*up + scale*v_id])
lst.append([origin+scale*v_id , origin+scale*v_id + r*scale*up])
lst.append([origin+scale*v_id + r*scale*up, origin+scale*v_id + r*scale*up + r*scale*right])
lst.append([origin+scale*v_id + r*scale*up, origin+scale*v_id + r*scale*up + scale*rot(pi/2, v_id)])
#center
center = scale*(1+r/2)*np.array([1,1])
lst = [ [p[0] - center , p[1] - center ] for p in lst ]
return [[rot(pi/4, p[0]), rot(pi/4, p[1])] for p in lst]
def ethiodraw(L):
for pair in L:
a, b = pair
line = plt.Line2D([a[0], b[0]], [a[1], b[1]], lw=2.5, color='k')
plt.gca().add_line(line)
plt.axis('scaled')
plt.axis('off')
#plt.savefig('et0.png', format='png', dpi=300)
plt.show()
```

In [ ]:

```
### Write your function here
def cross(scale, n):
pass
```