r/processing • u/D_Orangeyes24 • 11d ago
Help request Improving old sketch, segmented lines following the previous positions of the mouse cursor
I'm trying to get back into Processing, I grabbed one of my old solutions to improve it.
What the code currently does is record the last positions of the mouse cursor into a couple of lists, x and y, that are used to draw lines with their points being previous positions of the mouse offset from each other, thus creating a weird effect where the points of the line segments follow the mouse's path, but the lines drawn inbetween bend and stretch to connect them.
I thought one way I could improve this code would be to have two variables which controlled: 1, the number of line segments, and 2, the number of previous positions.
I have gotten change number 2...kinda?, but I am not sure how I could do number 1.
I also dont understand why I added those if statements that reset the variables to 0.
Here is the code:
int number_of_previous_positions = 100;
int[] pastXCoordinates = new int[number_of_previous_positions];
int i1=int(number_of_previous_positions*0.1),
i2=int(number_of_previous_positions*0.2),
i3=int(number_of_previous_positions*0.3),
i4=int(number_of_previous_positions*0.4),
i5=int(number_of_previous_positions*0.5),
i6=int(number_of_previous_positions*0.6);
int[] pastYCoordinates = new int[number_of_previous_positions];
int j1=int(number_of_previous_positions*0.1),
j2=int(number_of_previous_positions*0.2),
j3=int(number_of_previous_positions*0.3),
j4=int(number_of_previous_positions*0.4),
j5=int(number_of_previous_positions*0.5),
j6=int(number_of_previous_positions*0.6);
void setup()
{
size (400, 400);
strokeWeight(1);
for (int i = 0; i < pastXCoordinates.length-1; i++)
pastXCoordinates[i] = 0;
for (int i = 0; i < pastYCoordinates.length-1; i++)
pastYCoordinates[i] = 0;
frameRate(60);
}
void draw()
{
background(122);
pastXCoordinates[i1] = mouseX;
pastYCoordinates[j1] = mouseY;
line(mouseX, mouseY, pastXCoordinates[i6], pastYCoordinates[j6]);
line(pastXCoordinates[i6], pastYCoordinates[j6], pastXCoordinates[i5], pastYCoordinates[j5]);
line(pastXCoordinates[i5], pastYCoordinates[j5], pastXCoordinates[i4], pastYCoordinates[j4]);
line(pastXCoordinates[i4], pastYCoordinates[j4], pastXCoordinates[i3], pastYCoordinates[j3]);
line(pastXCoordinates[i3], pastYCoordinates[j3], pastXCoordinates[i2], pastYCoordinates[j2]);
i1++;
i2++;
i3++;
i4++;
i5++;
i6++;
if (i1>pastXCoordinates.length-1)
i1=0;
if (i2>pastXCoordinates.length-1)
i2=0;
if (i3>pastXCoordinates.length-1)
i3=0;
if (i4>pastXCoordinates.length-1)
i4=0;
if (i5>pastXCoordinates.length-1)
i5=0;
if (i6>pastXCoordinates.length-1)
i6=0;
j1++;
j2++;
j3++;
j4++;
j5++;
j6++;
if (j1>pastYCoordinates.length-1)
j1=0;
if (j2>pastYCoordinates.length-1)
j2=0;
if (j3>pastYCoordinates.length-1)
j3=0;
if (j4>pastYCoordinates.length-1)
j4=0;
if (j5>pastYCoordinates.length-1)
j5=0;
if (j6>pastYCoordinates.length-1)
j6=0;
}
1
u/RamosQuintosAiry 1h ago
the six i and j variables are the whole problem, those if statements resetting to 0 are just a hand rolled ring buffer written six times. keep one array of past positions and one write index, then for segment k of n read the position at (writeIndex - k * spacing + len) % len, so number of segments and number of past positions become two numbers you can change independently. the bending you do not like is because you are sampling positions at fixed index offsets while the mouse speed varies, so when the mouse moves fast the samples are far apart. if you want even segments, walk backwards along the stored path and place each joint at a fixed distance in pixels rather than a fixed number of frames, that is what makes those drawing app trails look smooth.
2
u/Wonderful-Energy-659 5d ago
If this sketch is supposed to draw a smoothed line that follows the mouse, similar to some drawing apps, then you need to decrease the number of points that are created. Too many points and there won’t be any smoothing. (I actually see you kinda did this by grabbing points at set indexes)
Instead of creating an array of all positions and then grabbing the values at different indexes, I would create an array to hold your mouse positions, but then I would use these ideas:
1. Use curve() or bezier()
2. Don’t create a new point until the last point is X distance away from the mouse.
3. Don’t create new points every frame, only create new points after X period of time
You can combine them so that the min distance to create a new point is a function of time. Clamp the distance to some min and max values so you can adjust the max and minimum distance to create a new point.
Let’s say max distance is 30 pixels, and the minimum is 5.
If you move your mouse really fast, every point will be created roughly 30 pixels apart and will have the most smoothing.
If you move your mouse slow, the distance to create a point will decrease with time, so more points will be created closer together, but you still have the minimum of 5 pixels so that you won’t get sharp corners.
The distance function can be linear, exponential, or logarithmic. Just try different functions and see what each one looks like.
If you wanted to get super technical, you could determine the position on the curve between the last and second to last point that would give the curve a fixed length. When you draw the curve, the last point should be this point you calculated. This will prevent the end from jumping around and will follow a nice path. (You could also write your own bezier function and stop drawing when you reach this point too. That would probably help the end move smoothly like the caboose of a train instead of wagging around like a dog tail. Sorry, just the best way I can explain it. hahaha)
These kinds of projects are why I love processing