How to map points onto a shape in P3D mode?

How can I map my coordinates to the box object that I have used in the following sketch. I want to create something like this:

I have ended up with the following result:

Following are the codes that I’ve written thus far:

PImage worldMap;
PShape box;

Table table;
int rowCount;
float x1, y1, z1, x2, y2, z2;

void setup() {
  size(1400, 800, P3D);
  table = new Table("From_USA_Coordinates.tsv");
  rowCount = table.getRowCount();
  worldMap = loadImage("world.topo.bathy.200406.3x5400x2700.jpg"); 
  worldMap.resize(500, 300);
  textureMode(NORMAL);
  fill(255);
  stroke(color(44,48,32));
  box = createShape(BOX, 650, 300, 30);
  box.beginShape(BOX);
  box.endShape();
  box.setTexture(worldMap);
}

void draw() {
  background(255);
  noStroke();
  translate(350, 600, -50);
  rotateX(PI/4);
  //rotateY(PI);
  //rotateZ(PI/4);
  
  shape(box);  
  //Second Box:
  translate(700,0,0);
  shape(box);
  translate(-1400, 0);  
  //rotateX(-PI/4);
  
  for(int row = 0; row < rowCount; row++) {
    float USALatitude = table.getFloat(row, 3);
    float USALongitude = table.getFloat(row, 4);
    String countryName = table.getString(row,1);
    
    //Mapped Within X-axis of the left side map box
    float mappedLatitude = map(USALatitude,-90, 90, 0, 650);
    System.out.println("USALatitude: " + mappedLatitude);
    float mappedLongitude = map(USALongitude, -180, 180, 0, 300);
    System.out.println("USALongitude: " + mappedLongitude);
    x1 = mappedLatitude;
    y1 = mappedLongitude;
    z1 = -50;

    float tripCountryLatitude = table.getFloat(row, 5);
    float tripCountryLongitude = table.getFloat(row, 6);     
    float tripLatitude = map(tripCountryLatitude, -90, 90, 0, 650);
    System.out.println("TripCountryLatitude: " + tripLatitude);
    float tripLongitude = map(tripCountryLongitude, -180, 180, 0, 300);
    System.out.println("TripCountryLongitude: " + tripLongitude);
    x2 = 700 + tripLatitude;
    y2 = tripLongitude;
    z2 = 250;

    //int tripCountryOccurance = table.getInt(row, 2);  
    
    //bezierDetail(120);
    noFill();
    stroke(255, 120);
    strokeWeight(1);
     
    
    pushMatrix();    
    stroke(#F05252);
    bezier(x1, y1, z1, // First point
           x1 - 150, y1 - 150, z1 - 150, // First intermediate point
           x2 - 150, y2 - 150, z2 - 150, // Second intermediate point
           x2, y2, z2); // Final point
    popMatrix();
    
  }
}
1 Like

Hello,

I have never worked with the bezier() function in 3D so I took this out for a spin.

Here is an example I worked through to understand this:

float x1, y1, z1, x2, y2, z2;

void setup() 
  {
  size(1000, 800, P3D);
  }

void draw() 
  {
  background(255);
  //noStroke();
  strokeWeight(3);
  //translate(350, 600, -50);
  rotateX(PI/8);
  
  rectMode(CENTER);
  rect(width/2, height/2, 700, 100);
 
  noFill();
  float zOff = map(mouseY, 0, height, 300, 0); // Move mouse up and down
  
  //left point
  x1 = width/4;
  y1 = height/2;
  z1 = 0;
 
  //right point 
  x2 = 3*width/4;
  y2 = height/2;
  z2 = 0;
  
  //manual lerping
  float a = (x2-x1)/3;
  float b = (y2-y1)/3;
  
 pushMatrix();    
  stroke(#F05252);
  bezier(x1, y1, z1,                 // First point
         x1 + a, y1 + b, z1 + zOff,  // First intermediate point
         x2 - a, y2 - b, z2 + zOff,  // Second intermediate point
         x2, y2, z2);                // Final point
 popMatrix();   
  }

I gave a lot of thougt to where the points were along the axis.

I did some manual lerping in my example.

There is a function for this:
https://processing.org/reference/lerp_.html

Linear interpolation:

I hope this helps.

:)

I may have to try this with my related post here (no code please).

1 Like

Yes, this helps a lot in how the curves can be controlled. Thank you so much for this.

My other problem, or the main problem here is how can I pinpoint those country latitude and longitude within the box I’ve created. I can map them in 2D but I’m having lots of confusion regarding 3D translation, rotation and scaling.

Do you have any suggestion.

In theory map them in 2D, apply the changes by translate etc. (Like with the cube).

Then use modelX, modelY,modelZ to store the coordinates of the same point in 3D.

Use the stored coordinates for bezier

@Chrisir Can you please go through my code and suggest me what I did wrong?

Did you implement glv‘s ideas already?

Then I would like to work from the new code

Please post

Yes and I’m much closer though its via manual implementation rather than accurate coding. :smiley:

PImage worldMap;
PShape box;

Table table;
int rowCount;
float x1, y1, z1, x2, y2, z2;

void setup() {
  size(1400, 800, P3D);
  table = new Table("From_USA_Coordinates.tsv");
  rowCount = table.getRowCount();
  worldMap = loadImage("world.topo.bathy.200406.3x5400x2700.jpg"); 
  worldMap.resize(500, 300);
  textureMode(NORMAL);
  fill(255);
  stroke(color(44,48,32));
  box = createShape(BOX, -650, 300, 30);
  box.beginShape(BOX);
  box.endShape();
  box.setTexture(worldMap);
}

void draw() {
  background(255);
  noStroke();
  translate(350, 600, -50);
  rotateX(PI/4);
  
  shape(box);  
  //Second Box:
  translate(700,0,0);
  shape(box);
  
  translate(-1400, -100, 50);  
  rotateX(radians(20));
  
  for(int row = 0; row < rowCount; row++) {
    float USALatitude = table.getFloat(row, 3);
    float USALongitude = table.getFloat(row, 4);
    String countryName = table.getString(row,1);
    
    //Mapped Within X-axis of the left side map box
    float mappedLatitude = map(USALatitude,-90, 90, 0, 650);
    System.out.println("USALatitude: " + mappedLatitude);
    float mappedLongitude = map(USALongitude, -180, 180, 0, 300);
    System.out.println("USALongitude: " + mappedLongitude);
    x1 = mappedLatitude;
    y1 = mappedLongitude;
    z1 = 0;

    float tripCountryLatitude = table.getFloat(row, 5);
    float tripCountryLongitude = table.getFloat(row, 6);     
    float tripLatitude = map(tripCountryLatitude, -90, 90, 0, 650);
    System.out.println("TripCountryLatitude: " + tripLatitude);
    float tripLongitude = map(tripCountryLongitude, -180, 180, 0, 300);
    System.out.println("TripCountryLongitude: " + tripLongitude);
    x2 = 700 + tripLatitude;
    y2 = tripLongitude;
    z2 = 0;

    //int tripCountryOccurance = table.getInt(row, 2);  
    
    //bezierDetail(120);
    noFill();
    stroke(255, 120);
    strokeWeight(1);    
    
    float zOff = map(0, 0, height, 300, 0); // Move mouse up and down
    
    float a = (x2-x1)/3;
    float b = (y2-y1)/3;
    
    pushMatrix();    
    stroke(#F05252);
    bezier(x1, y1, z1,                 // First point
         x1 + a, y1 + b, z1 + zOff,  // First intermediate point
         x2 - a, y2 - b, z2 + zOff,  // Second intermediate point
         x2, y2, z2); 
    popMatrix();
    
  }
}

These are the links for the map file and the table :

https://drive.google.com/file/d/1sZw5Gc3xf_RTM_Ti6FeJ-_PVj49b0mlT/view?usp=sharing

https://drive.google.com/file/d/111Tmhy6YDBQBmI2AaJuTPrrtdGZZpJSy/view?usp=sharing

1 Like

I don’t have time really

but

pushMatrix();
translate rotate etc
get values from modelX etc for x1,y1,z1: float pos1in3Dx = modelX(x1,y1,z1); etc. 
popMatrix();

Repeat for x2 etc.:

pushMatrix();
translate rotate etc
get values from modelX etc for x2,y2,z2: float pos2in3Dx = modelX(x2,y2,z2); etc. 
popMatrix();

Use the 6 values

Ok thank you vey much for the help @Chrisir

For example

Insert in my notes above

float pos1in3Dx = modelX(x1,y1,z1);

Then use this

Show your attempt as entire code

Suggestion:

  • Work in P3D.
  • Work in the x,y plane with z = 0.
  • The bezier start and end coordinates are x,y with z = 0.
  • The bezier intermediate points use the z.
  • If your images are side by side along the x-axis that you can do all the above easily and then rotate everything about the x-axis.
  • Some effort will have to be made to scale and map everything correctly; that is the fun part.
  • Focus on getting the above working.
  • It will be a bit more work for you if you rotate maps as in your first picture; is that what you want?
  • One step at a time.

This is the same as my example with an extra rectangle (this can be your map):

  • I was also able to map lat and long to the x, y coordinates of rect() shape (map textured over top); the formulas are out there.

I will not post any code as this is an achievable programming exercise.

:)

1 Like

Yes thanks to you guys, I was finally able to achieve what I set out for.

3 Likes