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; vectorvertexList; //----- . . . }
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
- Testar se existe alguma linha
- Se perto do ponto zero, ctza que está entre 0 e o 1. (Primeiro trecho)
- Se não é perto do primeiro ponto, verificar se está no ponto (local -1) e ponto (local)
- Se perto do ponto size( ) -1, ctza que está entre o size( ) - 2 e o size( ) - 1. (Último trecho)
- 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; }