Algoritmo para colisão entre objeto e linha

Padrão

Objetivo:

Cabeçalhos no .h

ofPolyline square1;
ofPolyline square2;
ofPolyline line;
ofPoint closestTo1;
ofPoint closestTo2;
bool moving1;
bool moving2;
void mountSquare1(ofPoint place);
void mountSquare2(ofPoint place);
void mountLine();

Metodos no .cpp

Setup

void ofApp::setup(){
       mountSquare1(ofPoint(100, 100));
       mountSquare2(ofPoint(400, 100));
       mountLine();

       moving1 = false;
       moving2 = false;

       ofSetLogLevel(OF_LOG_VERBOSE);
}

mountSquare1

void ofApp::mountSquare1(ofPoint place) {
       square1.clear();
       square1.addVertex(place + ofPoint(-40, -30));
       square1.addVertex(place + ofPoint(+40, -30));
       square1.addVertex(place + ofPoint(+40, +30));
       square1.addVertex(place + ofPoint(-40, +30));
       square1.close();
}

mountSquere2

void ofApp::mountSquare2(ofPoint place) {
       square2.clear();
       square2.addVertex(place + ofPoint(-40, -30));
       square2.addVertex(place + ofPoint(+40, -30));
       square2.addVertex(place + ofPoint(+40, +30));
       square2.addVertex(place + ofPoint(-40, +30));
       square2.close();
}

mountLine

void ofApp::mountLine() {
       line.clear();
       //find closestTo1 and closestTo2
       // first look source1 to source2
       closestTo1 = square1.getCentroid2D();
       closestTo2 = square2.getCentroid2D();

       ofPolyline helperLink;
       helperLink.clear();
       helperLink.addVertex(closestTo1);
       helperLink.addVertex(closestTo2);

       int index = 0;

       ofRectangle r = square1.getBoundingBox();
       float w = r.getWidth();
       float h = r.getHeight();
       float max;
       w > h ? max = w : max = h;

       while (true) {
             closestTo1 = helperLink.getPointAtLength(index);
             if (!square1.inside(closestTo1)) break;
             index += 1;
             if (index > max) break;
       }

       // second look source2 to source1
       helperLink.clear();
       helperLink.addVertex(closestTo2);
       helperLink.addVertex(closestTo1);
       index = 0;
       //     ofLogVerbose() << "process link point 2"; r = square2.getBoundingBox(); w = r.getWidth(); h = r.getHeight(); w > h ? max = w : max = h;

       while (true) {
             closestTo2 = helperLink.getPointAtLength(index);
             //     ofLogVerbose() << "closestTo2: " + ofToString(index) + " - " + ofToString(closestTo2); if (!square2.inside(closestTo2)) break; index += 1; if (index > max) break;
       }
       line.addVertex(closestTo1);
       line.addVertex(closestTo2);
}

draw

void ofApp::draw() {
       ofEnableAntiAliasing();
       ofEnableSmoothing();

       ofSetColor(ofColor::blue);
       ofSetLineWidth(1);
       square1.draw();
       square2.draw();
       line.draw();

       ofSetColor(ofColor::red);
       ofCircle(closestTo1, 5);
       ofCircle(closestTo2, 5);

}

mouseEvents

void ofApp::mouseDragged(int x, int y, int button) {

       if (moving1 == true) {
             mountSquare1(ofPoint(x, y));
             mountLine();
             return;
       }

       if (moving2 == true) {
             mountSquare2(ofPoint(x, y));
             mountLine();
             return;
       }
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button) {

       if (square1.inside(x, y)) {
             moving1 = true;
             moving2 = false;
             return;
       }
       if (square2.inside(x, y)) {
             moving1 = false;
             moving2 = true;
             return;
       }
       moving1 = moving2 = false;
}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button) {
       moving1 = moving2 = false;
}