RayTracing
mainwindow.cpp
См. документацию.
00001 /* NAME: Kirill Vasil'evich Timofeev, 322
00002  * ASGN: N1
00003  */
00004 
00005 #include <QtGui>
00006 
00007  #include "mainwindow.h"
00008 
00009  MainWindow::MainWindow()
00010  {
00011      window = new QWidget;
00012      Hey = 192;
00013      Wid = 256;
00014      AntiAl = false;
00015      labelIm = new QLabel;
00016      image = new QPixmap(Wid, Hey);
00017      curImage = new QImage(Wid, Hey, QImage::Format_ARGB32);
00018      CamPos = Vector3D((float)0, (float)0, (float)-1.5);
00019 
00020 
00021      makeFigures();
00022      makeLights();
00023 
00024      Paint();
00025 
00026      statusBar()->showMessage(tr("Rayed"), 2000);
00027      mainLayout = new QVBoxLayout;
00028      mainLayout->setSizeConstraint(QLayout::SetMinimumSize);
00029      labelIm->setPixmap(*image);
00030      mainLayout->addWidget(labelIm);
00031      window->setLayout(mainLayout);
00032      setCentralWidget(window);
00033 
00034      createActions();
00035      createMenus();
00036      createStatusBar();
00037 
00038      setUnifiedTitleAndToolBarOnMac(true);
00039  }
00040 
00041  MainWindow::~MainWindow()
00042  {
00043 
00044      delete image;
00045      delete curImage;
00046      delete labelIm;
00047      delete mainLayout;
00048      delete window;
00049 
00050 
00051  }
00052 
00053 
00054 void MainWindow::SerializeInXml()
00055 {
00056     XMLS Serial;
00057 
00058     QMessageBox msgBox;
00059     msgBox.setWindowTitle("Message");
00060     msgBox.setText("Input file name for writing in XML format in");
00061     msgBox.exec();
00062 
00063     if (Serializing(&Serial))
00064         statusBar()->showMessage(tr("Serialized in XML"));
00065     else
00066         statusBar()->showMessage(tr("Error"));
00067 
00068 }
00069 
00070 void MainWindow::SerializeInBin()
00071 {
00072     BinS Serial;
00073 
00074     QMessageBox msgBox;
00075     msgBox.setWindowTitle("Message");
00076     msgBox.setText("Input file name for writing in Binary format in");
00077     msgBox.exec();
00078 
00079     if (Serializing(&Serial))
00080         statusBar()->showMessage(tr("Serialized in Bin"));
00081     else
00082         statusBar()->showMessage(tr("Error"));
00083 
00084 }
00085 
00086 void MainWindow::LoadFromXml()
00087 {
00088     XMLL Serial;
00089 
00090     QMessageBox msgBox;
00091     msgBox.setWindowTitle("Message");
00092     msgBox.setText("Input file name for reading in XML format from");
00093     msgBox.exec();
00094 
00095     if (Serializing(&Serial))
00096     {
00097         statusBar()->showMessage(tr("Loaded from Xml"));
00098         delete image;
00099         delete curImage;
00100         image = new QPixmap(Wid, Hey);
00101         curImage = new QImage(Wid, Hey, QImage::Format_ARGB32);
00102         labelIm->setPixmap(*image);
00103         Paint();
00104         repaint();  // обновление изображения
00105         statusBar()->showMessage(tr("RayTraced"));
00106     }
00107     else
00108         statusBar()->showMessage(tr("Error"));
00109 
00110 }
00111 
00112 void MainWindow::LoadFromBin()
00113 {
00114     BinL Serial;
00115 
00116     QMessageBox msgBox;
00117     msgBox.setWindowTitle("Message");
00118     msgBox.setText("Input file name for reading in Binary format from");
00119     msgBox.exec();
00120     if (Serializing(&Serial))
00121     {
00122         statusBar()->showMessage(tr("Loaded from Bin"));
00123         delete image;
00124         delete curImage;
00125         image = new QPixmap(Wid, Hey);
00126         curImage = new QImage(Wid, Hey, QImage::Format_ARGB32);
00127         labelIm->setPixmap(*image);
00128         Paint();
00129         repaint();  // обновление изображения
00130         statusBar()->showMessage(tr("RayTraced"));
00131     }
00132     else
00133         statusBar()->showMessage(tr("Error"));
00134 
00135 }
00136 
00137 bool MainWindow::Serializing(Serializer *Serial)
00138 {
00139     AntiAl = false;
00140 
00141     QString newStr;
00142     do
00143     {
00144         newStr = QFileDialog::getOpenFileName(this);
00145     }
00146     while (newStr.isEmpty());
00147 
00148     bool b = Serial->Start(newStr);
00149     if (b)
00150     {
00151         Serial->SerPic(Wid, Hey);
00152         Serial->SerCam(CamPos);
00153         Serial->SerSph(Sphere1,"Sphere1");
00154         Serial->SerSph(Sphere2,"Sphere2");
00155         Serial->SerThor(Thor1,"Thor1");
00156         Serial->SerThor(Thor2,"Thor2");
00157         Serial->SerThor(Thor3,"Thor3");
00158         Serial->SerLight(Light1,"Light1");
00159         Serial->SerLight(Light2,"Light2");
00160 
00161         Serial->End();
00162     }
00163 
00164     return b;
00165 
00166 }
00167 
00168 void MainWindow::exit()
00169 {
00170     QMessageBox msgBox;
00171     msgBox.setWindowTitle("Exit");
00172     msgBox.setText("Thank you for using my Program)) Goodbye!!");
00173     msgBox.exec();
00174     close();
00175 }
00176 
00177 void MainWindow::createActions()
00178 {
00179 
00180     XMLLAct = new QAction(tr("&XML"), this);
00181     //XMLLAct->setShortcuts(Qt::CTRL + Qt::Key_L + Qt::Key_X);
00182     XMLLAct->setStatusTip(tr("Load attributes from XML format"));
00183     connect(XMLLAct, SIGNAL(triggered()), this, SLOT(LoadFromXml()));
00184 
00185     BinLAct = new QAction(tr("&Bin"), this);
00186     //BinLAct->setShortcuts(Qt::CTRL + Qt::Key_L + Qt::Key_B);
00187     BinLAct->setStatusTip(tr("Load attributes from Binary format"));
00188     connect(BinLAct, SIGNAL(triggered()), this, SLOT(LoadFromBin()));
00189 
00190     exitAct = new QAction(tr("E&xit"), this);
00191     exitAct->setShortcuts(QKeySequence::Quit);
00192     exitAct->setStatusTip(tr("Exit RayTracing"));
00193     connect(exitAct, SIGNAL(triggered()), this, SLOT(exit()));
00194 
00195     XMLSAct = new QAction(tr("&XML"), this);
00196     //XMLSAct->setShortcuts(Qt::CTRL + Qt::Key_S + Qt::Key_X);
00197     XMLSAct->setStatusTip(tr("Save attributes in XML format"));
00198     connect(XMLSAct, SIGNAL(triggered()), this, SLOT(SerializeInXml()));
00199 
00200     BinSAct = new QAction(tr("&Bin"), this);
00201     //BinSAct->setShortcuts(Qt::CTRL + Qt::Key_S + Qt::Key_B);
00202     BinSAct->setStatusTip(tr("Save attributes in Binary format"));
00203     connect(BinSAct, SIGNAL(triggered()), this, SLOT(SerializeInBin()));
00204 
00205 }
00206 
00207 
00208 void MainWindow::createMenus()
00209 {
00210 
00211     fileMenu = menuBar()->addMenu(tr("&File"));
00212     fileMenu->addAction(exitAct);
00213     menuBar()->addSeparator();
00214 
00215     fileMenu = menuBar()->addMenu(tr("&Load"));
00216     fileMenu->addAction(XMLLAct);
00217     fileMenu->addAction(BinLAct);
00218     menuBar()->addSeparator();
00219 
00220     fileMenu = menuBar()->addMenu(tr("&Save"));
00221     fileMenu->addAction(XMLSAct);
00222     fileMenu->addAction(BinSAct);
00223     menuBar()->addSeparator();
00224 
00225 }
00226 
00227 void MainWindow::createStatusBar()
00228 {
00229     statusBar()->showMessage(tr("Ready"));
00230 }
00231 
00232 void MainWindow::makeFigures()
00233 {
00234 
00235     Material1.SetRef(Vector3D(1.0f, 1.0f, 1.0f));
00236     Material1.SetCol(Vector3D(0.9f, 0.0f, 0.0f));
00237     Material2.SetSpe(Vector3D(0.0f, 0.0f, 0.0f));
00238 
00239     Material2.SetRef(Vector3D(0.3f, 0.3f, 0.3f));
00240     Material2.SetCol(Vector3D(0.0f, 0.2f, 0.7f));
00241     Material2.SetSpe(Vector3D(0.0f, 0.0f, 0.0f));
00242 
00243     Material3.SetRef(Vector3D(1.0f, 1.0f, 1.0f));
00244     Material3.SetCol(Vector3D(0.0f, 1.0f, 0.0f));
00245     Material3.SetSpe(Vector3D(0.0f, 0.9f, 0.0f));
00246 
00247 
00248 
00249     Sphere1.SetPos(Vector3D(3,0,3));
00250     Sphere1.SetRad(1.0f);
00251     Sphere1.SetMater(Material1);
00252 
00253     Sphere2.SetPos(Vector3D(0,0,3));
00254     Sphere2.SetRad(2.0f);
00255     Sphere2.SetMater(Material2);
00256 
00257 
00258     Thor1.SetPosCen(Vector3D(-2,1, 1));
00259     Thor1.SetRad(1.0f);
00260     Thor1.SetWid(0.4f);
00261     Thor1.SetMater(Material3);
00262 
00263     Thor2.SetPosCen(Vector3D(4,2, 3));
00264     Thor2.SetRad(0.8f);
00265     Thor2.SetWid(0.2f);
00266     Thor2.SetMater(Material2);
00267 
00268     Thor3.SetPosCen(Vector3D(4,-2, 3));
00269     Thor3.SetRad(0.4f);
00270     Thor3.SetWid(0.1f);
00271     Thor3.SetMater(Material1);
00272 
00273 
00274 }
00275 
00276 void MainWindow::makeLights()
00277 {
00278 
00279 
00280     Light1.SetPos(Vector3D(4,0,2));
00281     Light1.SetColor(Vector3D(0.1f, 0.4f, 0.9f));
00282     Light1.SetConst(0.0f);
00283     Light1.SetLinear(0.05f);
00284     Light1.SetQuadric(0.05f);
00285 
00286     Light2.SetPos(Vector3D(-4,0,2));
00287     Light2.SetColor(Vector3D(0.9f, 0.4f, 0.1f));
00288     Light2.SetConst(0.0f);
00289     Light2.SetLinear(0.1f);
00290     Light2.SetQuadric(0.05f);
00291 
00292 }
00293 
00294 
00295 void MainWindow::keyPressEvent(QKeyEvent* pe)
00296 {
00297    switch (pe->key())
00298    {
00299 
00300       case Qt::Key_Q:
00301           AntiAliasing();     // AA
00302           AntiAl = TRUE;
00303       return;
00304       case Qt::Key_Z:
00305          CamPos.Z -= 0.1;     // приблизить сцену
00306       break;
00307 
00308       case Qt::Key_X:
00309          CamPos.Z += 0.1;// удалиться от сцены
00310       break;
00311 
00312       case Qt::Key_S:
00313          CamPos.Y += 0.1; // транслировать сцену вниз
00314       break;
00315 
00316       case Qt::Key_W:
00317          CamPos.Y -= 0.1;   // транслировать сцену вверх
00318       break;
00319 
00320       case Qt::Key_A:
00321         CamPos.X -= 0.1;   // транслировать сцену влево
00322       break;
00323 
00324       case Qt::Key_D:
00325         CamPos.X += 0.1;   // транслировать сцену вправо
00326       break;
00327 
00328       case Qt::Key_Escape: // клавиша "эскейп"
00329          this->close();    // завершает приложение
00330       break;
00331     }
00332 
00333     Paint();
00334     AntiAl = false;
00335     repaint(); // обновление изображения
00336     statusBar()->showMessage(tr("Made"), 2000);
00337 
00338 }
00339 
00340 void MainWindow::wheelEvent(QWheelEvent* pe)
00341 {
00342    if ((pe->delta())>0) CamPos.Z -= 0.1; else if ((pe->delta())<0) CamPos.Z += 0.1;
00343 
00344    Paint();
00345    AntiAl = false;
00346    repaint();  // обновление изображения
00347    statusBar()->showMessage(tr("Zoomed"), 2000);
00348 }
00349 
00350 void MainWindow::mousePressEvent(QMouseEvent* pe) // нажатие клавиши мыши
00351 {
00352    ptrMousePosition = pe->pos();
00353 
00354 }
00355 
00356 // изменение положения стрелки мыши
00357 void MainWindow::mouseMoveEvent(QMouseEvent* pe)
00358 {
00359    // поворот
00360    CamPos.Y += (float)(pe->y()-ptrMousePosition.y())/3 /Hey;
00361    CamPos.X += (float)(pe->x()-ptrMousePosition.x())/3 /Wid;
00362 
00363 }
00364 
00365 void MainWindow::mouseReleaseEvent (QMouseEvent * pe)
00366 {
00367 
00368     if (ptrMousePosition != pe->pos())
00369     {
00370         Paint();
00371         AntiAl = false;
00372         repaint();  // обновление изображения
00373         statusBar()->showMessage(tr("Translated"), 2000);
00374     }
00375     ptrMousePosition = pe->pos();
00376 
00377 }
00378 
00379 float MainWindow::countMinDist(Vector3D temp, int *numObj, bool b1, bool b2, bool b3, bool b4, bool b5)
00380 {
00381     float len, t12 = 1000000, t22 = 1000000, t32 = 1000000, t42 = 1000000, t52 = 1000000;
00382 
00383     if (b1) t12 = (Sphere1.GetPos() - temp).Length() - Sphere1.GetRad();
00384 
00385     if (b2) t22 = (Sphere2.GetPos() - temp).Length() - Sphere2.GetRad();
00386 
00387     if (b3)
00388     {
00389         len = sqrt((temp.X - Thor1.GetPosCen().X) * (temp.X - Thor1.GetPosCen().X)
00390                     + (temp.Y - Thor1.GetPosCen().Y) * (temp.Y - Thor1.GetPosCen().Y));
00391         len -= Thor1.GetRad();
00392         t32 = sqrt(len * len + (temp.Z - Thor1.GetPosCen().Z) * (temp.Z - Thor1.GetPosCen().Z)) - Thor1.GetWid();
00393     }
00394 
00395     if (b4)
00396     {
00397         len = sqrt((temp.X - Thor2.GetPosCen().X) * (temp.X - Thor2.GetPosCen().X)
00398                     + (temp.Y - Thor2.GetPosCen().Y) * (temp.Y - Thor2.GetPosCen().Y));
00399         len -= Thor2.GetRad();
00400         t42 = sqrt(sqrt(sqrt(pow(len, 8) + pow(temp.Z - Thor2.GetPosCen().Z, 8)))) - Thor2.GetWid();
00401     }
00402 
00403     if (b5)
00404     {
00405         len = sqrt(sqrt(sqrt( pow((temp.X - Thor3.GetPosCen().X), 8)
00406                     + pow((temp.Y - Thor3.GetPosCen().Y) , 8))));
00407         len -= Thor3.GetRad();
00408         t52 = sqrt(sqrt(sqrt(pow(len, 8) + pow((temp.Z - Thor3.GetPosCen().Z), 8)))) - Thor3.GetWid();
00409     }
00410 
00411     len = t12;
00412     *numObj = 1;
00413     if (len > t22)
00414         {
00415         len = t22;
00416         *numObj = 2;
00417         }
00418     if (len > t32)
00419         {
00420         len = t32;
00421         *numObj = 3;
00422         }
00423     if (len > t42)
00424         {
00425         len = t42;
00426         *numObj = 4;
00427         }
00428     if (len > t52)
00429         {
00430         len = t52;
00431         *numObj = 5;
00432         }
00433 
00434     return len;
00435 }
00436 
00437 Vector3D MainWindow::countLites(Vector3D Dist, Vector3D Color, Vector3D SpeColor, Light Light0)
00438 {
00439     float t , p;
00440     Vector3D Col(Color);
00441     //do
00442     //{
00443         //minDist1 = countMinDist(temp1, &numObj, true, true, true, true, true);
00444         //temp1 += (- Light0.GetPos() + Dist).NormVect() * minDist1;
00445         //minDist2 = countMinDist(temp2, &numObj, true, true, true, true, true);
00446         //temp2 += (-Light0.GetPos() - Dist).NormVect() * minDist2;
00447     //}
00448     //while ((minDist1 >= ((float)1/ Wid)) || (minDist2 >= ((float)1/ Wid)));
00449     //if (minDist1 >= minDist2) temp = temp2;
00450     //else temp = temp1;
00451 
00452     t = ( Dist - Light0.GetPos()).Length();
00453     p = (float)1 / (Light0.GetConst() + t * Light0.GetLinear() + t * t * Light0.GetQuadric());
00454     Col.X *= p * Light0.GetColor().X * (1 + SpeColor.X);
00455     Col.Y *= p * Light0.GetColor().Y * (1 + SpeColor.Y);
00456     Col.Z *= p * Light0.GetColor().Z * (1 + SpeColor.Z);
00457     if (Col.X > 255)
00458     {
00459         Col.X = 255;
00460     }
00461     if (Col.Y > 255)
00462     {
00463         Col.Y = 255;
00464     }
00465     if (Col.Z > 255)
00466     {
00467         Col.Z = 255;
00468     }
00469 
00470    return Col;
00471 }
00472 
00473 void MainWindow::Paint()
00474 {
00475     RGBCol = new Vector3D*[Wid];
00476     for (int i = 0; i < Wid; i++)
00477             RGBCol[i] = new Vector3D[Hey];
00478 
00479     float W1 = (float)1 / Wid;
00480     for(int i = 0;i < Wid; i++)
00481         for(int j = 0;j < Hey; j++)
00482         {
00483             float len;
00484             Vector3D PixOnScreen((float)(i - Wid / 2) / Wid * 4,(float)(j - Hey / 2) / Hey * 3, 0);
00485             Vector3D RayCol(1.0f, 1.0f, 1.0f);
00486             Ray Rayij(PixOnScreen, CamPos);
00487             Vector3D temp0(Rayij.GetDir());
00488             temp0 = temp0 * ((float)W1 * 4);
00489             Vector3D temp(CamPos);
00490             bool b1 =true, b2=true, b3 =true, b4=true, b5 =true;
00491             int cola = 0;
00492             do
00493             {
00494                 int numObj;
00495 
00496                 len = countMinDist(temp, &numObj, b1, b2, b3, b4, b5);
00497                 temp += Rayij.GetDir() * len;
00498 
00499                 if (len <= W1)
00500                 {
00501                     cola++;
00502                     Vector3D Colour , Col, SpeCol, Dist;
00503                     Dist = temp - CamPos + PixOnScreen;
00504 
00505                     switch (numObj)
00506                     {
00507                        case 1:
00508                             {
00509                                 Col.X = Sphere1.GetMater().GetCol().X * RayCol.X * 255;
00510                                 Col.Y = Sphere1.GetMater().GetCol().Y * RayCol.Y * 255;
00511                                 Col.Z = Sphere1.GetMater().GetCol().Z * RayCol.Z * 255;
00512                                 SpeCol = Sphere1.GetMater().GetSpe();
00513                                 break;
00514                             }
00515 
00516 
00517                         case 2:
00518                             {
00519                                 Col.X = Sphere2.GetMater().GetCol().X * RayCol.X * 255;
00520                                 Col.Y = Sphere2.GetMater().GetCol().Y * RayCol.Y * 255;
00521                                 Col.Z = Sphere2.GetMater().GetCol().Z * RayCol.Z * 255;
00522                                 SpeCol = Sphere2.GetMater().GetSpe();
00523                                 break;
00524                             }
00525 
00526 
00527                         case 3:
00528                             {
00529                                 Col.X = Thor1.GetMater().GetCol().X * RayCol.X * 255;
00530                                 Col.Y = Thor1.GetMater().GetCol().Y * RayCol.Y * 255;
00531                                 Col.Z = Thor1.GetMater().GetCol().Z * RayCol.Z * 255;
00532                                 SpeCol = Thor1.GetMater().GetSpe();
00533                                 break;
00534                             }
00535 
00536 
00537 
00538                         case 4:
00539                             {
00540                                 Col.X = Thor2.GetMater().GetCol().X * RayCol.X * 255;
00541                                 Col.Y = Thor2.GetMater().GetCol().Y * RayCol.Y * 255;
00542                                 Col.Z = Thor2.GetMater().GetCol().Z * RayCol.Z * 255;
00543                                 SpeCol = Thor2.GetMater().GetSpe();
00544                                 break;
00545                             }
00546 
00547 
00548 
00549                         case 5:
00550                             {
00551                                 Col.X = Thor3.GetMater().GetCol().X * RayCol.X * 255;
00552                                 Col.Y = Thor3.GetMater().GetCol().Y * RayCol.Y * 255;
00553                                 Col.Z = Thor3.GetMater().GetCol().Z * RayCol.Z * 255;
00554                                 SpeCol = Thor3.GetMater().GetSpe();
00555                                 break;
00556                             }
00557 
00558 
00559                      }
00560 
00561                     Colour += countLites(Dist, Col, SpeCol, Light1);
00562                     Colour += countLites(Dist, Col, SpeCol, Light2);
00563                     if (Colour.X > 255) Colour.X = 255;
00564                     if (Colour.Y > 255) Colour.Y = 255;
00565                     if (Colour.Z > 255) Colour.Z = 255;
00566                     RGBCol[i][j] += Colour;
00567                     switch (numObj)
00568                     {
00569                        case 1:
00570                             {
00571                                 RayCol = Vector3D((1.0f - Sphere1.GetMater().GetRef().X) * RayCol.X,
00572                                                   (1.0f - Sphere1.GetMater().GetRef().Y )* RayCol.Y,
00573                                                   (1.0f - Sphere1.GetMater().GetRef().Z )* RayCol.Z);
00574                                 b1 =false;
00575                                 break;
00576                             }
00577 
00578 
00579                         case 2:
00580                             {
00581                                 RayCol = Vector3D((1.0f - Sphere2.GetMater().GetRef().X) * RayCol.X,
00582                                                 (1.0f - Sphere2.GetMater().GetRef().Y )* RayCol.Y,
00583                                                 (1.0f - Sphere2.GetMater().GetRef().Z )* RayCol.Z);
00584                                 b2 =false;
00585                                 break;
00586                             }
00587 
00588 
00589                         case 3:
00590                             {
00591                                 RayCol = Vector3D((1.0f - Thor1.GetMater().GetRef().X) * RayCol.X,
00592                                                 (1.0f - Thor1.GetMater().GetRef().Y )* RayCol.Y,
00593                                                 (1.0f - Thor1.GetMater().GetRef().Z )* RayCol.Z);
00594                                 b3 =false;
00595                                 break;
00596                             }
00597 
00598 
00599                         case 4:
00600                             {
00601                                 RayCol = Vector3D((1.0f - Thor2.GetMater().GetRef().X) * RayCol.X,
00602                                                 (1.0f - Thor2.GetMater().GetRef().Y )* RayCol.Y,
00603                                                 (1.0f - Thor2.GetMater().GetRef().Z )* RayCol.Z);
00604                                 b4 =false;
00605                                 break;
00606                             }
00607 
00608 
00609 
00610                         case 5:
00611                             {
00612                                 RayCol = Vector3D((1.0f - Thor3.GetMater().GetRef().X) * RayCol.X,
00613                                                 (1.0f - Thor3.GetMater().GetRef().Y )* RayCol.Y,
00614                                                 (1.0f - Thor3.GetMater().GetRef().Z )* RayCol.Z);
00615                                 b5 =false;
00616                                 break;
00617                             }
00618                      }
00619 
00620 
00621                 }
00622             }
00623             while ((temp.Length() < 30) && ((RayCol.X != 0) || (RayCol.Y != 0) || (RayCol.Z != 0)) && (cola < 5));
00624 
00625         }
00626 
00627 
00628 
00629     for(int i = 0;i < Wid; i++)
00630         for(int j = 0;j < Hey; j++)
00631         {
00632             if (RGBCol [i][j].X > 255) RGBCol [i][j].X = 255;
00633             if (RGBCol [i][j].Y > 255) RGBCol [i][j].Y = 255;
00634             if (RGBCol [i][j].Z > 255) RGBCol [i][j].Z = 255;
00635             curImage->setPixel(i, j, qRgb( RGBCol[i][j].X,RGBCol[i][j].Y, RGBCol[i][j].Z));
00636         }
00637     image->convertFromImage(*curImage);
00638 
00639     for (int i = 0; i < Wid; i++)
00640             delete[] RGBCol[i];
00641     delete[] RGBCol;
00642 
00643 }
00644 
00645 void MainWindow::AntiAliasing()//сепарабельное размытие
00646 {
00647     if (!AntiAl)
00648     {
00649         double sigma = 1.0;
00650         int N = 1 + (float)(3 * sigma), i;
00651         double tem;
00652         double wind[(2 * N) + 1];
00653         QImage *Temp = new QImage(curImage->width(),curImage->height(),QImage::Format_RGB32);
00654         for (i = (2 * N); i >= 0; i--)
00655         {
00656             if (i >= N)
00657             {
00658                 tem = (float)(N - i) * (i - N) / (2 * sigma * sigma);
00659                 if (tem >= 0)
00660                     wind[i]= exp(tem);
00661                 else
00662                     wind[i]= 1 / exp(-tem);
00663             }
00664             else wind[i] = wind[2 * N - i] ;
00665         }
00666         wash(Temp, curImage->height(), curImage->width(), N, wind, true);
00667         wash(Temp, curImage->width(), curImage->height(), N, wind , false);
00668         image->convertFromImage(*curImage);
00669         delete Temp;
00670         statusBar()->showMessage(tr("AntiAliasing Made"), 2000);
00671         repaint();
00672     }
00673 
00674 }
00675 
00676 void MainWindow::wash(QImage *Temp,int koef1, int koef2, int N, double* wind, bool a)//размытие
00677 {
00678     int i , j , k;
00679     double red, green, blue;
00680     double sum;
00681     for (i = 0; i < koef1; i++)
00682         for (j = 0; j < koef2; j++)
00683         {
00684             sum = 0;
00685             red = 0;
00686             green = 0;
00687             blue = 0;
00688             for (k = (-N) ; k <= N ; k++)
00689                 if (( (j + k) >= 0) && ( (j + k) < koef2))
00690                 {
00691                     if (a)
00692                     {
00693                         red += qRed(curImage->pixel(j + k, i)) * wind [k + N] ;
00694                         green += qGreen(curImage->pixel(j + k, i)) * wind [k + N] ;
00695                         blue += qBlue(curImage->pixel(j + k, i)) * wind [k + N] ;
00696                     }
00697                     else
00698                     {
00699                         red += qRed(curImage->pixel(i, j + k)) * wind [k + N] ;
00700                         green += qGreen(curImage->pixel(i, j + k)) * wind [k + N] ;
00701                         blue += qBlue(curImage->pixel(i, j + k)) * wind [k + N] ;
00702                     }
00703                 }
00704             for (k = (-N) ; k <= N ; k++) if (( (j + k) >= 0) && ( (j + k) < koef2))
00705                 sum += wind[k + N];
00706             if (a)
00707                 Temp->setPixel(j , i , qRgb(red / sum, green / sum, blue / sum));
00708             else
00709                 Temp->setPixel(i , j , qRgb(red / sum, green / sum, blue / sum));
00710         }
00711     *curImage = *Temp;
00712 }
00713