NuG was created to make it easier to create graphics with movement, variation, and order. It includes a number of noise generators, a flexible valiable-width and variable-color curve renderer, and a parallelizer with big dreams (i.e. replicating movement).
parallelization
Parallel curves can be interesting. For example, the Panton Kurve really comes to life with its parellel neighbors (thanks Jared for bringing this to the new century!). NuG's Rainbow's Edge makes it easy to create parallel curves. The examples above were generated with a few lines of code each:
final RainbowsEdge edge = new RainbowsEdge(LIST, OF, OFFSETS); edge.append(SOME_SHAPE, false); final Shape parellelShapeAtOffset0 = edge.export(0); final Shape parellelShapeAtOffset1 = edge.export(1); // etc
Future work: to be really useful, some clipping needs to be done. For sure self-intersections need to be removed.
However, it's not trivial to figure out which ones to remove. I started looking at ways to do
aesthetic clipping (that is, aesthetically pleasing ways to remove self intersections
and intersections between several curves) ...
there are some notes on this in the code in the rainbowsedge package.
NuG uses an abstraction (courtesy of HALCYON GLAZE) that re-parameterizes Java2D shapes as spatial functions. This abstraction associates points on a shape with the length of the shape up to that point. With length as an index, you can assign width and color to any point on the shape. In the end, it's easy to render with variable width and color!
final Function widthf = new AbstractFunction(Interval.UNIT_INTERVAL, Interval.ALL_REALS) {
@Override
public float value(float length) {
return lerp(minWidth, maxWidth, (1 + (float) Math.sin(pw + fw * length)) / 2);
}
};
final ObjectFunction colorf = new AbstractObjectFunction(Interval.UNIT_INTERVAL) {
@Override
public Color value(float length) {
return new Color(
(int) Math.round(lerp(minr, maxr, (1 + (float) Math.sin(pr + fr * length)) / 2)),
(int) Math.round(lerp(ming, maxg, (1 + (float) Math.sin(pg + fg * length)) / 2)),
(int) Math.round(lerp(minb, maxb, (1 + (float) Math.sin(pb + fb * length)) / 2))
);
}
};
// HOOK IT UP:
PathTracer tracer = new PathTracer()
.setPosWidthParameter(InputParameter.LENGTH)
.setPosWidthControls(Collections.singletonList(widthf));
final Shape shape = FontFactory.getPx10Font().deriveFont( 120.f ).createGlyphVector( g2d.getFontRenderContext(),
"connexxi0n?"
).getOutline( 100, 100 );
final Path path = ShapePathUtilities.createPathFromShape(shape);
PathTracer.render(g2d, 0.f, 1.f, tracer, colorf, InputParameter.LENGTH, 1.f, path);
noise generators
#1
launch . Interaction: click & drag to change forces
#2
launch