fossunited / joy

Joy is a tiny creative coding library in Python.
MIT License
193 stars 19 forks source link

Support adding transformations #15

Open anandology opened 3 years ago

anandology commented 3 years ago

Here is a wild idea.

Add support for adding transformations with the following property.

T1(s) + T2(s) == (T1+T2)(s)

This could be used to generate higher-order transformation that combine multiple transformations. With this, users would be able to create their own transformations.

Examples:

def twiceX(width):
    return translate(x=0, y=0) + translate(x=width, y=0)

shape = circle(r=50) | twiceX(width=100)
def grid(shape, w, h):
    t1 = translate(x=-w/2, y=h/2)
    t2 = translate(x=-w/2, y=-h/2)
    t3 = translate(x=w/2, y=h/2)
    t4 = translate(x=w/2, y=-h/2)
    return t1 + t2 + t3 + t4

shape = circle(r=50) | grid(w=100, h=100)
show(shape)

@amitkaps what do you think?

amitkaps commented 3 years ago

Now we are getting into layouts. Keeping the same shape and applying a list of translations.

You can introduce + operator. More importantly, it would be better to introduce product type data structures like list and apply function like map, cross etc.

t = List(t1, t2, ...)
s = circle(10)
shape = s.map(t)
show(shape)
anandology commented 3 years ago

I'm not convinced about map yet.

I would prefer to write it this way.

t = combine([t1, t2, ...])
shape = circle(r=50) | t
show(shape)

You combine multiple transformations in to a single transformation (I need to pick a better name than combine though) and apply it to a shape.

Can you suggest an example of cross?

anandology commented 3 years ago

Are there any libraries that has this functionality?

I've seen zimjs which transformations and generators etc. But I wasn't too happy with the API.

opheliagame commented 3 years ago

Hey, I thought this would be the right place to maybe add my thought.

While trying to chain transformations, I tended naturally to do the following bit l1 = line(0, 0, 0, 0-length) | translate(x, y) | rotate(-45)

Since I am quite new to software design, would love to hear thoughts on why you think it might or might not be a good choice :)

anandology commented 3 years ago

@opheliagame, we already support chaining of transformations as you've shown in the example. However, this issue is trying to improve the case where you want to take a shape, apply multiple transformations and combine all the resulting shapes.

For example, consider the following:

s1 = ellipse()
s2 = s1 | rotate(60)
s3 = s3 | rotate(120)
shape = s1 + s2 + s3
show(shape)
ellipses

If I want to do the same thing with a rectangle, I would have to do the while thing again.

s1 = rectangle()
s2 = s1 | rotate(60)
s3 = s3 | rotate(120)
shape = s1 + s2 + s3
show(shape)
rectangles

Wouldn't it be nice to model all this as a transformation?

rotate_trice = rotate(0) + rotate(60) + rotate(120)

shape = ellipse() | rotate_thrice
show(shape)

shape = rectangle() | rotate_thrice
show(shape)

This allows the users to create their own transformations by creating the existing ones.

Does this sound like an interesting feature?

opheliagame commented 3 years ago

@anandology yes I do think that would be useful :) I am also wondering how to chain the following transformations

  1. translate to p1
  2. rotate around p1