Уроки, алгоритмы, программы, примеры

Вход на сайт

Материалы по разделам

Построения
на плоскости (2D)
Графика
в пространстве (3D)
Вычислительная
геометрия
Физическое
моделирование
Фрактальная
графика

Новые комментарии

Я код на C++ набрал сам. Строил кривую Безье, но "прилипал" к нулю. То есть я задаю точки далеко от нуля, а он строил из нуля, а потом только обходил предложенные точки. Потом я нашёл Ваш сайт и эту статью. Оказалось, что я забыл возвести t в...
просто я не так понял, здесь мы вращаем точки куба что вращает сам куб. Мне нужно вращать просто 3д объект , данный способ не подходит
Задавайте объект в мировых координатах. Вращайте его относительно мировой системы координат. А при отрисовке преобразуйте в экранные координаты. Посмотрите пример преобразования в экранные координаты.
Это вращение по мировым осям ? Если да то как сделать по осям объекта ?
Добрый вечер! Область прорисовки остается пустой. Чего-то не хватает. Объясните плз, чего? Рамиль.

Счетчики и рейтинг

Рейтинг@Mail.ru
чтобы купить лайки в инстаграме за 24 руб. (100 шт), переходите на сайт
Скриншот к примеру
Среда программирования: 
Qt
Статья по теме: 

Детали фрактала

Изначально есть лишь буква Н, затем к каждому из концов этой буквы пририсовывается точно такая же буква Н, но в два раза меньше, и так далее.
Известно, что Н-фрактал заполняет свой квадрат и его фрактальная размерность равна двум.

Принцип построения данного фрактала используется в проектировании микросхем.
Если рисовать толстые буквы Н, то получается дерево Мандельброта.
Принцип построения Н-фрактала очень похож на пострение Т-фрактала.

Детали реализации

Чтобы запоминать точки в которых надо рисовать буквы H будем использовать очередь, так как данная структура данных лучше всего подходит для наших целей. На каждой итерации построения букв H мы будем использовать рандомные цвета.
Все остальные детали будут описаны в комментариях в коде.

Конкретно данный пример кода был написан на Qt/C++, из-за удобств работы с ui интерфейсом.

Код программы: 

// widget.h
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QPair>
#include <QPainter>
#include <queue>
#include <time.h>
#include <stdlib.h>
using namespace std;
 
namespace Ui {
class Widget;
}
 
class Widget : public QWidget
{
    Q_OBJECT
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void drawH(int size, QPair<int,int> coord, QPainter *paint); // функция для отрисовки Н в какой-то точке coord с длиной линий size
    int getSize(int depth); // в зависимости от глубины узнаем длину линии, она равна начальной длине, деленной на два в степени глубина минус один (в 1-индексации)
    void drawHDepth(int depth); // отрисовка всех Н до глубины depth
    QColor getRandColor(); // функция, возвращающая рандомный цвет
 
private slots:
    void on_drawButton_clicked(); // метод клика по кнопке
 
private:
    Ui::Widget *ui; // форма
    int oX,oY; // начальные координаты центра
    int sizeMin; // начальная длина
    queue<QPair<int,int> > coords; // очередь, используемая для запоминания точек в которых надо рисовать Н
};
 
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"
 
// в конструкторе проинициализируем начальные значения координат и длины
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    oX = 290;
    oY = 255;
    sizeMin = 200;
}
 
Widget::~Widget()
{
    delete ui;
}
 
void Widget::drawH(int size, QPair<int,int> coord, QPainter *paint)
{
    // в данном методы мы просто рисуем три линии, которые и являются буквой Н
    // *paint нужен для отрисовки
    paint->drawLine(coord.first-(size/2),coord.second,coord.first+(size/2),coord.second);
    paint->drawLine(coord.first-(size/2),coord.second-(size/2),coord.first-(size/2),coord.second+(size/2));
    paint->drawLine(coord.first+(size/2),coord.second-(size/2),coord.first+(size/2),coord.second+(size/2));
 
    return;
}
 
int Widget::getSize(int depth)
{
    // функция, возвращающая длину линий на каждом шаге
    return sizeMin/(1<<(depth-1));
}
 
// так как на i-том шаге у нас будет ровно четыре в степени i-1 точек из которых надо рисовать Н, напишем рекурсивную функцию бинарного возведения в степень, которая за логарифмическую асимптотику позволяет вычислять степень числа
int binPow(int a, int b) {
    if(!b)
        return 1;
    if(b%2)
        return binPow(a,b-1)*a;
    int tmp = binPow(a,b/2);
    return tmp*tmp;
}
 
// в данном методе мы лишь задаем рандомные значения RGB для класса QColor
QColor Widget::getRandColor()
{
    int r = rand()%255;
    int g = rand()%255;
    int b = rand()%255;
    return QColor(r,g,b);
}
 
void Widget::drawHDepth(int depth)
{
    srand(time(NULL)); // для начала инициализируем рандомные значения
 
    QPixmap H(580,510); // далее создадим область рисования
    QPainter paint;
    paint.begin(&H);
    paint.eraseRect(0,0,580,510); // и закрасим её белым цветом
 
    while(!coords.empty()) // чтобы при каждой новой отрисовке не было конфузов, очистим очередь вершин
        coords.pop();
 
    QPair<int,int> a(oX,oY),tmp;
    int size;
    coords.push(a); // изначально в очередь поместим только центральную точку
    for(int i=1;i<=depth;++i) { // и последовательно пройдемся по всем глубинам
 
        size = getSize(i); // узнаем размер линии на каждом шаге глубины
 
        paint.setPen(QPen(getRandColor(),1)); // задаем кисть рандомного цвета толщиной 1
 
        for(int j=1;j<=binPow(4,i-1);j++) { // т.к. вершин на данном шаге будет 4 в степени i-1, проходимся только по 4 в степени i-1 первым значениям в очереди
 
            a = coords.front(); // узнаем координату очередной вершины
            coords.pop(); // удаляем её из очереди
            drawH(size,a,&paint); // и рисуем
 
            // далее просто добавляем 4 новые вершины в стек
            tmp.first = a.first-(size/2);
            tmp.second = a.second-(size/2);
            coords.push(tmp);
 
            tmp.first = a.first-(size/2);
            tmp.second = a.second+(size/2);
            coords.push(tmp);
 
            tmp.first = a.first+(size/2);
            tmp.second = a.second-(size/2);
            coords.push(tmp);
 
            tmp.first = a.first+(size/2);
            tmp.second = a.second+(size/2);
            coords.push(tmp);
        }
    }
 
    paint.end(); // заканчиваем рисование
    ui->output->setPixmap(H); // и выводим картинку на экран
}
 
void Widget::on_drawButton_clicked()
{
    QString tmp = ui->depthEdit->text(); // получаем глубину, которую пользователь вводит в форме
    int depth;
    if(tmp=="") // если строка пуста
        depth = 1; // то считаем, что глубина равна 1
    else // иначе
        depth = tmp.toInt(); // преобразовываем строку в число
    drawHDepth(depth); // и запускаем отрисовку фрактала до глубины depth
}

Прикрепленный файлРазмер
Kish_Hfrac.zip2.47 кб