Geomerative

Introduction

Geomerative is a library for Processing. It extends 2D geometry operations to facilitate generative geometry. Includes a TrueType font and an SVG interpreters. This library exposes the shapes (such as vector drawings or typographies) in a more approchable way. Geomerative makes it easy to access the paths, the handles and the points, making it easy to develop generative typography and geometry pieces in Processing.

Download

Geomerative (rev 19) (November 29 2008)

unzip the contents of this file to /path/to/sketchbook/libraries

Credits

Creator:
Ricard Marxer
Collaborator:
Mark Luffel
Overview and examples:
Florian Jenett

Works

Geomerative has been used in the following projects:

Overview

The library is composed of 4 basic elements (RShape, RPolygon, RMesh and RGroup) all of which support a set of common methods such as: accessing (getCurvePoints, getPoints,...), transforming (translate, rotate, scale,...), styling (setStroke, setStrokeColor, setStrokeWeight, setFill, setFillColor,...) and drawing (draw). Additionally the library has 2 interpreters that will allow the user to import shapes from TTF fonts and SVG vector drawings into the library's classes.

Elements

RShape

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
 *
 *    fjenett 20080417
 */

import geomerative.*;

RShape shp;

void setup()
{
    size(400,400);
    smooth();
    
    RGeomerative.init(this);
    
    shp = new RShape();
    
    shp.addMoveTo( 0 , 141 );        // zeichenbefehle, vergleiche beginShape, vertex, bezierVertex
    shp.addLineTo( 2 , 133 );
    shp.addLineTo( 34 , 133 );
    shp.addLineTo( 60 , 9 );
    shp.addLineTo( 38 , 9 );
    shp.addBezierTo( 20 , 9 , 16 , 12 , 12 , 30 );
    shp.addLineTo( 9 , 46 );
    shp.addLineTo( 0 , 46 );
    shp.addLineTo( 10 , 0 );
    shp.addLineTo( 123 , 0 );
    shp.addLineTo( 113 , 46 );
    shp.addLineTo( 104 , 46 );
    shp.addLineTo( 107 , 30 );
    shp.addBezierTo( 111 , 12 , 109 , 9 , 91 , 9 );
    shp.addLineTo( 69 , 9 );
    shp.addLineTo( 43 , 133 );
    shp.addLineTo( 75 , 133 );
    shp.addLineTo( 73 , 141 );
    shp.addLineTo( 0 , 141 );
    shp.addClose();
}

void draw()
{
    background(255);
    translate(140,120);
    
    stroke( 120 );
    strokeWeight( 3 );
    fill( 220 );

    shp.draw();
}

RPolygon

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
*
*    fjenett 20080417
*/

import geomerative.*;

RPolygon ply;

void setup()
{
    size(400,400);
    
    RGeomerative.init(this);
    
    ply = new RPolygon();
    
    for ( int i=0; i<360; i++ )
    {
        float rad = radians(i);
        float rad2 = radians(i*12);
        ply.addPoint( sin(rad)*120+sin(rad2)*20, cos(rad)*120+cos(rad2)*20 );
    }
}

void draw()
{
    background(255);
    translate(width/2,height/2);
    
    stroke( 120 );
    strokeWeight( 3 );
    fill( 220 );

    ply.draw();
}

RMesh

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
*
*    fjenett 20080419
*/

import geomerative.*;

RMesh msh;

void setup()
{
    size(400,400);
    frameRate( 2 );
    
    RGeomerative.init(this);
    
    strokeWeight( 1.2 );
}

void draw()
{
    background(130);
    
    RPolygon pl = RPolygon.createRing( random(80,160), random(10,50), int(random(5,15)) ).toPolygon();
    msh = pl.toMesh();
    
    translate( width/2, height/2 );
    msh.draw( );
}

RGroup

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
*
*    glyphen eines fonts auslesen
*
*    fjenett 20080417
*/

import geomerative.*;

RFont font;

void setup()
{
    size(400,400);
    smooth();
    
    RGeomerative.init(this);

    font = new RFont( "lucon.ttf", 100, RFont.CENTER);
}

void draw()
{
    background(255);
    translate(width/2,height/2);
    
    RGroup grp = font.toGroup("Hello?");                                // text in ein gruppen-objekt umwandeln
    
    for ( int i = 0; i < grp.elements.length; i++ )                     // elemente durchlaufen
    {
        RShape shp = grp.elements[i].toShape();                         // gruppen-element in shape-objekt umwandeln
        
        for ( int ii = 0; ii < shp.paths.length; ii++ )             // shapes durchlaufen
        {
            RPath sushp = shp.paths[ii];                        // path-objekt
            
            for ( int iii = 0; iii < sushp.commands.length; iii++ )     // zeichen-kommando-objekte durchlaufen
            {
                RPoint[] pnts = sushp.commands[iii].getPoints();        // punkte des kommando-objekts
                
                switch( sushp.commands[iii].getCommandType() )          // je nach kommando-art anderern befehl ausfŸhren
                {
                    case RCommand.LINETO:
                        line( pnts[0].x, pnts[0].y, pnts[1].x, pnts[1].y );
                        break;
                    case RCommand.QUADBEZIERTO:    // eigentlich falsch, denn bezier() ist kubisch
                        bezier( pnts[0].x, pnts[0].y, pnts[1].x, pnts[1].y, pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y );
                       break;
                    case RCommand.CUBICBEZIERTO:
                        bezier( pnts[0].x, pnts[0].y, pnts[1].x, pnts[1].y, pnts[2].x, pnts[2].y, pnts[3].x, pnts[3].y );
                       break;
                }
            }
        }
    }
}

Interpreters

RFont

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
*
*    fjenett 20080417
*/

import geomerative.*;

RFont font;

void setup()
{
    size(400,400);
    
    RGeomerative.init(this);

    font = new RFont( "lucon.ttf", 72, RFont.LEFT);
}

void draw()
{
    background(0,100,50);
    translate(width/2-200,height/2-100);
    
    font.draw("Hello?");
}

RSVG

/*
*    geomerative example
*    http://www.ricardmarxer.com/geomerative
*
*    fjenett 20080417
*/

import geomerative.*;

RSVG svg;

void setup()
{
    size(800,800);
    frameRate( 30 );
    
    RGeomerative.init(this);
    
    svg = new RSVG( );
}

void draw()
{
    background(255);
    svg.draw("hello.svg");
}

Tutorials

The tutorials are not available online yet. They can be found in the tutorials directory inside the zip file.

Documentation

The documentation is not available online yet. It can be found in the documentation directory inside the zip file.

Changelog

rev 19 (29 - November - 2008):
  • Added the methods .getX and .getY() to all geometric elements. This should finally deprecate the use of .getBounds()
rev 18 (26 - November - 2008):
  • Major addition of a RG static class that contains most functions available in the library and that resembles more to the Processing way of doing things (RG.loadShape(), RG.loadFont(), RG.beginShape(),...).
  • Updated the examples to use the new RG interface.
  • Renamed RGeomerative.init() -> RG.init()
  • Changed the way getBounds() works. It now returns an instance of type RRectangle.
  • RGroup will soon become deprecated. Please start using RShape everywhere and it's method children. This will allow us a smoother transition to Processing's PShape.
rev 15 (06 - October - 2008):
  • Major bug fixes
  • Renamed RSubshape -> RPath
  • Renamed getPoints -> getHandles
  • Renamed getCurvePoints -> getPoints
  • Added method getHeight returns the height of a geometric element
  • Added method getWidth returns the width of a geometric element
  • Added method transform rescales the geometric element to fit a rectangle
  • Added method contains takes as input an RPoint returns True if inside the geometric element False otherwise
  • Added method split returns an array of RGroup containing the two geometric elements resulting in splitting the geometric element at the advancement passed as input
  • Added method splitPaths returns an array of RGroup containing the two geometric elements resulting in splitting each of the paths of the geometric element at the advancement passed as input
  • Added method insertHandle inserts a new handle in the geometric element at the advancement passed as input
  • Added method insertHandleInPaths inserts a new handle in each of the paths of the geometric element at the advancement passed as input
  • Added method getPointsInPaths returns an array of arrays of RPoint for the point on each of the paths of the geometric element
  • Added method getHandlesInPaths returns an array of arrays of RPoint for the handle on each of the paths of the geometric element
  • Added method getTangentsInPaths returns an array of arrays of RPoint for the tangent on each of the paths of the geometric element
  • Mark Luffel made the clipping (used for the binary operations and for rendering in OPENGL) faster and better
  • Mark Luffel made the buildsystem using Makefile
rev 12 (05 - May - 2008):
  • Partial support for SVG styles
  • Fixes in SVG commands: line, polyline, path, etc...
rev 11 (28 - April - 2008):
  • Partial support for SVG transformations
  • Partial support for SVG commands: line, polyline, path, etc...
  • Introduction of RGeomerative.init(PApplet applet)