Capture click on rectangle while using ofEasyCam?


#1

What is the simplest way of detecting whether a rectangle is “clicked on” while ofEasyCam is on? (such that no matter what angle and zoom I am at, I can still register a click on the rectangle.)

I have this so far, which works when ofEasyCam is off:

if (mouseX >= rectangleLocationX && mouseX <= rectangleLocationX + rectangleSizeX && 
            mouseY >= rectangleLocationY && mouseY <= rectangleLocationY + rectangleLocationY + rectangleSizeY ) {...}

#2

well first use the ofRectangle class. it will save you all those lines you posted :smiley:

ofRectangle rect;
rect.set(x, y, width, height);
if(rect.inside(mouseX, mouseY) ){
///mouse is inside!!
}

The cool thing about ofRectangle is that it is widely used within the OF core so if you want to draw an image inside an ofRectangle instance you just say


ofImage img; //assuming this image is declared in the .h file and correctly loaded.

//then in draw();
img.draw(rect);//assumming that rect is an ofRectangle instance, like the one declared further up.

so then, ofEasyCam.
just call screenToWorld() on the ofEasyCam object, passing the mouse coordinates, then perform the rectangle check.
cheers


#3

Thank you for your help! I’m really scratching my head on this one.

This is what I have; it does not work :(. What am I doing wrong here?

class ofApp : public ofBaseApp{
public:
    static constexpr int X = 0;
    static constexpr int Y = 0;
    static constexpr int sX = 60;
    static constexpr int sY = 88;

    ofRectangle rectangle;
    ofEasyCam cam;
}

void ofApp::setup(){
    rectangle.set(X, Y, sX, sY);
} 

void ofApp::draw(){
    cam.begin();
    ofDrawRectangle(rectangle);
    cam.end();
}

void ofApp::mousePressed(int x, int y, int button){
    ofVec3f screenToWorld = cam.screenToWorld(ofVec3f(x,y,0.0));
    if (rectangle.inside(screenToWorld)) {
        cout << "hit" << endl;
    }
}

#4

I got this to work by doing the following: Calling cam.worldToScreen for every corner of the rectangle, then creating an ofPolyline with the four "worldToScreen"ed corners of the rectangle, and then calling .inside(mouseCoords) on the path.

ofApp.h

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
	static constexpr int X = 0;
	static constexpr int Y = 0;
	static constexpr int sX = 60;
	static constexpr int sY = 88;

		void setup();
		void update();
		void draw();

		void mousePressed(int x, int y, int button);

        ofEasyCam cam;

	ofRectangle rectangle1;

};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
    rectangle1.set(X, Y, sX, sY);
}

//--------------------------------------------------------------
void ofApp::draw(){
    cam.begin();
    ofSetColor(0, 255, 0);
    ofDrawRectangle(rectangle1);
    cam.end();
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){
    ofVec3f rectToScreen_botLeft = cam.worldToScreen(rectangle1.getBottomLeft());
    ofVec3f rectToScreen_botRight = cam.worldToScreen(rectangle1.getBottomRight());
    ofVec3f rectToScreen_topRight = cam.worldToScreen(rectangle1.getTopRight());
    ofVec3f rectToScreen_topLeft = cam.worldToScreen(rectangle1.getTopLeft());

    ofPolyline p;
    p.addVertex(rectToScreen_topLeft);
    p.addVertex(rectToScreen_topRight);
    p.addVertex(rectToScreen_botRight); 
    p.addVertex(rectToScreen_botLeft);

    if (p.inside(ofVec3f(x,y,0))) {
        cout << "Clicked on rectangle" << endl;
    }
}