Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: hackoff от Декабрь 26, 2009, 08:01



Название: Определить цвет точки
Отправлено: 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);
}
//


Название: Re: Определить цвет точки
Отправлено: Rcus от Декабрь 26, 2009, 10:35
Визуализация это конечно хорошо, но метод Монте-Карло обычно входит в программу курса моделирования случайных величин (где-то в начале), а не компьютерной графики. Соответственно решение задается предметной областью - вывести аналитический критерий принадлежности из функции описания контура.


Название: Re: Определить цвет точки
Отправлено: hackoff от Декабрь 26, 2009, 12:02
аналитически не очень хочется выводить, тем более функция параметрически заданная, да и к тому же это задача по "ППРНЗ" (практикум по решению не стандартных задач).
Да и к моделированию можно отнести, так как я строю когнитивную модель :)

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



Название: Re: Определить цвет точки
Отправлено: hackoff от Декабрь 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));
}



Название: Re: Определить цвет точки
Отправлено: Dendy от Декабрь 26, 2009, 15:25
Работать в координатах QGraphicsScene, а не QGraphicsView. Определять с помощью if( scene->itemAt( x, y, QTransform() ) ).


Название: Re: Определить цвет точки
Отправлено: hackoff от Декабрь 27, 2009, 06:04
про QGraphicsView  я и в правду глупость сморозил.. А вот твой способ пока что еще не понял... Пойду assistant читать :)


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

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

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

Примечание (для любознательных): выброс точки с помощью 2-х rand (чистый Монте-Карло) не лучший, Quasi Monte Carlo заметно сильнее.


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