How to animate a 3D curve between two points on a map? - animation

I am trying to do a twitter visualization.
I using curves to connect two points on the map.
Here is the code which I am using for it. It has been taken from an example by Chrisir from the processing forums.
void setup()
{
size( 800, 800, P3D );
} // setup
void draw()
{
// myCurveTest() ;
PVector firstpoint = new PVector (120, 320, -30);
PVector secondpoint = new PVector (320, 220, -30);
myCurve (firstpoint, secondpoint ) ;
firstpoint = new PVector (420, 220, 30);
secondpoint = new PVector (620, 120, -30);
myCurve (firstpoint, secondpoint ) ;
}
void myCurve (
PVector firstpoint,
PVector secondpoint) {
PVector beginningcontrolpoint = new PVector (120, firstpoint.y+1200, -30);
PVector endingcontrolpoint = new PVector (720, secondpoint.y+1200, -30);
myPointPVector(beginningcontrolpoint, color(255, 0, 0));
myPointPVector(firstpoint, color(0, 0, 255));
myPointPVector(secondpoint, color(0, 0, 255));
myPointPVector(endingcontrolpoint, color(255, 0, 0));
stroke (255);
noFill();
curve(
beginningcontrolpoint.x, beginningcontrolpoint.y, beginningcontrolpoint.z,
firstpoint.x, firstpoint.y, firstpoint.z,
secondpoint.x, secondpoint.y, secondpoint.z,
endingcontrolpoint.x, endingcontrolpoint.y, endingcontrolpoint.z);
}
void myPointPVector (PVector test, color col1) {
MyBox(test.x, test.y, test.z,
test.x+3, test.y, test.z,
9,
col1);
}
void MyBox(float x1, float y1, float z1, float x2, float y2, float z2, float weight, color strokeColour)
// was called drawLine; programmed by James Carruthers
// see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
{
PVector p1 = new PVector(x1, y1, z1);
PVector p2 = new PVector(x2, y2, z2);
PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
float phi = acos(v1.z/rho);
float the = atan2(v1.y, v1.x);
v1.mult(0.5);
pushMatrix();
translate(x1, y1, z1);
translate(v1.x, v1.y, v1.z);
rotateZ(the);
rotateY(phi);
noStroke();
fill(strokeColour);
box(weight, weight, p1.dist(p2)*1.2);
popMatrix();
}
I want to animated this 3D curve so that I can see them being drawn on the map. Can anyone help me out with this. I have tried everything from framecount to advanced animation libraried in processing but no luck yet :(
Thanks.

You may just calculate a parabola point by point, draw it using curveVertex and orbit it in 3D using translate and rotate, here an example (using 1.5.1/P3D/fontMode(SCREEN)):
float initial_x = -200;
float x = initial_x;
float y;
float y_offset;
float r = 200;// change this to change the height of the parabola
ArrayList<PVector> pts = new ArrayList<PVector>();
float mx = 70, my = -15, tmx, tmy;
boolean animating = false;
PFont f;
void setup() {
size( 800, 400, P3D);
background(255);
smooth();
f = createFont("Arial", 15);
textMode(SCREEN);
}
void draw() {
//lights();
background(255);
fill(100);
textFont(f, 15);
text("drag to orbit", width - 10 - textWidth("drag to orbit"), height -30);
text("any key to redraw parabola", width - 10 - textWidth("any key to redraw parabola"), height -10);
//rotate 3d
translate(width/4, height/2);
rotateY(radians(mx));
rotateZ(radians(my));
// to mark origin and help view 3d
noFill();
stroke(100);
box(20);
pushMatrix();
translate(100, 5, -100);
stroke(200);
fill(0, 20);
box(600, 2, 600);
popMatrix();
//store y offset
if (x == initial_x) {
y_offset = (sq(x)+2*x)/r;
}
// stop parabola
if ( x == initial_x || x < -initial_x + 2) {
x+=2;
animating = true;
// add to curve storage
pts.add(new PVector(x, y));
}
else {
animating = false;
}
//calc y
y = (sq(x)+2*x)/r - y_offset;
stroke(50, 30, 7);
noFill();
strokeWeight(1);
//draw at origin
translate(-initial_x, 0);
//draw curve
beginShape();
for (PVector p:pts) {
curveVertex(p.x, p.y);
}
endShape();
//draw a ball
if (!animating) {
translate(pts.get(frameCount%pts.size()).x, pts.get(frameCount%pts.size()).y);
noStroke();
fill(220, 190, 35);
sphere(4);
}
}
void mousePressed() {
tmx = mouseX;
tmy = mouseY;
}
void mouseDragged() {
mx = tmx - mouseX;
my = tmy - mouseY;
}
void keyPressed() {
x = -200;
pts.clear();
}

You're drawing the curves using the curve() command (http://processing.org/reference/curve_.html) which draws a Catmull-Rom spline. In your code, you're only drawing a single spline section (the one between the two control points), so what you're really interested in is "how can I draw only part of a Catmull-Rom spline section". I don't have the answer for that one, but if you change your curve(control1, first, second, control2) call into a bezier(first,c1,c2,second) call (where you will now have to come up with the code for the control points c1 and c2) instead, then you can use de Casteljau's algorithm to cut up a curve into two segments anywhere along it. If you slide up the where-to-cut-it point every frame, and then only draw the first segment that you get from the split operation, it'll look like a curve that draws itself from the start to the end point. See http://pomax.github.io/bezierinfo/#splitting for the description on how to do this (bonus: the source code is even in Processing)

Make use of the curvePoint() method. Here is a resolution to a similar problem:
http://forum.processing.org/one/topic/animation-with-curve.html.

Related

How can add interaction and animation to shapes drawn in Processing?

I'm trying to code a canvas full of shapes(houses) and animate them in processing.
Here's an example of shape:
void house(int x, int y) {
pushMatrix();
translate(x, y);
fill(0, 200, 0);
triangle(15, 0, 0, 15, 30, 15);
rect(0, 15, 30, 30);
rect(12, 30, 10, 15);
popMatrix();
}
By animation I mean moving them in random directions.
I would also like to add basic interaction: when hovering over a house it's colour would change.
At the moment I've managed to render a canvas full of houses:
void setup() {
size(500, 500);
background(#74F5E9);
for (int i = 30; i < 500; i = i + 100) {
for (int j = 30; j < 500; j = j + 100) {
house(i, j);
}
}
}
void house(int x, int y) {
pushMatrix();
translate(x, y);
fill(0, 200, 0);
triangle(15, 0, 0, 15, 30, 15);
rect(0, 15, 30, 30);
rect(12, 30, 10, 15);
popMatrix();
}
Without seeing source code: your attempted sketch it's very hard to tell.
They can be animated in many ways and it's unclear what you mean. For example, is that the position/rotation/scale of each square, is it the corners/vertices of each square, both ?
You might have a clear idea in your mind, but the current form of the question is ambiguous. We also don't know you're comfort level with various notions such as classes/objects/PVector/PShape/etc. If you were to 'story board' this animation what would it look like ? Breaking the problem down and explaining it in a way that anyone can understand might actually help you figure out a solution on your own as well.
Processing has plenty of examples. Here are a few I find relevant based on what my understanding is of your problem.
You can have a look at the Objects and Create Shapes examples:
File > Examples > Basics > Objects > Objects: Demonstrates grouping drawing/animation (easing, damping). You can tweak this example draw a single square and once you're happy with the look/motion you can animate multiple using an array or ArrayList
File > Examples > Topics > Create Shapes > PolygonPShapeOOP3: Great example using PShape to animate objects.
File > Examples > Topics > Create Shapes > WigglePShape: This example demonstrates how to access and modify the vertices of a PShape
For reference I'm simply copy/pasting the examples mentioned above here as well:
Objects
/**
* Objects
* by hbarragan.
*
* Move the cursor across the image to change the speed and positions
* of the geometry. The class MRect defines a group of lines.
*/
MRect r1, r2, r3, r4;
void setup()
{
size(640, 360);
fill(255, 204);
noStroke();
r1 = new MRect(1, 134.0, 0.532, 0.1*height, 10.0, 60.0);
r2 = new MRect(2, 44.0, 0.166, 0.3*height, 5.0, 50.0);
r3 = new MRect(2, 58.0, 0.332, 0.4*height, 10.0, 35.0);
r4 = new MRect(1, 120.0, 0.0498, 0.9*height, 15.0, 60.0);
}
void draw()
{
background(0);
r1.display();
r2.display();
r3.display();
r4.display();
r1.move(mouseX-(width/2), mouseY+(height*0.1), 30);
r2.move((mouseX+(width*0.05))%width, mouseY+(height*0.025), 20);
r3.move(mouseX/4, mouseY-(height*0.025), 40);
r4.move(mouseX-(width/2), (height-mouseY), 50);
}
class MRect
{
int w; // single bar width
float xpos; // rect xposition
float h; // rect height
float ypos ; // rect yposition
float d; // single bar distance
float t; // number of bars
MRect(int iw, float ixp, float ih, float iyp, float id, float it) {
w = iw;
xpos = ixp;
h = ih;
ypos = iyp;
d = id;
t = it;
}
void move (float posX, float posY, float damping) {
float dif = ypos - posY;
if (abs(dif) > 1) {
ypos -= dif/damping;
}
dif = xpos - posX;
if (abs(dif) > 1) {
xpos -= dif/damping;
}
}
void display() {
for (int i=0; i<t; i++) {
rect(xpos+(i*(d+w)), ypos, w, height*h);
}
}
}
PolygonPShapeOOP3:
/**
* PolygonPShapeOOP.
*
* Wrapping a PShape inside a custom class
* and demonstrating how we can have a multiple objects each
* using the same PShape.
*/
// A list of objects
ArrayList<Polygon> polygons;
// Three possible shapes
PShape[] shapes = new PShape[3];
void setup() {
size(640, 360, P2D);
shapes[0] = createShape(ELLIPSE,0,0,100,100);
shapes[0].setFill(color(255, 127));
shapes[0].setStroke(false);
shapes[1] = createShape(RECT,0,0,100,100);
shapes[1].setFill(color(255, 127));
shapes[1].setStroke(false);
shapes[2] = createShape();
shapes[2].beginShape();
shapes[2].fill(0, 127);
shapes[2].noStroke();
shapes[2].vertex(0, -50);
shapes[2].vertex(14, -20);
shapes[2].vertex(47, -15);
shapes[2].vertex(23, 7);
shapes[2].vertex(29, 40);
shapes[2].vertex(0, 25);
shapes[2].vertex(-29, 40);
shapes[2].vertex(-23, 7);
shapes[2].vertex(-47, -15);
shapes[2].vertex(-14, -20);
shapes[2].endShape(CLOSE);
// Make an ArrayList
polygons = new ArrayList<Polygon>();
for (int i = 0; i < 25; i++) {
int selection = int(random(shapes.length)); // Pick a random index
Polygon p = new Polygon(shapes[selection]); // Use corresponding PShape to create Polygon
polygons.add(p);
}
}
void draw() {
background(102);
// Display and move them all
for (Polygon poly : polygons) {
poly.display();
poly.move();
}
}
// A class to describe a Polygon (with a PShape)
class Polygon {
// The PShape object
PShape s;
// The location where we will draw the shape
float x, y;
// Variable for simple motion
float speed;
Polygon(PShape s_) {
x = random(width);
y = random(-500, -100);
s = s_;
speed = random(2, 6);
}
// Simple motion
void move() {
y+=speed;
if (y > height+100) {
y = -100;
}
}
// Draw the object
void display() {
pushMatrix();
translate(x, y);
shape(s);
popMatrix();
}
}
WigglePShape:
/**
* WigglePShape.
*
* How to move the individual vertices of a PShape
*/
// A "Wiggler" object
Wiggler w;
void setup() {
size(640, 360, P2D);
w = new Wiggler();
}
void draw() {
background(255);
w.display();
w.wiggle();
}
// An object that wraps the PShape
class Wiggler {
// The PShape to be "wiggled"
PShape s;
// Its location
float x, y;
// For 2D Perlin noise
float yoff = 0;
// We are using an ArrayList to keep a duplicate copy
// of vertices original locations.
ArrayList<PVector> original;
Wiggler() {
x = width/2;
y = height/2;
// The "original" locations of the vertices make up a circle
original = new ArrayList<PVector>();
for (float a = 0; a < radians(370); a += 0.2) {
PVector v = PVector.fromAngle(a);
v.mult(100);
original.add(new PVector());
original.add(v);
}
// Now make the PShape with those vertices
s = createShape();
s.beginShape(TRIANGLE_STRIP);
s.fill(80, 139, 255);
s.noStroke();
for (PVector v : original) {
s.vertex(v.x, v.y);
}
s.endShape(CLOSE);
}
void wiggle() {
float xoff = 0;
// Apply an offset to each vertex
for (int i = 1; i < s.getVertexCount(); i++) {
// Calculate a new vertex location based on noise around "original" location
PVector pos = original.get(i);
float a = TWO_PI*noise(xoff,yoff);
PVector r = PVector.fromAngle(a);
r.mult(4);
r.add(pos);
// Set the location of each vertex to the new one
s.setVertex(i, r.x, r.y);
// increment perlin noise x value
xoff+= 0.5;
}
// Increment perlin noise y value
yoff += 0.02;
}
void display() {
pushMatrix();
translate(x, y);
shape(s);
popMatrix();
}
}
Update
Based on your comments here's an version of your sketch modified so the color of the hovered house changes:
// store house bounding box dimensions for mouse hover check
int houseWidth = 30;
// 30 px rect height + 15 px triangle height
int houseHeight = 45;
void setup() {
size(500, 500);
}
void draw(){
background(#74F5E9);
for (int i = 30; i < 500; i = i + 100) {
for (int j = 30; j < 500; j = j + 100) {
// check if the cursor is (roughly) over a house
// and render with a different color
if(overHouse(i, j)){
house(i, j, color(0, 0, 200));
}else{
house(i, j, color(0, 200, 0));
}
}
}
}
void house(int x, int y, color fillColor) {
pushMatrix();
translate(x, y);
fill(fillColor);
triangle(15, 0, 0, 15, 30, 15);
rect(0, 15, 30, 30);
rect(12, 30, 10, 15);
popMatrix();
}
// from Processing RollOver example
// https://processing.org/examples/rollover.html
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}
// check if the mouse is within the bounding box of a house
boolean overHouse(int x, int y){
// offset half the house width since the pivot is at the tip of the house
// the horizontal center
return overRect(x - (houseWidth / 2), y, houseWidth, houseHeight);
}
The code is commented, but here are the main takeaways:
the house() function has been changed so you can specify a color
the overRect() function has been copied from the Rollover example
the overHouse() function uses overRect(), but adds a horizontal offset to take into account the house is drawn from the middle top point (the house tip is the shape's pivot point)
Regarding animation, Processing has tons of examples:
https://processing.org/examples/sinewave.html
https://processing.org/examples/additivewave.html
https://processing.org/examples/noise1d.html
https://processing.org/examples/noisewave.html
https://processing.org/examples/arrayobjects.html
and well as the Motion / Simulate / Vectors sections:
Let's start take sine motion as an example.
The sin() function takes an angle (in radians by default) and returns a value between -1.0 and 1.0
Since you're already calculating positions for each house within a 2D grid, you can offset each position using sin() to animate it. The nice thing about it is cyclical: no matter what angle you provide you always get values between -1.0 and 1.0. This would save you the trouble of needing to store the current x, y positions of each house in arrays so you can increment them in a different directions.
Here's a modified version of the above sketch that uses sin() to animate:
// store house bounding box dimensions for mouse hover check
int houseWidth = 30;
// 30 px rect height + 15 px triangle height
int houseHeight = 45;
void setup() {
size(500, 500);
}
void draw(){
background(#74F5E9);
for (int i = 30; i < 500; i = i + 100) {
for (int j = 30; j < 500; j = j + 100) {
// how fast should each module move around a circle (angle increment)
// try changing i with j, adding i + j or trying other mathematical expressions
// also try changing 0.05 to other values
float phase = (i + frameCount) * 0.05;
// try changing amplitude to other values
float amplitude = 30.0;
// map the sin() result from it's range to a pixel range (-30px to 30px for example)
float xOffset = map(sin(phase), -1.0, 1.0, -amplitude, amplitude);
// offset each original grid horizontal position (i) by the mapped sin() result
float x = i + xOffset;
// check if the cursor is (roughly) over a house
// and render with a different color
if(overHouse(i, j)){
house(x, j, color(0, 0, 200));
}else{
house(x, j, color(0, 200, 0));
}
}
}
}
void house(float x, float y, color fillColor) {
pushMatrix();
translate(x, y);
fill(fillColor);
triangle(15, 0, 0, 15, 30, 15);
rect(0, 15, 30, 30);
rect(12, 30, 10, 15);
popMatrix();
}
// from Processing RollOver example
// https://processing.org/examples/rollover.html
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}
// check if the mouse is within the bounding box of a house
boolean overHouse(int x, int y){
// offset half the house width since the pivot is at the tip of the house
// the horizontal center
return overRect(x - (houseWidth / 2), y, houseWidth, houseHeight);
}
Read through the comments and try to tweak the code to get a better understanding of how it works and have fun coming up with different animations.
The main changes are:
modifying the house() function to use float x,y positions (instead of int): this is to avoid converting float to int when using sin(), map() and get smoother motions (instead of motion that "snaps" to whole pixels)
Mapped sine to positions which can be used to animate
Wrapping the 3 instructions that calculate the x offset into a reusable function would allow you do further experiment. What if you used a similar technique the y position of each house ? What about both x and y ?
Go through the code step by step. Try to understand it, change it, break it, fix it and make new sketches reusing code.

Using pushMatrix(), popMatrix(), translate(), and rotate()

I have a program that draws a flower with 4 petals to the screen where ever you click. Instead of redoing the petals one at a time I was just going to attempt to rotate the flower by a quarter turn and have it overlay the first flower, so it appears to have 8 petals. The problem is that it draws the second flower some distance away from the first in the x and y direction, but as I get closer to (0,0) they get closer to overlapping (and do at (0, 0)). I'm not sure why this is happening and would appreciate any help. I'm using Processing 3 for this program.
int c_center = 15;
int c_petal = 20;
int petalsize = 70;
color rcol;
void setup(){
fullScreen();
background(0);
}
void draw(){
rcol = color(random(255), random(255), random(255));
}
void mouseClicked(){
pushMatrix();
flower();
translate(mouseX, mouseY);
rotate(PI/4);
flower();
popMatrix();
}
void flower(){
//left petal
make_petal(mouseX - (petalsize - c_petal), mouseY, petalsize, c_petal);
//right petal
make_petal(mouseX + (petalsize - c_petal), mouseY, petalsize, c_petal);
//top petal
make_petal(mouseX, mouseY - (petalsize - c_petal), c_petal, petalsize);
//bottom petal
make_petal(mouseX, mouseY + (petalsize - c_petal), c_petal, petalsize);
//flower center
fill(random(255), random(255), random(255));
ellipse(mouseX, mouseY, c_center, c_center);
}
void make_petal(int a, int b, int c, int d){
fill(rcol);
ellipse(a, b, c, d);
}
You're mixing two styles of drawing together: your flower() function uses mouseX and mouseY to determine where to draw the petals, but then you're also calling translate(mouseX, mouseY);. So you're drawing petals relative to the mouse, but then moving the entire canvas by the mouse position, and then drawing more petals relative to the mouse again.
Instead, you probably want to only use one style of drawing. Specifically, you probably don't want your flower() function to care about the mouse position. Treat it like a "stamp" that draws things around the origin at 0,0. Then move the origin by calling translate() and rotate the stamp by calling rotate().
I corrected the code thanks to feedback, so it works now in case anyone is interested. I condensed it a little by just making one petal then rotating it through a loop.
int c_center = 20;
int c_petal = int(random(5, 15));
int petalsize = int(random(30, 60));
color rcol;
void setup(){
fullScreen();
background(0);
}
void draw(){
rcol = color(random(255), random(255), random(255));
}
void mouseClicked(){
pushMatrix();
translate(mouseX, mouseY);
for(int r = 0; r < 360; r+=5){
rotate(radians(r));
flower();
}
popMatrix();
}
void flower(){
//petal
make_petal(0, 0 - (petalsize - c_petal), c_petal, petalsize);
//flower center
fill(random(255), random(255), random(255));
ellipse(0, 0, c_center, c_center);
}
void make_petal(int a, int b, int c, int d){
fill(rcol);
ellipse(a, b, c, d);
}

Using processing 3.0 render pipeline with a custom projection matrix

My goal is only to use the current processing PGraphcsOpenGL rendering pipeline replacing the camera or projection transformation matrix. The current code returns me strange results. I can't understand how processing is multiplying matrices internally or even if this is possible to achieve what I want this way.
All closest references I found are not opengl compatible. Another solution would probably be decomposing this matrix to extract camera parameters and set the camera object every frame. I couldn't make it work. But my first attempts increased the number of lines considerably.
PMatrix3D p;
void setup() {
size(600, 400, P3D);
p = new PMatrix3D(
5.400566, 0.519709, -4.3888016, 193.58757,
5.284709, -9.016302, 3.312224, 266.927,
0.012042404, 7.253584E-5, 0.0084899925, 1.0,
0, 0, 0, 1);
p.invert();
}
void draw() {
float x = map(mouseX, 0, width, -200, 200);
float z = map(mouseY, 0, height, -150, 150);
((PGraphicsOpenGL) g).camera.set(p);
//?
//((PGraphicsOpenGL) g).modelview.set(p);
//((PGraphicsOpenGL) g).projection.set(p);
background(20);
lights();
translate(width/2, height/2);
translate(x, 0, z);
box(100);
}
EDIT
Below is a code where I multiply each vertex directly with the matrix. Results are quite different from the previous code.
Processing has its own native rendering pipeline including a camera, lighting, shaders, etc. I didn't want to build a new shader just because I am not being able to set the camera matrix. However this is what I am doing now for my project. And by doing so I drop my framerate by half.Terrible.
PMatrix3D p;
void setup() {
size(600, 400, P3D);
p = new PMatrix3D(
5.400566, 0.519709, -4.3888016, 193.58757,
5.284709, -9.016302, 3.312224, 266.927,
0.012042404, 7.253584E-5, 0.0084899925, 1.0,
0, 0, 0, 1);
//p.invert();
}
void draw() {
float x = map(mouseX, 0, width, -500, 500);
float z = map(mouseY, 0, height, -500, 500);
//((PGraphicsOpenGL) g).camera.set(p);
//((PGraphicsOpenGL) g).modelview.set(p);
//((PGraphicsOpenGL) g).projection.set(p);
background(50);
lights();
//translate(width/2, height/2);
translate(x, 0, z);
stroke(0);
strokeWeight(1);
//box(100);
myBox(true);
}
void myBox(boolean multiplyed) {
float side = 10;
float h = side/2;
/* cube verteces
-----5------
--1-------6-
--------2---
-----7------
--3-------8-
--------4---
*/
PVector [] vtx = {
new PVector (-h, -h, -h),
new PVector (+h, -h, -h),
new PVector (-h, +h, -h),
new PVector (+h, +h, -h),
new PVector (-h, -h, +h),
new PVector (+h, -h, +h),
new PVector (-h, +h, +h),
new PVector (+h, +h, +h),
};
strokeWeight(5);
for(PVector v : vtx){
if(multiplyed){
PVector result = new PVector();
PMatrix3D mat = p;
mat.mult(v, result);
stroke(#ff0000);
point(result.x/result.z ,result.y/result.z) ;
}else{
point(v.x,v.y,v.z);
}
}
}
I did a bit of research on it and found out this about OpenGL:
"The renderer class, PGraphicsOpenGL, exposes a function that can be used for that purpose, called textureSapling(int mode), where mode can take the values 2 (nearest), 3 (linear), 4 (bilinear) and 5 (trilinear).
Research taken from https://github.com/processing/processing/wiki/Advanced-OpenGL, edited by technosalon.
Because you only have those options, try changing your mode variable to a higher number to see if that works.

How to store co-ordinates of all shapes on a canvas

I am trying to create a sketch which consists of randomly placed lines with random angulations and strokeWeight. The idea is that at each frame the lines change their tilt slightly according to a preset rule which in turn depends on the strokeWeight and other parameters. To do this I think I need to record the co-ordinates of each line at setup and then transform them and then record them again. If that makes sense.
Basically the question boils down to how can I record the co-ordinates of all the lines on a canvas?
Here is what I have written so far but how do I store the shape co-ordinates:
//Sets up the random lines on the canvas
//Sets up the authorities (line widths)
//Sets up the connections between lines
void setup() {
background(204);
size(800, 800);
for (int x=1;x <1000;x +=1){
fill(75, 70, 80);
//For the x y cords
float r = random(800);
float s = random(800);
//for the strokeWeight
float fat = random(5);
//for the stroke colour which varies with stroke weight
float col = random(350);
float red = random(350);
float g = random(350);
float b = random(350);
//for the initial tilt
float rot = random(360);
//stroke(242, 204, 47, 255);
strokeWeight(fat);
//stroke (red,green,blue,opacity)
stroke(fat*100, 180, 180);
//stroke(242, 204, 47, 255);
line(r,s,r+10,s+10);
rotate(radians(rot));
}
}
//This part is the diffusion animation
void draw() {
}
You might want to create a Line class that holds the information necessary to draw a line. Something like this:
class Line{
float x1, y1, x2, y2;
public Line(float x1, float y1, float x2, float y2){
this.x1 = x1;
this.y1 = y1
this.x2 = x2;
this.y2 = y2;
}
public void draw(){
line(x1, y1, x2, y2);
}
public boolean intersects(Line other){
//left as exercise for reader
}
}
Then you can randomly generate lines:
ArrayList<Line> lines = new ArrayList<Line>();
void setup(){
for(int i = 0; i < 10; i++){
lines.add(new Line(random(width), random(height), random(width), random(height));
}
}
void draw(){
background(0);
for(Line line : lines){
line.draw();
}
}
This is what I was getting at when I told you in your other question that you need to create a data structure and store your line coordinates. From here you can write logic that moves your lines around, or detects intersections, etc.

How to rotate a line in a circle (radar like) in Processing while also plotting points?

I am trying to rotate a line around in a circle that represents the direction a sensor is facing, while also plotting distance measurements. So I can't use background() in the draw function to clear the screen, because it erases the plotting of the distance readings. I've tried pggraphics and a few others ways, but can't seem to find a way to do it.
This is what I have right now:
void setup() {
background(255,255,255);
size(540, 540);
}
void draw() {
translate(width/2, height/2);
ellipse(0,0,100,100);
newX = x*cos(theta)- y*sin(theta);
newY = x*sin(theta)+ y*cos(theta);
theta = theta + PI/100;
//pushMatrix();
fill(255, 255);
line(0, 0, newX, newY);
rotate(theta);
//popMatrix();
}
I am new to Processing, and coding in general, but can anyone point me in the right direction on how to do this? Thanks
This is what it outputs: http://imgur.com/I825mjE
You can use background(). You just need to redraw the readings on each frame. You could store the readings in an ArrayList, which allows you to add new readings, change them and remove them.
An example:
ArrayList<PVector> readings;
int readingsCount = 15;
void setup() {
size(540, 540);
// create collection of random readings
readings = new ArrayList<PVector>();
for(float angle = 0; angle < TWO_PI; angle += TWO_PI/ readingsCount) {
float distance = random(100, 200);
// the new reading has an angle...
PVector newReading = PVector.fromAngle(angle);
// ... and a distance
newReading.mult(distance);
// Add the new reading to the collection
readings.add(newReading);
}
}
void draw() {
background(255);
// Put (0, 0) in the middle of the screen
translate(width/2, height/2);
float radius = 250;
noFill();
ellipse(0, 0, 2*radius, 2*radius);
// draw spinning line
float angle = frameCount * 0.1;
line(0, 0, radius * cos(angle), radius * sin(angle));
// draw readings
for(PVector p : readings) {
ellipse(p.x, p.y, 20, 20);
}
}

Resources