void Clipping::clipBottom(Coordinates& input, Coordinates& output){
    if(output.size() > 0)
        output.clear();
    if(input.size() == 0)
        return;

    double clipY = m_w->minY;
    input.push_back(input[0]);
    for(unsigned int i = 0; i < input.size()-1; i++){
        Coordinate c0 = input[i];
        Coordinate c1 = input[i+1];

        //Caso 1: out -> out
        if(c0.y < clipY && c1.y < clipY){}

        //Caso 2: in -> in
        if(c0.y >= clipY && c1.y >= clipY)
            output.push_back(c1);

        double y = clipY;
        double m = (c1.x-c0.x)/(c1.y-c0.y);
        double x = m * (y-c0.y) + c0.x;

        //Caso 3: in -> out
        if(c0.y >= clipY && c1.y < clipY)
            output.emplace_back(x,y);

        //Caso 4: out -> in
        if(c0.y < clipY && c1.y >= clipY){
            output.emplace_back(x,y);
            output.push_back(c1);
        }
    }
}
void Clipping::clipRight(Coordinates& input, Coordinates& output){
    if(output.size() > 0)
        output.clear();
    if(input.size() == 0)
        return;

    double clipX = m_w->maxX;
    input.push_back(input[0]);
    for(unsigned int i = 0; i < input.size()-1; i++){
        Coordinate c0 = input[i];
        Coordinate c1 = input[i+1];

        //Caso 1: out -> out
        if(c0.x >= clipX && c1.x >= clipX){}

        //Caso 2: in -> in
        if(c0.x < clipX && c1.x < clipX)
            output.push_back(c1);

        double x = clipX;
        double m = (c1.y-c0.y)/(c1.x-c0.x);
        double y = m * (x-c0.x) + c0.y;

        //Caso 3: in -> out
        if(c0.x < clipX && c1.x >= clipX)
            output.emplace_back(x,y);

        //Caso 4: out -> in
        if(c0.x >= clipX && c1.x < clipX){
            output.emplace_back(x,y);
            output.push_back(c1);
        }
    }
}
void MainWindow::addLine(GtkBuilder* builder){
    LineDialog dialog(GTK_BUILDER(builder));
    bool finish = false;

    while(!finish){
        if(dialog.run() == 1){
            try{
                Coordinates c;
                c.emplace_back(dialog.getX1(), dialog.getY1());
                c.emplace_back(dialog.getX2(), dialog.getY2());

                Object* obj = _world->addLine(
                                    dialog.getName(), dialog.getColor(), c);
                _viewport->transformObj(obj);
                addObjOnListStore(dialog.getName(), "Line");

                gtk_widget_queue_draw(_mainWindow);
                log("Nova reta adicionada.\n");
                finish = true;
            }catch(MyException& e){
                log(e.what());
                showErrorDialog(e.what());
            }
        }else
            finish = true;
    }
}
void PolygonDialog::getCoords(Coordinates& coords) const {
    GtkTreeIter iter;
    gboolean valid;
    double x, y;

    valid = gtk_tree_model_get_iter_first (m_model,
                                            &iter);

    if(!valid)
        throw MyException("Adicione pelo menos uma coordenada.\n");

    while(valid){
        gtk_tree_model_get (m_model, &iter,
                       0, &x, 1, &y, -1);
        coords.emplace_back(x, y);

        valid = gtk_tree_model_iter_next (m_model,
                                     &iter);
    }
}