I’d like to achieve shapes like this, to simulate flowing “noodles” and I’d like to be able to control fill and stroke, so I’d assume it needs to be a shape, but I have no idea how to do it.
My initial thinking was to just move a circle through a path and “unite” the shapes like what you would do in a vector program, but haven’t been able to find out how to do this.
How would you achieve a shape like this, where you’d be able to control, fill, stroke and direction?
micuat
March 28, 2021, 1:29pm
2
Hi! Welcome to the forum!
I don’t know if there is a easy way to do this, but I think if you want to do it “properly”, you need to use trigonometry - basically you calculate a vector orthogonal to a small segment on each side and connect them. And if you want to do it even better, you can connect these points with curveVertex
to make it smooth. If I feel doing so maybe I can make an example later (maybe not ).
1 Like
Thank you @micuat
Certainly, it will be easier for me to try and find out just by having some direction.
micuat
March 28, 2021, 1:59pm
4
something like this - it needs smoothing etc to make it nicer and an edge case literally for the edges. Now I wonder if there is a library to do this easier, maybe exists in toxiclibs or geomerative??
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(800, 800, P2D);
}
void draw() {
float thickness = 10;
ArrayList<Float> angles = new ArrayList<Float>();
for (int i = 0; i < points.size() - 1; i++ ) {
PVector v0 = points.get(i);
PVector v1 = points.get(i+1).copy();
v1.sub(v0);
float angle = v1.heading();
angles.add(angle);
}
background(255);
stroke(100, 20, 200);
strokeWeight(3);
fill(20, 100, 230);
beginShape();
for (int i = 0; i < points.size() - 1; i++ ) {
PVector v0 = points.get(i);
float angle = angles.get(i);
angle += PI/2;
float x = cos(angle) * thickness;
float y = sin(angle) * thickness;
vertex(v0.x + x, v0.y + y);
}
for (int i = points.size() - 2; i >= 0; i-- ) {
PVector v0 = points.get(i);
float angle = angles.get(i);
angle -= PI/2;
float x = cos(angle) * thickness;
float y = sin(angle) * thickness;
vertex(v0.x + x, v0.y + y);
}
endShape(CLOSE);
}
void addPoint() {
PVector v = new PVector(mouseX, mouseY);
points.add(v);
}
void mousePressed() {
points.clear();
addPoint();
}
void mouseDragged() {
addPoint();
}
quark
March 28, 2021, 5:25pm
5
This works differently by drawing the line twice
use border colour for full line width
use line colour to replace ‘inside’ of line drawn in (1)
Works well for slow-ish mouse movement, would need some additional points added in mouseDragged for rapid mouse movement.
ArrayList<PVector> points = new ArrayList<PVector>();
float sWeight = 2;
int sCol = 0xFF0000AA;
float lWeight = 20;
int lCol = 0xFFC0C000;
void setup() {
size(800, 800, P2D);
}
void draw() {
background(255);
noStroke();
fill(sCol);
for (PVector p : points) ellipse(p.x, p.y, 2 * lWeight, 2 * lWeight);
fill(lCol);
float fWeight = lWeight - 2 * sWeight;
for (PVector p : points) ellipse(p.x, p.y, 2 * fWeight, 2 * fWeight);
}
void addPoint(float x, float y) {
points.add(new PVector(x, y));
}
void mousePressed() {
points.clear();
addPoint(mouseX, mouseY);
}
void mouseDragged() {
addPoint(mouseX, mouseY);
}
2 Likes
glv
March 28, 2021, 10:21pm
6
Hello,
I created a simple shape with curveVertex() and overlaid them to show an outline.
A line is a shape. :)
My first version for testing:
Code
// Worm
// v1.0.0
// GLV 2021-03-28
float amp;
void setup()
{
size(640, 360);
}
void draw()
{
amp = map(mouseX, 0, width, 3*height/4, height/4);
background(255);
strokeWeight(20);
noFill();
stroke(0);
myShape();
strokeWeight(15);
stroke(255);
myShape();
}
void myShape()
{
beginShape();
curveVertex(width/8, height/2);
curveVertex(width/8, height/2);;
curveVertex(width/8 + 7*width/32, amp);
curveVertex(3*width/4 - 3*width/32, height -amp);
curveVertex(7*width/8, height/2);
curveVertex(7*width/8, height/2);
endShape();
}
I then replaced all the fixed co-ordinates with variables and manipulated them (algebra and trigonometry) with code.
Not quite there yet but a work in progress:
:)
2 Likes
glv
March 29, 2021, 10:23am
7
@thesandrobrito ,
This has inspired me and had noodles of fun with this!
I am doing an event later in the year and may use something similar to engage the guests.
Update:
This can replace the mouse movement and animate it in my previous post.
amp = height/2 + 100*sin(frameCount*TAU/360);
:)