Changing colours of triangles with mousex and mousey

R_BR_B
edited December 2015 in Questions about Code

I'm trying to make a simple sketch where depending on mouse location, the triangle changes colour.

I can do this for quarter squares by saying if (mouseX < 300 & mouseY < 300) { rect ... }

but am unable to work out how to define the triangle from two corners to the centre - shown in my sketch as coloured red.

void draw() {
  background(145,180,70);

  if (mouseX < 300 & mouseY < 300) {
    triangle(0, 0, 0,600, 300,300); // Left
    fill(190,75,90);
    }

    if (mouseX > 300 & mouseY > 300){
    triangle(300, 300, 600,600, 600,0); // Left
    fill(190,75,90); // Right
  }
}

Answers

  • edited December 2015 Answer ✓

    If i understand your goal correctly, you could use atan2() to calculate the angle of the mouse-position in relation to the window-center. Something like this:

    void draw() {
    
      background(0);
    
      // get angle
      float angle = degrees(atan2( mouseY-height/2, mouseX-width/2));
    
      // make angle positive
      if (angle<0) angle = angle+360;
    
      // bottom
      if (angle >= 45 && angle < 135) {
        triangle(width/2, height/2, width, height, 0, height);
      } 
    
      // left
      else if (angle >=135 && angle < 225) {
        triangle(width/2, height/2, 0, height, 0, 0);
      } 
    
      // top
      else if (angle >=225 && angle < 315) {
        // draw top triangle
      } 
    
      // right
      else {
        // draw right triangle
      }
    }
    
  • oh dear... far too complicate...

    imho, you could draw the same triangle in an invisible PGraphics of the same size like your screen (and with noSmooth() I guess). Here the color is unaltered and identifies the triangle. Now, on mouse click use pg.get() to retrieve the color of the point and compare it to the fixed color of your triangle. Thus without using heavy math you can comfortable identify different triangles.

  • Some fun with triangles. There is an adapted test for "insideness" of the triangle (credits on code). It works like a charm, but I dont really get all the math...

    The code is a bit more complicated, but the TShape class can be hepfull, maybe.

    //CLICK MOUSE TO RESET 
    
    
    TShape t;
    int TRIWIDTH = 40;
    int bottonMargin ;
    
    TShape[][] upLine = new TShape [TRIWIDTH/3][];
    TShape[][] downLine = new TShape [TRIWIDTH/3][];
    
    boolean blackWhite = true;
    
    void setup() {
      size(900, 500, P2D);
    
      //some offset calcs
      bottonMargin = height - 50;
      int firstupLineLength = TRIWIDTH * (upLine.length-1);
      PVector startPoint = new PVector(width/2 - firstupLineLength/2, bottonMargin); 
    
      // lines pointing up
      for ( int i = 0; i < upLine.length; i++) {
        //create always smaller lines...
        upLine[i] = new TShape [upLine.length - i];
    
        // populate lines
        for ( int j = 0; j < upLine.length -i; j++) {
    
          // offsets from startPoint
          float locX = startPoint.x +j * TRIWIDTH/2 + i*TRIWIDTH;
          float locY = startPoint.y - j * TRIWIDTH * 0.85;// cheatting '0.85'
    
          upLine[i][j] = new TShape(locX, locY, TRIWIDTH, color(0));
        }
      }
    
      //lines pointing down
      for ( int i = 0; i < downLine.length; i++) {
    
        //create always smaller lines...
        downLine[i] = new TShape [downLine.length - i]; 
    
        // populate lines
        for ( int j = 0; j < downLine.length -i; j++) {
    
          // offsets from startPoint
          float locX = startPoint.x  +j * TRIWIDTH/2 + i*TRIWIDTH;
          float locY = startPoint.y + TRIWIDTH/2 + 3 - j * TRIWIDTH * 0.85; // more cheating '3'
    
          // skip line that would be under first one
          // don't want to recalc all, cheat
          if (j > 0) {
            downLine[i][j] = new TShape(locX, locY, TRIWIDTH, color(0));
            downLine[i][j].rotateT(180);
          }
        }
      }
    
    
      smooth();
    }
    
    
    
    
    void draw() {
      background(255);
      //  t.display();
    
      for ( int i = 0; i < upLine.length; i++) {
        for ( int j = 0; j < upLine.length -i; j++) {
          upLine[i][j].display();
          if (j > 0) {//cheat
            downLine[i][j].display();
          }
        }
      }
    }
    
    
    
    
    void mousePressed() {
      color w = blackWhite?  color(255):color(0);
      for ( int i = 0; i < upLine.length; i++) {
        for ( int j = 0; j < upLine.length -i; j++) {
          upLine[i][j].setColor(color(0));
          ;
    
          if (j > 0) {//cheat
            downLine[i][j].setColor(w);
          }
        }
      }
      blackWhite = !blackWhite;
    }
    
    
    
    
    class TShape {
    
      //properties
      PVector[] pts;
      PVector center;
    
      float rad, rotation = 30.;
      color c;
      PShape tri;
    
      //cheat i found that by testing
      // to make the base of triangle the number inputed as 'rad'
      float ratio = 0.577350289;
    
      boolean wasInside = false;
    
      TShape(float _x, float _y, float _r, color _c) {
        rad =_r*ratio;
        pts  =  getCoordinatesFromCenter(_x, _y, rad, rotation);
        makeTShape(pts);
        c = _c;
    
        //draw from center
        center = new PVector(_x, _y);
      }
    
    
      void makeTShape(PVector[] p) {
    
        //using vertex to call noStroke
        //I could not call it using createShape(TRIANGLE...
        tri = createShape();
        tri.beginShape();
        tri.noStroke();
        tri.vertex(pts[0].x, pts[0].y);
        tri.vertex(pts[1].x, pts[1].y);
        tri.vertex(pts[2].x, pts[2].y);
        tri.endShape();
      }
    
      void setColor(color newColor) {
        c = newColor;
      }
    
      void display() {
    
        //color based on mouse
        if (!mouseInTriangle()) {
          tri.setFill(c);
        } 
        else {
          tri.setFill(color(brightness(c), 10));
        }
    
    
        pushMatrix();
        translate(center.x, center.y);
    
        shape(tri, 0, 0);
        popMatrix();
    
        //change colors after mouse Leaving
        if (justLeft()) {
          c = color(random(30, 80));
        }
      }
    
      void rotateT (float degrees) {
    
        // making my own rotation to be considered by muose test
        rotation+=degrees;
        pts = getCoordinatesFromCenter(center.x, center.y, rad, rotation);
        makeTShape(pts);
      }
    
    
      // a function using trig to get coordinates for triangle
      PVector[] getCoordinatesFromCenter(float x, float y, float d, float r) {
        PVector[] coord = new PVector [3];
        coord[0] = new PVector (cos(radians(r)) * d, sin(radians(r)) * d);
        coord[1] = new PVector (cos(radians(120+r)) * d, sin(radians(120+r)) * d);
        coord[2] = new PVector (cos(radians(240+r)) * d, sin(radians(240+r)) * d);
        return coord;
      }
    
    
      boolean justLeft() {
        if (wasInside) {
          if (!mouseInTriangle()) {
            wasInside = false;
            return true;
          }
        }
        return false;
      }
    
    
    
    
      // test for insidness get from
      //www.openprocessing.org/sketch/12681
      //by Dan Thompson
      //he states:
      // Concept taken from the "Same Side Technique" example on this site:
      // www.blackpawn.com/texts/pointinpoly/default.html
    
      // I adapted the code to work from inside the class.
      // but did not really get all the math...
      // and changed methods capital inicial char
    
    
    
    
      boolean mouseInTriangle() {
        PVector mouse = new PVector(mouseX - center.x, mouseY - center.y);
        if (sameSide( mouse, pts[0], pts[1], pts[2]) &&
          sameSide( mouse, pts[1], pts[0], pts[2]) && 
          sameSide( mouse, pts[2], pts[0], pts[1])) {
          wasInside = true;
          return true;
        } 
        else {
          return false;
        }
      }// mouseInTriangle
    
    
    
    
    
        boolean sameSide(PVector p1, PVector p2, PVector a, PVector b) {
        b = PVector.sub(b, a);
        p1 = PVector.sub(p1, a);
        p2 = PVector.sub(p2, a);
    
    
        PVector cp1 = b.cross(p1);
        PVector cp2 = b.cross(p2);
    
        if ((cp1.dot(cp2)) >= 0) {
          return true;
        } 
        else
          return false;
      }// eof sameSide
    }// eof TShape
    
Sign In or Register to comment.