davidedc / livecodelab

a web based livecoding environment
http://livecodelab.net/
MIT License
329 stars 63 forks source link

Going all meta with arrangements of objects (grids and more) #210

Open davidedc opened 10 years ago

davidedc commented 10 years ago

With Guy we were thinking some time ago that we might want a simplified way to make grids / cubes of objects.

Proposal for discussion: we could go all meta and use the block notation applied to primitives, and do the following:

// cubes arranged in a line:
line
  box
// a grid (of proportions 2x1) of squares
rect 2 1
  rect
// rotating balls arranged in cube
box
  rotate ball
// pairs of lines arranged in cubes
box
  line
  move 0.1
    line
// lines arranged in cubes, put on the surface of a sphere
ball
  box
    line

The only attention point comes with the level of detail:

//draws 6 squares
detail 1
rect 2 1
  rect
// fills the 2x1 space with more rectangles
// probably 6 at top, 6 at bottom, 2 at centers?
detail 2
rect 2 1
  rect

and so on and so forth.

It's going to be occasionally tricky to find ways to arrange objects according to a geometry and a given level of detail, but we can peek into the routines that generate the vertexes of the three.js shapes. Anyways, may be tricky but for sure doable.

Thoughts?

noio commented 10 years ago

Interesting! A similar thought occurred to me a while ago, though much more limited, I was going to propose a syntax just for grids like:

3x4
  box

which would be a shortcut roughly for:

4.times (x) ->
  3.times (y) ->
    pushMatrix
    move (-(4-1)/2+x),(-(3-1)/2+y),0
    //DO COOL STUFF HERE LIKE
    box
    popMatrix

But—and your proposal is proof of this—there are so many possible variations! Cubes, objects along vertices of other objects, etc.

Proposal

So, this is kind of more than you asked for, but I'm going to propose something that crossed my mind. Combining user-definable functions with the thing you mentioned before: that it would be nice if users could save and share sketches.

So this is a three part thing.

1) Functions

Create syntax for defining functions that can take a code block as an argument. Like

grid(3, 4, <code>)

2) Macros

Letting users define rewrite rules that make these functions easier to write:

3x4 \n\t <code> --> grid(3, 4, <code>)

3) Sharing

Allow users to share sketches (just dump them to gist? that's pretty easy). And allow other users to import these sketches into their own sketch: import gist/123456. The imported sketch could consist of fully fleshed out visuals, or it could just define functions (like grid) with macros, so the user now has access to these extras.

Other thoughs:

So, I realize there is a lot potentially reinventing the wheel going on here, so this warrants some careful planning. And reading back, this might not even be an answer to your "cubes on a sphere" problem, because these user-defined functions probably won't have access to "the routines that generate the vertices of the three.js shapes" [davidedc].

But it is a nice way to separate LCL into high performance+powerful core code, and expressive/limitless user code.

P.S. @davidedc / @rumblesan , I was looking at both of your blogs (the retina burn arts and 'errrord' respectively) and: very cool.

davidedc commented 10 years ago

I think we should break down these threads into separate issues (and you are welcome to do that), this is a lot of material to discuss, it's definitely not all going to fit in this one thread.

What do you think specifically about the proposed objects-arrangement mechanism? (I think that this is a system-level thing that can be discussed on its own separately from functions/macro definitions and imports.)

(thanks for the compliment btw - I'm glad that I got 1 visitor in the whole of 2013, I've got 100% appreciation rate at this point :-)

noio commented 10 years ago

Haha yes, I realized at the end of my text that it was a little off topic. My actual thoughts on object-in-template arrangements:

  1. My first thought is this: it's going to be ambiguous. Are objects placed uniformly throughout the volume of the template? On the surface of the template? On the vertices of the template? On the edges of the template? Are they oriented in some way (as with your "pairs of lines" example)?
  2. Second thought: will the template be recognisable without needing too many objects? I can imagine this system invites the user to create many many shapes and impact performance considerably.
  3. A loose thought, but it extends to more cases: is box \t\n line equivalent to a box without fill? (Similarly: box \t\n rect)
  4. Last thought: in creating such an infinitely recursive language, it might be worth to really consider what "box" means (not in a philosophical sense xD, but in a geometric algebraic sense), to keep things consistent throughout all cases.

I think it's going to be hairy, and I have personally never wanted to do anything beyond grid, but that's just me, so don't take it as an objection.

(P.S. maybe you can enlighten me sometime as to the process you used to create some of the illustrative/figurative pieces in the series :) )

rumblesan commented 10 years ago

definitely think that some higher order functionality for adding grids and cubes of shapes is needed. :+1: to this

left my comments to @noio 's thoughts on relevant issues. also glad you like the blog btw. for something that's entirely automated it's worked out pretty well :)

davidedc commented 10 years ago

Good spots, this is much more complicated than I thought. Let me try to defend this a bit more, I'll try some answers.

1) We might need the followings: ballVertexes ballEdges ballSurface and ballVolume. Where "ball" can be any primitive (for the case where the primitives has a 2nd, 3rd dimension) (also we should accept both "lineEdges" and "lineEdge"). Just we'll find some defaults by which ball will be equal to ballVolume, same for box, rect will be its surface, line will be its edge. So:

rect 2, 1
  rect

will be the same as

rectSurface 2,1
  rect

draws squares in a grid of proportion 2,1. Default detail means that there will be 2 squares

box
  rect

As for the orientation (and also, as an effect, the scale) - you are right unfortunately there are many many ways. For filling a volume for example, there is "straight" (all objects put in straight, like gold bars in a stack of gold), there is "radially" (like needles of a sea urchin), for a surface there is also "longitudinal" and "latitudinal" (if it's "radially symmetrical shape", with lines pointing like latitude and longitude lines), "randomly" and probably more. Sounds like we need an optional parameter then, something like:

ballSurface radially,2,1,3
  line

And some values will apply in some cases and not in others, and we'll pick some defaults when that parameter is not given. Also we might need another parameter to indicate whether the scale of the objects should change as well (lines placed in latitude/longitude are not all the same size, lines at the equator are longer than lines at the poles)

2) we can push a few hundred shapes. I think it will be OK for in some cases like a ball surface with lines and a 3d grid of boxes, and less OK for others.

3) ballSurface latitudeAndLongitude line yes, would be equivalent (or similar) to a wireframe. But rects can't tile a ballSurface neatly, I don't think it's reasonable to expect that, at the end of the day a rect is a rect, not a trapezium.

4) not sure what you mean. Some of these case would sound like disfluencies in English. When you say "a box of balls" for example you mean both the box and the balls being drawn. But you can say "a line of boxes" or, say, "a pyramid of boxes". So, some of those cases make sense in English, and I think by extension, for orthogonality, we can give some meaning to also the cases that sound like disfluencies in English.

I'm happy to get more challenges on this, I didn't think about the problems with orientations at all, it's more difficult than I first thought. But we don't need to do it all in one shot, we can do the simple grid cases first, maybe vertexes, and then see how it goes.?

noio commented 10 years ago

In regards to 4) I didn't mean language so much as geometry. (As in, do surfaces and lines have orientation? Is a box a collection of vertices, edges, surfaces, or a volume?) But I guess it's just the same as the other questions.

It's going to be hard to implement this with a compact and orthogonal syntax that is easy to type. So I have another suggestion for brainstorming: how about a a literal object notation:

box
    edges: line
    vertices: ball

And then: edges would always be aligned to the edges themselves (latitudeAndLongitude), vertices are always radial, and volume is always straight.

As a side note: surface and volume are going to be somewhat tricky (and relatively computationally expensive) to implement.

davidedc commented 10 years ago

Further comments after email exchange with "Patterning" author Phil Jones and also referencing the "Diagrams" Haskell package documentation (http://projects.haskell.org/diagrams/doc/quickstart.html), we could handle it like so:

  decorate
    box
  with
    ball // automatic positioning at the vertexes of the ball

or, with some vertex-specific operations like:

  decorate
    polyhedron n // number of faces as per standard greek name
  with
    (x) -> ball 1/x // shrinking, automatic positioning at the vertexes of the ball

or, avoiding the with part, one can manually do the re-positioning manually like:

  boxDecorationPoints = decorate box
  boxDecorationPoints.reverse().map (x) -> move x ball 1/x // shrinking. Manual positioning in this case.