Using data to draw custom shapes

Hello! I don’t have a lot of code experience, but have been learning a lot about Processing through tutorials, etc.

I have a desire to pull data in from a csv that contains two columns : time (in decimal format) and an integer (that represents a number rating from 0-100)

I would like to draw an organic shape based off these points (see image below). I’m wondering what approach would be best in this situation. I would like the distance from center (or radius) to equal the rating integer and the angle of where the point lies to equal the time.

I’ve attempted to draw shapes, but haven’t gotten close- typically, I end up with a circle with one radius value from the data table.
Also, would the use of an array be helpful to achieve this?
Eventually, I’d also like the points to be rounded (bezier curve potentially?)

1 Like

It can be done is the generic answer here in the forum

Load your data

Did you manage to load your data using eg loadStrings or loadTable? You might want to look those up in the reference, where you find great examples.

https://www.processing.org/reference/

trigonometry

I would then read the tutorial on trigonometry. Here you can see how they do a circle with cos and sin.

https://www.processing.org/tutorials/trig/

Modify the values

For Loop over the loaded values.

Next step is to use map() - see reference: https://www.processing.org/reference/map_.html -

  • to map the time to an angle from 0 to 360 degrees (use radians() to go to radians what is needed by cos and sin): angle=map( myHour * 60 + myMinute, 0, 12*60, 0, 360 ); and

  • to map the integer value (0…100) to your radius (as a first step you can do without the 2nd mapping, because 0…100 will look ok): radius = map ( integerRating, 0, 100, 0, 400 ) ; .

You get a bunch of x,y values (the wobbly circle for your shape) which you can either store in an Array of PVector and then show using curveVertex() in a nice for loop or which you show directly using curveVertex() inside of a beginShape(); ... endShape(); section.

https://www.processing.org/reference/curveVertex_.html

Chrisir

2 Likes

Thanks for your reply, @Chrisir ! Appreciate all this thorough information!

Here’s what I’ve got – a very rough start. As I don’t have much code background, don’t be too scared of my messiness! I’m having trouble knowing how to store x,y values in an array of PVector. Also, the items inside beginShape are incorrect - nothing is actually being drawn. Any suggestions?

Table myTable = loadTable("data-small.csv", "header");
int numEntries = myTable.getRowCount();
float time;
float radius;

size(400,400);
background(255);

for(int i = 0; i < numEntries; i++){
    time = myTable.getRow(i).getFloat("Time Decimal");
    println("time:", time);
    
    radius = myTable.getRow(i).getFloat("Productivity Level");
    println("radius:", radius);

    beginShape();
        float angle = map(time,0,24,0,TWO_PI);
        float xCenter = width/2; 
        float yCenter = height/2;
        float xCoord = xCenter + sin(angle) * radius;
        float yCoord = yCenter + cos(angle) * radius;
  
        curveVertex(xCoord, yCoord);
      endShape(CLOSE);
      }
1 Like

Thanks!

Could you also post like 10 lines of your data so we have test data to work with?

Edit:

  • beginShape() and endShape() must be outside the for loop so we get a shape that consists of many points (and not many shapes and each only has one point. My bad.)

  • The curveVertex() was wrong (or is very complicate to handle. Not sure about this.) - better try vertex first. See curves tutorial or reference.

New version:



Table myTable = loadTable("data-small.csv", "header");
int numEntries = myTable.getRowCount();
float time;
float radius;

size(400, 400);
background(255);

beginShape(); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!

for (int i = 0; i < numEntries; i++) {
  time = myTable.getRow(i).getFloat("Time Decimal");
  println("time:", time);

  radius = myTable.getRow(i).getFloat("Productivity Level");
  println("radius:", radius);


  float angle = map(time, 0, 24, 0, TWO_PI);
  float xCenter = width/2; 
  float yCenter = height/2;
  float xCoord = xCenter + sin(angle) * radius;
  float yCoord = yCenter + cos(angle) * radius;

  vertex(xCoord, yCoord); // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}

endShape(CLOSE);  // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 Like

You can use fill and stroke for the shape

@Chrisir Yes! I’m seeing something! Great :slight_smile:
Here is my data

Timestamp,Time,Time Decimal,To Do List Amount,Peace Level,Life Rating,Productivity Level
"March 10, 2019 10:08:55am",10:08,10.1,3,70,82,86
"March 10, 2019 12:47:27pm",12:47,12.8,5,62,78,70
"March 10, 2019 01:42:28pm",13:42,13.7,2,76,83,65
"March 10, 2019 05:28:29pm",17:28,17.5,2,70,80,60
"March 10, 2019 06:23:46pm",18:23,18.4,2,70,80,43

@Chrisir
Hi again-- so, I simplified my data so I could see if it was accurately mapping it. And I don’t think it is… can’t exactly tell what’s going on?

Time,Time Decimal,Productivity Level
0:00,0,10
6:00,0.25,30
12:00,0.5,60
18:00,0.75,100
21:00,0.88,200

In the simplified list, Time decimal seems to be a value between 0 and 1 - and not between 0 and 24 (as it was in the previous data).

Hence your map() command is wrong, since it’s assuming the wrong range.

I am talking about this line:

float angle = map(time, 0,…

Fix it.

Similarly you can amplify the radius by using another map() command

Oh and you swapped cos and sin

Cos is for x value, sin is for y value

1 Like

Another thing: 0 degree in processing is not at the top of the circle but on its right side

This is inconvenient

You have to subtract TWO_PI/4 from your angle I guess to compensate or something similar

You want to have time 0 on the top of the circle not on its right side

wonderful – It’s all working beautifully. Thanks again for all your help! much appreciated :slight_smile:

1 Like