Russian Qt Forum
Ноябрь 24, 2024, 22:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Определить цвет точки  (Прочитано 9203 раз)
hackoff
Гость
« : Декабрь 26, 2009, 08:01 »

Решаю задачу, в которой методом Монте-Карло нужно определить площадь фигуры.
Суть в том что фигуру помещаю в прямоугольник, площадь которого известна и начинаю рандомом в этот прямоугольник кидать точки. Площадь находится как произведение отношения точек попавших точек в фигуру ко всем точкам на площадь фигуры. S=(count_true/count)*Sкв
Почти все сделал, но вот не могу сделать кусочек, в котором надо определить попала точка на фигуру или нет, а проблема в том что я не знаю как определить цвет в заданной точке.


В том месте где нужно определять стоит комментарий
Код:
#include "mainwindowimpl.h"
#include <QGraphicsScene>
#include <QPointF>
#include <QPainterPath>
#include <QPen>
//#include <QColor>
#include <QBrush>
#include <QTime>
#include <QDebug>
#include <math.h>
//
MainWindowImpl::MainWindowImpl( QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
setupUi(this);
connect (cmdGo, SIGNAL(clicked()), this, SLOT(Go()));
connect (cmdClear, SIGNAL(clicked()), this, SLOT(clear()));
QWidget * w = new QWidget;
w->setLayout(basic);
setCentralWidget(w);
GS = new QGraphicsScene;
GV->setScene(GS);
GV->scale(130,130);
konstr();
QTime timer;
timer.start();
qsrand(timer.second());

}
//--------------------------------
QPointF MainWindowImpl::func(double x){
QPointF point;
point.setX(pow(sin(x),2));
point.setY(sin(x-2));
return point;
//x(t)=sin^2(t), y(t)=sin(t-2)
}
//--------------------------------
void MainWindowImpl::Go(){
clear();
double x,y;
QGraphicsEllipseItem * item;
while (spinBox->value()){
spinBox->setValue(spinBox->value()-1);
x=rand()%100/100.0;
y=rand()%200/100.0-1;
                     /* В ТОЧКЕ Х и У НУЖНО ОПРЕДЕЛИТЬ ЦВЕТ*/
item=GS->addEllipse(x,-y, 0.01,0.01);

}
}
//-------------------------------
void MainWindowImpl::konstr(){
path = new QPainterPath;
path->moveTo(func(0));
for (double i=0; i<2*M_PI; i+=0.01){
path->lineTo(func(i));
}
//QGraphicsPathItem * addPath ( const QPainterPath & path, const QPen & pen = QPen(), const QBrush & brush = QBrush() )
QPen pen(Qt::darkCyan);
QBrush brush(Qt::darkCyan);
GS->addPath(*path, pen, brush);
GS->addRect(0,-1,1,2);
}
void MainWindowImpl::clear(){
GS->clear();
QPen pen(Qt::darkCyan);
QBrush brush(Qt::darkCyan);
GS->addPath(*path, pen, brush);
GS->addRect(0,-1,1,2);
}
//
Записан
Rcus
Гость
« Ответ #1 : Декабрь 26, 2009, 10:35 »

Визуализация это конечно хорошо, но метод Монте-Карло обычно входит в программу курса моделирования случайных величин (где-то в начале), а не компьютерной графики. Соответственно решение задается предметной областью - вывести аналитический критерий принадлежности из функции описания контура.
Записан
hackoff
Гость
« Ответ #2 : Декабрь 26, 2009, 12:02 »

аналитически не очень хочется выводить, тем более функция параметрически заданная, да и к тому же это задача по "ППРНЗ" (практикум по решению не стандартных задач).
Да и к моделированию можно отнести, так как я строю когнитивную модель Улыбающийся

Задачу в принципе могу на VB решить за 15 минут, но принципиально ее хочу сделать на Qt.

Записан
hackoff
Гость
« Ответ #3 : Декабрь 26, 2009, 12:46 »

Сделал с помощью коллизии. Переписал функцию. Но до сих пор интересно, как можно получить цвет точки QGraphicsView, не переходя к координатам виджета. 

Код:
void MainWindowImpl::Go(){
clear();
double x,y;
QGraphicsItem * item;
int count=spinBox->value(), countTrue=0;
while (spinBox->value()){
spinBox->setValue(spinBox->value()-1);
x=rand()%100/100.0;
y=rand()%200/100.0-1;
item=GS->addEllipse(x,-y, 0.01,0.01);
if (item->collidesWithPath(*path)) countTrue++;
}
txtOut->setText(QString::number((countTrue/(double)count)*2));
}

Записан
Dendy
Гость
« Ответ #4 : Декабрь 26, 2009, 15:25 »

Работать в координатах QGraphicsScene, а не QGraphicsView. Определять с помощью if( scene->itemAt( x, y, QTransform() ) ).
Записан
hackoff
Гость
« Ответ #5 : Декабрь 27, 2009, 06:04 »

про QGraphicsView  я и в правду глупость сморозил.. А вот твой способ пока что еще не понял... Пойду assistant читать Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Декабрь 27, 2009, 13:17 »

Визуализация это конечно хорошо, но метод Монте-Карло обычно входит в программу курса моделирования случайных величин (где-то в начале), а не компьютерной графики.
Не знаю как в теории преподавания но на практике в 3D графике Монте-Карло применяется очень интенсивно, можно сказать - доминирует в некоторых областях. Многочисленные попытки заменить его чем-то пока большого успеха не имеют.

Насчет решения - задача сводится к определению находится ли точка P1 внутри полигона. Алгоритм простой: берем любую точку P0 которая гарантированно лежит вне полигона. Подсчитываем число пересечений отрезка (P0, P1) со всеми отрезками контура. Если это число четное -  точка снаружи фигуры, иначе внутри.

Если же надо (или есть желание) "решить задачу средствами Qt" - то совершенно незачем привлекать path, ellipse и.т.п - можно просто залить фигуру, пройтись по вмещающему прямоугольнику и подсчитать число точек цвета заливки. Правда к Монте-Карло это никакого отношения не имеет.

Примечание (для любознательных): выброс точки с помощью 2-х rand (чистый Монте-Карло) не лучший, Quasi Monte Carlo заметно сильнее.
Записан
hackoff
Гость
« Ответ #7 : Январь 04, 2010, 14:43 »

Способ хороший. Буду иметь его ввиду.  Спасибо за подробный ответ.
Кстати, небольшой парадокс... В VB я не знаю как определить пересечения фигур, но знаю как определить цвет точки по координатам. А в Qt наоборот: знаю как определить пересечение фигур, но не знаю как определить цвет точки по координатам.(Имеются в виду, что определять буду средствами языка).

Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 23.