Background of Triangular objects

Hey guys!

I’ve been playing around with processing as of yesterday and am stuck on creating a background of triangular objects for my project. The idea of the project is to have triangles in the background so that I can click on any of them to change to a specific state, but I’m struggling to create the objects in the first place.

I found a great example on the forum that creates something similar using square boxes:
http://studio.processingtogether.com/sp/pad/export/ro.9ABG0RKl9D2Bx

I figured out a way to draw the triangles using processing using the code I made down below, but I want to somehow convert them into objects so I can do things when I mouseover them and such:

for (float xPos = 0.0; xPos < 500.0; xPos += triHeight * 2) {
    for (float yPos = 0.0; yPos < 500.0; yPos += 50.0) {
      stroke(#d8adad);
      fill(colorScheme[0]); 
      triangle(xPos, yPos, xPos, yPos + triLength, xPos +  triHeight, yPos + triLength / 2);
    }
  }
  
  for (float xPos = 0.0; xPos < 500.0; xPos += triHeight * 2) {
    for (float yPos = 50.0; yPos < 500.0; yPos += 50.0) {
      triangle(xPos, yPos, xPos + triHeight, yPos - triLength / 2, xPos +  triHeight, yPos + triLength / 2);
    }
  }
  
  for (float xPos = triHeight; xPos < 500.0; xPos += triHeight * 2) {
    for (float yPos = triLength / 2; yPos < 500.0; yPos += 50.0) {
      triangle(xPos, yPos, xPos + triHeight, yPos - triLength /2, xPos + triHeight, yPos + triLength/2);
    }
  }
  
  for (float xPos = triHeight; xPos < 500.0; xPos += triHeight * 2) {
    for (float yPos = triLength / 2; yPos < 500.0; yPos += 50.0) {
      triangle(xPos, yPos, xPos + triHeight, yPos + triLength / 2, xPos, yPos + 50);
    }
  }

My initial thoughts about moving forward was to create a my own class Triangle and then creating static methods that call upon existing processing functions to do things like display the triangles, change states, etc.
However, I’m not sure how I could refer to each triangle object, even with an array. To give you guys an idea of what the background looks like, I have this:

Any advice and guidance would be helpful!

1 Like

I’d recommend googling something like “check if point is inside triangle” for a ton of results. Get this working for a single hard-coded triangle before you try it with multiple triangles. Good luck!

1 Like

Nevermind. Don’t listen to me. :rofl:

// mouse inside triangle question
// 2D only!
/*
as background and age of "jbott" is unknown 
i want try to help with the first step, what i copy from
https://stackoverflow.com/a/13301035
*/

int plong = 3;                     // point array length        
PVector[] p = new PVector[plong];  // point array
PVector pm;                        // mouse
PShape t;                          // triangle strip shape
//_________________________________________________
void setup() {
  size(200, 200);
  p[0] = new PVector( 20, 30);     // test points
  p[1] = new PVector( 40, 80);
  p[2] = new PVector( 120, 60);
  pm = new PVector( 0, 0);         // for mouse pos

  t = createShape();               // try a shape instead triangle primitiv
  t.beginShape(TRIANGLE_STRIP);
//  t.fill(0, 200, 200);
  t.noStroke();
  t.vertex(p[0].x, p[0].y);
  t.vertex(p[1].x, p[1].y);
  t.vertex(p[2].x, p[2].y);
  t.endShape();
}
//_________________________________________________
void draw() {
  background(0, 200, 0);
  pm.x = mouseX;
  pm.y = mouseY;
  if ( over_t(pm, p[0], p[1], p[2]) ) t.setFill(color(200, 0, 0)); else t.setFill(color(0, 0, 200));
  shape(t, 0, 0);
}
//_________________________________________________
boolean over_t(PVector pm, PVector p1, PVector p2, PVector p3) {
  float alpha = ((p2.y - p3.y)*(pm.x - p3.x) + (p3.x - p2.x)*(pm.y - p3.y)) /
    ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
  float beta = ((p3.y - p1.y)*(pm.x - p3.x) + (p1.x - p3.x)*(pm.y - p3.y)) /
    ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
  float gamma = 1.0 - alpha - beta;
  if ( gamma > 0 && alpha > 0 && beta > 0 ) return true;
  return false;
}

1 Like

To mouse over a triangle, you want Point-Triangle collision detection. Here is one example in Processing – there are several great Processing collision detection guides, but rectangles get the most attention and not all of them cover triangles.

http://www.jeffreythompson.org/collision-detection/tri-point.php

@jbott what is you status?
did the mouse over detection example help?
i have a version what might be more close to what you want:

some code
// mouse inside triangle question
// 2D only!
//  copy from https://stackoverflow.com/a/13301035
// https://discourse.processing.org/t/background-of-triangular-objects/5857/4
// v1    3 test point
// v2    class of 3 pvector and color, pvector array of lines 
// v3    master fill color editor: click PI and press key [f],[F],[Alt][f] and mouse scroll

int lwide=22, plong = 10*lwide;    // line and point array length        
PVector[] p = new PVector[plong];  // point array
PVector pm;                        // mouse
boolean showstroke = true, shownum = false, cedit = false, dbug = false;

int i = 0;   // point counter
int j = 0;   // triangle counter
int x0 = 10, y0 = 10, xw = 40, yw = 40;
color ct = color(200, 200, 0);    // init color
color cm = color(200, 0, 0);      // master color start default

Tri[] my_triangles = new Tri[plong];


//_________________________________________________
void make_array() {
  int l = 0;
  while ( i < plong ) {
    p[i] = new PVector(x0+xw*(0), y0+yw*(i%2)+yw*l );
    if (dbug) println("i: "+i+" j "+j+" "+p[i]);
    i++; 
    p[i] = new PVector(x0+xw*(0), y0+yw*(i%2)+yw*l );    
    if (dbug) println("i: "+i+" j "+j+" "+p[i]);
    i++; 
    for ( int k = 1; k < lwide/2; k++) {
      p[i] = new PVector(x0+xw*(k), y0+yw*(i%2)+yw*l );
      if (dbug) println("i: "+i+" j "+j+" "+p[i]);
      my_triangles[j] = new Tri(p[i-2], p[i-1], p[i], ct,j);
      i++; 
      j++;

      p[i] = new PVector(x0+xw*(k), y0+yw*(i%2)+yw*l );    
      if (dbug) println("i: "+i+" j "+j+" "+p[i]);
      my_triangles[j] = new Tri(p[i-2], p[i-1], p[i], ct,j);
      i++; 
      j++;
    }
    l++;
  }
}

//_________________________________________________
void setup() {
  size(440, 440);
  make_array();
  println("mouse click: left SET, right UNSET / key[r] RESET all / key [h] show number");
}

//_________________________________________________
void draw() {
  background(0, 200, 0);
  for (int i = 0; i < j; i++) {
    my_triangles[i].show();
    my_triangles[i].update();
  }
  the_PI();
}

//_________________________________________________
class Tri {
  PVector p1, p2, p3;
  PVector pm = new PVector(0, 0);
  color cf;
  int j;
  Tri(PVector p1, PVector p2, PVector p3, color cf,int j) {
    this.p1 = p1;
    this.p2 = p2;
    this.p3 = p3;
    this.cf = cf;
    this.j  = j;
  }

  public void show() {
    pm.x = mouseX;
    pm.y = mouseY;
    if ( over_t(pm) ) stroke(200, 0, 0);
    else        if ( showstroke ) stroke(0, 0, 200);   else noStroke();   
    fill(cf);
//    triangle(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
    beginShape();
    vertex(p1.x, p1.y);
    vertex(p2.x, p2.y);
    vertex(p3.x, p3.y);    
    endShape(CLOSE);
    if (shownum) { fill(0); text(j+1,p1.x+20*(j%2), p1.y+10-10*(j%2)); }
  }

  public void update() {
    cset();
    creset();
  }

  private void cset() {
    pm.x = mouseX;
    pm.y = mouseY;
    if ( mousePressed && mouseButton == LEFT && over_t(pm) ) cf = cm;
  }

  private void creset() {
    pm.x = mouseX;
    pm.y = mouseY;
    if ( mousePressed && mouseButton == RIGHT && over_t(pm) ) cf = ct;
  }

  public void cdefault() {
    cf = ct;
  }
    
  private boolean over_t(PVector pm) {
    float alpha = ((p2.y - p3.y)*(pm.x - p3.x) + (p3.x - p2.x)*(pm.y - p3.y)) /
      ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
    float beta = ((p3.y - p1.y)*(pm.x - p3.x) + (p1.x - p3.x)*(pm.y - p3.y)) /
      ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
    float gamma = 1.0 - alpha - beta;
    if ( gamma > 0 && alpha > 0 && beta > 0 ) return true;
    return false;
  }
}


// add secret PI function
int rposX =420, rposY=420, rwide=19;
boolean altKey = false, ctrlKey = false, shiftKey = false;
boolean mousePresent = false;
int   e_fillR=255, e_fillG=0, e_fillB=0;

void the_PI() {
  if ( cedit ) { 
    fill(cm); 
    rect( rposX, rposY, rwide, rwide );
  } else { 
    fill(0); 
    text("π", rposX+5, rposY+10);
  }
}

boolean over(int mx, int my) {
  if ((mx > (rposX)) & (mx < (rposX+ rwide))) {
    if ((my > (rposY))  & (my < (rposY+ rwide))) {
      return true;
    }
  }
  return false;
}

void mouseExited() {  
  mousePresent = false;
}
void mouseEntered() {  
  if (focused) mousePresent = true;
}

void mousePressed() { 
  if ( over(mouseX, mouseY) ) { 
    cedit = !cedit;
    if ( cedit ) { 
      println(" fill color editor function");
      println("use key [f] (Red), [F] (Green), [Alt][f] (Blue) and scroll mousewheel");
    }
  }
}

void mouseWheel(MouseEvent event) {
  float e = event.getCount();
  if ( cedit && over(mouseX, mouseY) ) {
    if ( keyPressed && key == 'f' && !altKey ) { 
      e_fillR += 2*e;
      e_fillR = constrain(e_fillR, 0, 255);
      cm = color(e_fillR, e_fillG, e_fillB);
    }          // [f] fill hue color
    if ( keyPressed && key == 'F' ) { 
      e_fillG += 2*e;
      e_fillG = constrain(e_fillG, 0, 255);
      cm = color(e_fillR, e_fillG, e_fillB);
    }          // [F]  ([Shift][f] or [Capslock][f]) fill saturation
    if ( keyPressed && key == 'f' && altKey ) { 
      e_fillB += 2*e;
      e_fillB = constrain(e_fillB, 0, 255);
      cm = color(e_fillR, e_fillG, e_fillB);
    }          // [Alt][f] fill brt
    println("fill color= ("+e_fillR+" , "+e_fillG+" , "+e_fillB+" ) ( RGB 0 .. 255 )");
  }
}


//_______________________________________________ Code KEY set
void keyPressed () {
  if (key == CODED) {
    if      (keyCode == ALT)     altKey   = true;
    else if (keyCode == SHIFT)   shiftKey = true;
    else if (keyCode == CONTROL) ctrlKey  = true;
  }
  if ( key == 'r' ) {
      for (int i = 0; i < j; i++)  my_triangles[i].cdefault();
  }
  if ( key == 'h' ) {
      shownum = !shownum;
  }
  if ( key == 's' ) {
      showstroke = !showstroke;
  }
}
//_______________________________________________ Code KEY unset
void keyReleased() {
  if ((keyCode >= '0' && keyCode <= '9') || // digit
    (keyCode >= 'A' && keyCode <= 'Z') || // upper-case letter
    (keyCode >= 'a' && keyCode <= 'z')) { // lower-case letter
    if (altKey) {
      //println("ALT " + char (keyCode)+" "+keyCode);
      altKey = false;
    } else if (ctrlKey) {
      //println("CTRL " + char (keyCode)+" "+keyCode);
      ctrlKey = false;
    } else if (shiftKey) {
      //println("SHIFT " + char (keyCode)+" "+keyCode);
      shiftKey = false;
    } //else println("KEY = "+ key+" "+keyCode);
  }
}