pie
ExamplesDocs

Topics

  • Canvas
  • Reactivity
  • Broadcasting
  • Autodiff
  • Animation
  • Python
unitgridOpacitycanvasColor

Reactivity

  • Varignon's parallelogram
  • A live label
  • An ellipse with a string

A node remembers the nodes it was built from. Change one of those and it updates, along with everything built from it in turn. Nothing else on the page needs to rerun.

Varignon's parallelogram

Draw any four-sided shape. Join the midpoints of its sides. The result is always a parallelogram.

pie.clear()
a = pie.point(-4, -2, out='a')
b = pie.point(3, -3, out='b')
c = pie.point(4, 2, out='c')
d = pie.point(-2, 3, out='d')
for p, q in [(a, b), (b, c), (c, d), (d, a)]:
    pie.line(p, q, stroke='gray')

m = [pie.midpoint(p, q, fill='crimson') for p, q in [(a, b), (b, c), (c, d), (d, a)]]
for i in range(4):
    pie.line(m[i], m[(i + 1) % 4], stroke='crimson')

Now move one corner. Only c is set again, but the gray sides, the midpoints and the red shape all follow, and the red shape is still a parallelogram:

pie.point(1, 4, out='c')

Try your own coordinates, or move a, b or d.


A live label

Opposite sides of the parallelogram have the same length. Show both lengths as text. pie.lift turns a plain Python function into one that reruns when its input nodes change.

def two_lengths(x, y):
    return f"{x:.2f} and {y:.2f}"
label = pie.lift(two_lengths, pie.Text)

lengths = label(pie.distance(m[0], m[1]), pie.distance(m[2], m[3]))
pie.text(lengths, 0, -5, 16)

Move a corner again. The label updates with the shape:

pie.point(-5, 1, out='a')

The chain here is: point a → midpoints → distances → two_lengths → the text on the canvas.


An ellipse with a string

An ellipse is the path of a pencil held tight by a string pinned at two points, its foci. pie.ellipse_from_foci takes the two foci and the string's length.

pie.clear()
f1 = pie.point(-2, 0, out='f1')
f2 = pie.point(2, 0, out='f2')
s = pie.scalar(6, out='s')
pie.ellipse_from_foci(f1, f2, s, stroke='teal')

A longer string gives a rounder ellipse:

pie.scalar(9, out='s')

Pinned closer together, the foci give an ellipse close to a circle:

pie.point(-0.5, 0, out='f1')
pie.point(0.5, 0, out='f2')

A string shorter than the distance between the foci can't reach around them, so then nothing is drawn.