Example #1
0
void Triangle::changePoints(const TexturedPoint& a, const TexturedPoint& b, const TexturedPoint& c){
    points.clear();
    points.push_back(a);
    points.push_back(b);
    points.push_back(c);
    currAngle = 0;
    currScaleX = DEFAULT_SCALE_X;
    currScaleY = DEFAULT_SCALE_Y;
    rotCenterX = (a.x() + b.x() + c.x())/3.;
    rotCenterY = (a.y() + b.y() + c.y())/3.;
}
void Triangle::changePoints(const TexturedPoint& a, const TexturedPoint& b, const TexturedPoint& c){
    // заполняем вектор вершин
    points.clear();
    points.push_back(a);
    points.push_back(b);
    points.push_back(c);

    // установка параметоров начальных
    currAngle = 0;
    currScaleX = DEFAULT_SCALE_X;
    currScaleY = DEFAULT_SCALE_Y;

    //?
    // вычисление центра вращения
    rotCenterX = (a.x() + b.x() + c.x())/3.;
    rotCenterY = (a.y() + b.y() + c.y())/3.;
}
// отрисовка из прошлой лабы, только берём цвета из текстуры
void Triangle::draw(Canvas& canvas, Texture* texture = 0) {
    std::vector<TexturedPoint> points;

    // преобразование и упорядочивание по x
    transform(points);
    std::sort(points.begin(), points.end());

    std::vector<Edge> edges;

    // установка границ
    int minY = (points.front().y() < 0) ? 0: points.front().y();
    int maxY = (points.back().y() < this->maxY) ? points.back().y() : this->maxY - 1;

    int curY = minY;
    int i = 0;

    while (curY < maxY) {
        int nextY = maxY;

        while ( i != (int)points.size() && trunc( points[i].y()) <= curY ){
            TexturedPoint a = points[i];
            TexturedPoint b = points[(points.size() - i - 1 ) % points.size()];
            TexturedPoint c = points[(i + 1) % points.size()];

            if (b.y() > curY ) {
                edges.push_back(Edge(a,b));
                if ( b.y() < nextY ) {
                    nextY = b.y() ;
                }
            }
            if (c.y() > curY) {
                edges.push_back(Edge(a,c));
                if ( c.y() < nextY) {
                    nextY = c.y();
                }
            }
            ++i;
        }

        while(curY <= nextY && curY <= maxY) {

            std::vector<TexturedPoint> borderX;
            for (int i = 0; i < (int)edges.size(); ++i) {
                int n = curY - edges[i].getA().y();
                double curX = (edges[i].getA().x()) + n * edges[i].getK();
                TexturedPoint texCoord(curX, curY);
                texCoord.calcTextureCoordinates(edges[i].getA(), edges[i].getB());
                borderX.push_back(texCoord);
            }

            std::sort(borderX.begin(), borderX.end(), TexturedPoint::compX);
            int begin = borderX.front().x() > 0 ? borderX.front().x() : 0;

            for (int x = begin; x < borderX.back().x() && x < maxX; ++x) {
                TexturedPoint curPoint(x, curY);

                curPoint.calcTextureCoordinates(borderX.front(),borderX.back());

                if (0 == texture) {
                    // если текстуры нет( то как градиент )
                    canvas.drawPixel(x, curY, TexturedPoint::transformToColor(curPoint.getTexX(), curPoint.getTexY()));
                } else {
                    canvas.drawPixel(x, curY, texture->get_color(curPoint));
                }
            }

            ++curY;
        }

        std::vector<Edge>::iterator iter = edges.begin();
        while (iter != edges.end()) {
           if ( (*iter).getB().y() < curY) {
               edges.erase(iter);
           }
           else {
               ++iter;
           }
        }

   }
}