Пример 1.
Генерация типовых предметов
Предмет (файлы object.h, object.cpp)
object.h
///////////////////////////////////////////////////////////////////////////////////////////////////
// object.h
// Предмет - двумерная комплексная выборка в реальных координатах. Размер выборки по x и y одинаковый.
// Генерация нескольких типовых объектов с соблюдением симметрии относительно центра выборки.
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// Университет ИТМО
///////////////////////////////////////////////////////////////////////////////////////////////////
#if !defined OBJECT_H
#define OBJECT_H
#include "sample_complex.h"
//-------------------------------------------------------------------------------------------------
class Object: public SampleComplex
{
private:
// шаг по предмету (к.е.)
double m_dx;
public:
// конструктор
// size - количество элементов, одинаковое по x и y (size*size)
// dx - шаг по предмету (к.е.)
Object(int size, double dx);
~Object();
// создание предмета в виде бинарной периодической решетки
// period - период решетки (к.е.)
// width - ширина линии (к.е.)
void CreateLineAndSpace(double period, double width);
// создание предмета в виде полутоновой периодической решетки
// period - период решетки (к.е.)
// width - ширина линии (к.е.)
void CreateLineAndSpaceAttenuaten(double period, double width);
// создание предмета в виде чередующейся полутоновой периодической решетки
// period - период решетки (к.е.)
// width - ширина линии (к.е.)
void CreateLineAndSpaceAlternating(double period, double width);
// создание предмета в виде полуплоскости
void CreateHalfPlane();
// создание предмета в виде радиальной миры
// count - количество секторов (линий)
void CreateTargetStar(int count);
private:
// универсальная функция создания предмета в виде чередующейся периодической решетки
// period - период решетки (к.е.)
// width - ширина линии (к.е.)
// ob_module_line, ob_phase_line - модуль и фаза "линии", т.е. непрозрачной части решетки
// ob_module_space, ob_phase_space - модуль и фаза "промежутка", т.е. прозрачной части решетки
// ob_phase_space2 - фаза второго "промежука", для чередующейся решетки
void CreateLineAndSpaceCommon(double period, double width,
double ob_module_line=1., double ob_phase_line=0,
double ob_module_space=0., double ob_phase_space=0,
double ob_phase_space2=0);
};
//-------------------------------------------------------------------------------------------------
#endif // OBJECT_H
object.cpp
///////////////////////////////////////////////////////////////////////////////////////////////////
// object.cpp
// Предмет - двумерная комплексная выборка в реальных координатах. Размер выборки по x и y одинаковый.
// Генерация нескольких типовых объектов с соблюдением симметрии относительно центра выборки.
//
// Кафедра Прикладной и компьютерной оптики, http://aco.ifmo.ru
// Университет ИТМО
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "Object.h"
//-------------------------------------------------------------------------------------------------
Object::Object(int size, double dx)
: SampleComplex(size)
, m_dx(dx)
{
}
//-------------------------------------------------------------------------------------------------
Object::~Object()
{
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде полуплоскости
void Object::CreateHalfPlane()
{
for(int j=0;j<m_size;j++)
{
for(int i=0;i<m_size;i++)
{
if(i<m_size/2)
operator()(i,j)=complex<double>(0., 0.);
else
operator()(i,j)=complex<double>(1., 0.);
}
}
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде радиальной миры
void Object::CreateTargetStar(int count)
{
double dStep=180/count;
for(int j=0; j<m_size; j++)
{
double y=CalcCoord(j, m_dx);
for(int i=0; i<m_size; i++)
{
double x=CalcCoord(i, m_dx);
double dAngle=atan2(y,x)*180/PI + 180;// вычисление угла в диапазоне 0 - 360 град.
if(int(dAngle/dStep)%2!=0)
operator()(i,j)=complex<double>(0., 0.);
else
operator()(i,j)=complex<double>(1., 0.);
}
}
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде бинарной периодической решетки
void Object::CreateLineAndSpace(double period, double width)
{
CreateLineAndSpaceCommon(period, width, 0., 0., 1., 0., 0.);
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде полутоновой периодической решетки
void Object::CreateLineAndSpaceAttenuaten(double period, double width)
{
CreateLineAndSpaceCommon(period, width, 0.06, PI, 1., 0., 0);
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде чередующейся полутоновой периодической решетки
void Object::CreateLineAndSpaceAlternating(double period, double width)
{
CreateLineAndSpaceCommon(period, width, 0., 0., 1., 0., PI);
}
//-------------------------------------------------------------------------------------------------
// создание предмета в виде периодической решетки
// period - период решетки (к.е.)
// width - ширина линии (к.е.)
void Object::CreateLineAndSpaceCommon(double period, double width,
double ob_module_line, double ob_phase_line,
double ob_module_space, double ob_phase_space, double ob_phase_space2)
{
// период и ширина решетки в кол-ве элементов
int i_period=period/m_dx;
int i_width=width/m_dx;
// значения для соs и sin части комплексного числа (представление по формуле Эйлера)
// для линии и промежутков
double ob_c_line=cos(ob_phase_line);
double ob_s_line=sin(ob_phase_line);
double ob_c_space=cos(ob_phase_space);
double ob_s_space=sin(ob_phase_space);
double ob_c_space2=cos(ob_phase_space2);
double ob_s_space2=sin(ob_phase_space2);
// для четного кол-ва элементов в выборке ширина линии должна быть четной, для нечетного - четной
if((m_size%2==0 && i_width%2!=0) || (m_size%2!=0 && i_width%2==0))
i_width++;
// ширина промежутка в кол-ве элементов
int i_space=i_period-i_width;
// определение, что должно быть на краю выборки - линия или промежуток
bool bFirstline=false;
int i_first=(m_size/2-i_width/2)/i_period;
i_first=m_size/2-i_width/2-i_first*i_period;
if(i_first-i_space > 0)
{
i_first-=i_space;
bFirstline=true;
}
// признаки, что будет следующее - линия или промежуток, и будет ли меняться фаза
bool bPhase=true, bLine=false;
for(int j=0; j<m_size; j++)
{
// промежуток
if(( bFirstline && (j>=(i_first+i_space) && j<(i_first+i_period) || j<i_first)) ||
(!bFirstline && (j>=(i_first) && j<(i_first+i_width )) ) )
{
if(bLine)
bPhase=!bPhase;
for(int i=0; i<m_size; i++)
{
if(bPhase)
operator()(i,j)=ob_module_space*complex<double>(ob_c_space,ob_s_space);
else
operator()(i,j)=ob_module_space*complex<double>(ob_c_space2,ob_s_space2);
}
bLine=false;
}
// линия
else
{
for(int i=0; i<m_size; i++)
{
operator()(i,j)=ob_module_line*complex<double>(ob_c_line,ob_s_line);
}
bLine=true;
}
if((j+1)>=i_first+i_period)
i_first+=i_period;
}
}
//-------------------------------------------------------------------------------------------------
|