Pular para o conteúdo

Criando linhas usando ofPolyline no openFrameworks

1.Criar as linhas:

Para criar as linhas pode-se usar duas estruturas básicas, uma para desenhar e a outra para conter a lista de vértices
class ofApp : public ofBaseApp{
        public:
                //----- . . .
                ofPolyline shape;
                vector vertexList;
                //----- . . .
}
Basicamente é só adicionar novos pontos da fila
if (mode == shapeMode::creating) {
        vertexList.push_back(ofPoint(x, y));
        this->createShape();
        return;
}
A rotina de criar o shape, é noobescamente essa:
void ofApp::createShape() {
        shape.clear();
        vector::iterator itV;
        for (itV = vertexList.begin(); itV != vertexList.end(); itV++)
                shape.addVertex((*itV));
}
E o draw:
void ofApp::drawShape() {
        shape.draw();
}

2. Adicionar pontos no meio do campo

Aqui é um pouco mais tricky, deve-se observar algumas coisas
  1. Testar se existe alguma linha
  2. Se perto do ponto zero, ctza que está entre 0 e o 1. (Primeiro trecho)
  3. Se não é perto do primeiro ponto, verificar se está no ponto (local -1) e ponto (local)
  4. Se perto do ponto size( ) -1, ctza que está entre o size( ) - 2 e o size( ) - 1.  (Último trecho)
  5. Se não é perto do último ponto, verificar se está no ponto (local) e ponto (local + 1)
if (mode == shapeMode::editing) {
        unsigned int perto;
        ofPoint c = shape.getClosestPoint(ofPoint(x, y), &perto);

        if (vertexList.empty()) return;

        if (perto == 0) {
                vertexList.insert(vertexList.begin() + perto + 1,c);
                this->createShape();
                return;
        }
        else {
                ofPoint a = vertexList[perto];
                ofPoint b = vertexList[perto - 1];

                if (abs((a.y - c.y) - ((a.y - b.y) / (a.x - b.x))*(a.x - c.x)) < 5) { vertexList.insert(vertexList.begin() + perto, c); this->createShape();
                        return;
                        }
        }

        if (perto == shape.size() - 1) {      
                vertexList.insert(vertexList.begin() + perto, c);
                this->createShape();
                return;
        }
        else {
                ofPoint a = vertexList[perto];
                ofPoint b = vertexList[perto + 1];

                if (abs((a.y - c.y) - ((a.y - b.y) / (a.x - b.x))*(a.x - c.x)) < 5) { vertexList.insert(vertexList.begin() + perto + 1, c); this->createShape();
                        return;
                        }
        }
}

3. Movimentar os pontos

Primeiro tem que ser feita uma mini função ninja para encontrar o ponto mais próximo:
ofPoint * ofApp::closeToVertex(ofPoint p) {
        vector::iterator itV;
        for (itV = vertexList.begin(); itV != vertexList.end(); itV++)
                if (p.squareDistance((*itV)) < 100) return &(*itV);
        return NULL;
}
Para mudar os pontos deve-se fazer duas coisas, na verdade três, mas enfim: selecionar, mover, e liberar. Não considerei a segunda, só ignorei o liberar como parar de fazer qq função.
Selecionar:
void ofApp::mousePressed(int x, int y, int button){
        if (mode == shapeMode::pointSelected) {
                closest = this->closeToVertex(ofPoint(x, y));
                return;
        }
}
Mover:
void ofApp::mouseDragged(int x, int y, int button){
        if (mode == shapeMode::pointSelected){
                if (closest != NULL) {
                        closest->x = x;
                        closest->y = y;
                        this->createShape();
                }
        return;
        }
}

4. Apagar os pontos

Apagar um ponto basta encontrar novamente o ponto, e dar um delete ninja no vetor.
if (mode == shapeMode::removingPoint) {
        ofLogVerbose() << "testing point"; closest = this->closeToVertex(ofPoint(x, y));
        if (closest != NULL) {
                vector::iterator itV;
                for (itV = vertexList.begin(); itV != vertexList.end(); itV++) {
                        if (itV->x == closest->x && itV->y == closest->y) {
                               vertexList.erase(itV);
                               this->createShape();
                               return;
                        }
                }
                }
        return;
}
Marcações:

Deixe um comentário