Projects-3-computer Graphics & Virtual Reality (algorithms, Modeling, Programs)

  • Uploaded by: Marin Vlada
  • 0
  • 0
  • April 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Projects-3-computer Graphics & Virtual Reality (algorithms, Modeling, Programs) as PDF for free.

More details

  • Words: 9,327
  • Pages: 43
Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada

Grafica pe calculator / Geometrie computationala Computer Graphics / Computation Geometry Titular curs : Conf. Dr. Marin Vlada, Universitatea din Bucuresti WEB: http://marinvlada.googlepages.com/, www.ad-astra.ro/marinvlada E-mail: marinvlada[at]yahoo.com, marinvlada[at]gmail.com Course: COMPUTER GRAPHICS | Bachelor of Science (Computer Science) Software: C++, OpenGL, Java 3D, Java Script, VRML, SVG http://marinvlada.googlepages.com/prog_grafic.htm www.cniv.ro

www.icvl.eu ©

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada

PROIECT – generare curbe plane remarcabile Nota: Codul in C++

REFERINTA: M. Vlada, A,.Posea,…, Grafica pe calculator in limbajele Pascal si C, vol. I,II, , Implementare si aplicatii, Ed. Tehnica,1992 /* cout cout cout cout cout cout cout cout cout cout cout cout */

<<"*******************************************************"<<"\n"; <<" CURBE PLANE REMARCABILE "<<"\n"; <<" autor : M . Vlada "<<"\n"; <<"*******************************************************"<<"\n"; <<" 1 =concoida NICOMEDE 2 =melcul lui PASCAL "<<"\n"; <<" 3 =cisoida DIOCLES 4 =cisoida elipsei "<<"\n"; <<" 5 =trisectoarea MAC-LAURIN 6 =trisectoarea LONGCHAMPS"<<"\n"; <<" 7 =cicloida 8 =epicicloida "<<"\n"; <<" 9 =hipocicloida 10=astroida "<<"\n"; <<" 11=strofoida 12=bucla MARIA AGNESI "<<"\n"; <<" ( centrul ecranului = originea sistemului cartezian ) "<<"\n"; <<"*******************************************************"<<"\n";

//{=========================================================} //program CURBE ; curbe plane remarcabile - ecuatii parametrice #include #include <math.h> #include #include #include <stdlib.h> #define pi M_PI double round(double number) { double x = ceil(number)-number; if( number >= 0 ) {if(x <= 0.5) return ceil(number); else return floor(number);} else {if(x < 0.5) return ceil(number); else return floor(number);} } char solid[8]={255,255,255,255,255,255,255,255}; int graphdriver , graphmode; char ch; int graphX[740], graphY[740]; //array[-319..319] of integer; double a , b , arg , val1 , val2; int i , t1 , t2 , flag; //========================================================== void INIT() { graphdriver = DETECT;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada initgraph (&graphdriver ,&graphmode , "C:\\Borlandc\\bgi"); //init mod grafic setfillpattern ( solid , 15); bar ( 0,0 ,700,500 ); setcolor( 0 ) ; setviewport ( 320 , 175 , 500 , 200 , 0 );//fixare origine rectangle ( -150 , -150 , 150 , 150 ); //deseneaza un chenar setviewport ( 170 , 25 , 470 , 325 , 1 ); //fixare fereastra } void STOP() //iesire din modul grafic { getch(); // inghetare imagine closegraph(); // iesire mod grafic } void AXE() //-----------// deseneaza axele (format mic) in origine { moveto ( 120 , 150 ); lineto ( 180 , 150 ); moveto ( 150 , 120 ); lineto ( 150 , 180 ); } void GRAPH1 (int t1 ,int t2) //-----------------------------------------------//deseneaza curba data de ecuatiile parametrice // x = f (t) , y = g(t) pe intervalul [t1 ,t2] { int i; moveto ( graphX[t1+319] , graphY[t1+319] ) ; // fara trasare for(i = t1+1; i <= t2; i++) lineto ( graphX [ i+319 ] , graphY [ i+319 ] );// trasare } //{----------------------------------------------------} // main void main() { cout <<"*******************************************************"<<"\n"; cout <<" CURBE PLANE REMARCABILE "<<"\n"; cout <<" autor : M . Vlada "<<"\n"; cout <<"*******************************************************"<<"\n"; cout <<" 1 =concoida NICOMEDE 2 =melcul lui PASCAL "<<"\n"; cout <<" 3 =cisoida DIOCLES 4 =cisoida elipsei "<<"\n"; cout <<" 5 =trisectoarea MAC-LAURIN 6 =trisectoarea LONGCHAMPS"<<"\n"; cout <<" 7 =cicloida 8 =epicicloida "<<"\n"; cout <<" 9 =hipocicloida 10=astroida "<<"\n"; cout <<" 11=strofoida 12=bucla MARIA AGNESI "<<"\n"; cout <<" ( centrul ecranului = originea sistemului cartezian ) "<<"\n"; cout <<"*******************************************************"<<"\n"; cout <<" precizitati numarul de ordine pentru curba dorita : "<<"\n"; cin >> flag; switch (flag){

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada case 1: { // ================= curba lui cout <<" curba lui NICOMEDE "; cout <<" dati parametri a , b = "; t1 = round( (- pi / 2.0)*100) ; t2 //factorul 100 reprezinta scalarea for(i = t1; i <= t2; i++) { arg = i / 100.00 ; //vectorii graphX, graphY retin

NICOMEDE =============== cin >> a; cin>>b; =round( (pi / 2.0)*100); imaginii

coordonatele pentru

desenare graphX [i+319] = round( ( a + b * cos (arg) ) * 100 )+150 ; graphY [i+319] = round( ( a*sin(arg)/cos(arg) + b*sin(arg))*100)+150; } INIT(); AXE(); GRAPH1 ( t1 , t2 ); for(i = t1; i <= t2; i++) { arg = i / 100.00 ; graphX[i+319] = round( ( a - b * cos(arg) ) *100 )+150 ; graphY[i+319] = round( ( a*sin(arg)/cos(arg) b*sin(arg))*100)+150; } GRAPH1 ( t1 , t2 ) ; break; } // =================== melcul lui PASCAL =================== case 2 : { cout <<" melcul lui PASCAL "<<"\n"; cout <<" dati parametri a ,b = "; cin >> a; cin >> b; t1 = round( -pi * 90 ) ; t2 = - t1 ; for(i = t1; i <= t2; i++) { arg = i / 90.00 ; graphX[i+319] = round( ( 2 *(a * cos(arg) + b)*cos(arg) ) * 90 ); graphY[i+319] = round( ( 2 *(a * cos(arg) + b)*sin(arg) ) * 90 ); graphX[i+319] = graphX[i+319] + 150 ; graphY[i+319] = graphY[i+319] + 150; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ; break; } // =========== cisoida lui DIOCLES ( cisoida cercului ========= case 3 : { cout <<" cisoida lui DIOCLES ( cisoida cercului "<<'\n'; cout<<" dati parametrul a = "; cin >> a; t1 = round ( (-pi /2.0 ) * 90 ) ; t2 = - t1 ;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada for(i = t1; i <=t2; i++) { arg = i / 90.0 ; graphX[i+319] = round( ( 2*a*sin(arg) *sin(arg) ) * 90 ) + 150 ; graphY[i+319] = round( ( 2*a*sin(arg)*sin(arg)*sin(arg) /cos(arg) ) * 90 ) + 150 ; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ; break; } // ========================= cisoida elipsei ==================== case 4 : { cout <<" cisoida elipsei "; cout<<" dati parametri a , b = "; cin >> a>> b; t1 = round( ( - pi / 2.0 ) * 90 ) ; t2 = - t1 ; for( i = t1; i<= t2; i++) { arg = i / 90.0 + 0.01 ; graphX[i+319] = round( ( 2*a*a*a / ( a*a + b*b* pow(( cos(arg) / sin(arg) ),2) ) ) * 90 ) + 150 ; graphY[i+319] = round( ( 2*a*a*a / ( a*a * cos(arg) / sin(arg) + b*b * pow( ( cos(arg) / sin(arg) ),2) * ( cos(arg) / sin(arg) ) ) ) * 90 ) + 150 ; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ; break; } // ================== trisectoarea lui MAC - LAURIN ================== case 5 : { cout <<" trisectoarea lui MAC - LAURIN "<<"\n"; cout <<" dati parametrul a = "; cin>> a; t1 = round ( ( - pi / 2.0 ) * 90 ) ; t2 = - t1 ; for( i= t1; i<=t2; i++) { arg = i / 90.0 + 0.01 ; graphX[i+319] = round ( ( 4 * a * cos(arg) * cos(arg) - a) * 90)+150; graphY[i+319] = round ( ((4 * a * cos(arg) * cos(arg) - a) * sin(arg) / cos(arg) ) * 90 ) + 150 ; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ; break; } // ==================== trisectoarea lui LONGCHAMPS =================== case 6 : { cout <<" trisectoarea lui LONGCHAMPS ";

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada cout <<" dati parametrul a = "; cin >> a; t1 = round ( ( - pi / 2.0 ) * 50 ) ; t2 = - t1 ; for( i = t1; i <= t2; i++) { arg = i / 50.0 + 0.01 ; graphX[i+319] = round ( ( a / ( 4 * cos(arg)*cos(arg) -3) ) *50) +150; graphY[i+319] = round ( ( ( a* sin(arg) /cos(arg) ) / ( 4 * cos(arg) * cos(arg) - 3 ) ) * 50 ) + 150 ; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ; break; } // ======================= cicloida ================================ case 7 : { cout <<" cicloida "; cout<<" dati parametri a , b = "; cin >> a>>b; t1 = round ( ( - 2 * pi* 1.4 )* 35 ) ; t2 = - t1 ; for(i= t1; i <= t2; i++) { arg = i / 35.0 ; graphX[i+319] = round ( ( a * arg - b*sin(arg) ) * 35 ) + 150 ; graphY[i+319] = round ( ( a - b * cos(arg) ) * 35 ) + 150 ; } INIT(); AXE(); GRAPH1 ( t1 , t2 ) ;break; } // ===================== epicicloida =============================== case 8 :{ cout <<" epicicloida "; cout <<" dati parametri a , b = "; cin>> a>> b ; t1 = 0 ; t2 = round ( 10 * pi * 10) ; for(i = t1; i <= t2; i++) { arg = i / 10.00 ; val1 = b *arg / a ; val2 = arg + b * arg / a; graphX[i+319] = round( ( ( a + b) * cos( val1 ) - b * cos( val2 ) ) * 60 ) + 150; graphY[i+319] = round( ( (a + b) * sin( val1 ) - b * sin( val2 ) ) * 60 ) + 150 ; } INIT() ; AXE() ; GRAPH1 ( t1 , t2 ); break; } // ======================== hipocicloida ============================= case 9 : { cout <<" hipocicloida "; cout <<" dati parametri a , b = "; cin>> a >> b; t1 = 0 ; t2 = round ( 10 * pi * 10 ) ;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada for(i = t1; i <= t2; i++) { arg = i / 10.00 ; val1 = b * arg / a ; val2 = arg - b * arg / a ; graphX[i+319] = round( (( a-b ) * cos( val1 ) + b * cos( val2 )) * 150 ) + 150 ; graphY[i+319] = round( (( a-b ) * sin( val1 ) - b * sin( val2 )) * 150 ) + 150 ; } INIT() ; AXE() ; GRAPH1 ( t1 , t2 ) ; break; } // ======================== astroida =============================== case 10 : { cout <<" astroida "; cout <<" dati parametrul a = "; cin >> a; t1 = 0 ; t2 = round ( 2 * pi * 10 ) ; for(i = t1; i <= t2; i++) { arg = i / 10.00 ; graphX[i+319] = round ( ( a * cos(arg) * cos(arg) * cos(arg) ) * 60 ) + 150 ; graphY[i+319] = round ( ( a * sin(arg) * sin(arg) * sin(arg) ) * 60 ) + 150 ; } INIT() ; AXE() ; GRAPH1 ( t1 , t2 ) ; break; } // ========================= strofoida ============================== case 11 : { cout <<" strofoida "; cout <<" dati parametrul a = "; cin >> a; t1 = round ( ( - pi / 2 ) * 60 ) ; t2 = -t1 ; for(i = t1; i <= t2; i++) { arg = i / 60.0 + 0.01 ; graphX[i+319] = round( ( a + a * sin(arg) ) * 60 ) + 150 ; graphY[i+319] = round( ( a*sin(arg)/cos(arg) + a * sin(arg) * sin(arg) / cos(arg) ) * 60 ) + 150 ; } INIT() ; AXE() ; GRAPH1 ( t1 , t2 ) ; for(i = t1; i <= t2; i++) { arg = i / 60.0 + 0.01 ;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada graphX[i+319] = round( ( a - a * sin(arg) ) * 60 ) + 150 ; graphY[i+319] = round( ( a*sin(arg)/cos(arg) - a * sin(arg) * sin(arg) / cos(arg) ) * 60 ) + 150 ; } GRAPH1 ( t1 , t2 ) ; break; } // ==================== bucla MARIA AGNESI ====================== case 12 : { cout <<" bucla MARIA AGNESI "; cout <<" dati parametrul a = "; cin >> a; t1 = 1 ; t2 = round( pi * 60 ) - 1; for(i = t1; i <= t2; i++) { arg = i / 60.0 ; graphX[i+319] = round ( a * cos(arg) / sin(arg) * 60 ) + 150 ; graphY[i+319] = round ( a * sin(arg) * sin(arg) * 60 ) + 150 ; } INIT() ; AXE() ; GRAPH1 ( t1 , t2 ) ;break; } case 13: exit(0); } STOP(); } //sfirsit program

PROIECT – mini editor grafic Nota: Codul Visual Studio (Visual

C++); Visual Studio .NET 2003

Autor: Lucian Codita, sudent Facultatea de Matematica si Informatica, Universitatea din Bucuresti -Utilizeaza algoritmul Bresenham pentru trasarea liniei si cercului Program.cs using System; using System.Collections.Generic; using System.Windows.Forms; namespace Grafica { static class Program { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1());

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada } } }

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada Form1.cs using using using using using using using using

System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Drawing.Imaging; System.Text; System.Windows.Forms;

namespace Grafica { public partial class Form1 : Form { private Bitmap buffer; // va contine figura ce se deseneaza la un moment dat; dupa ce am terminat, se va salva figura pe canvas private Bitmap canvas; // va contine imaginea finala private Graphics canvasGraphics; private Graphics bufferGraphics; private private private private

int int int int

Ax; // punctul de unde incep sa desenez Ay; Bx; // punctul unde termin de desenat By;

private Color color; //culoarea cu care se picteaza private Boolean drawMode = false; // desenez in momentul asta sau nu ? private String operation; // operatia ce se desfasoara public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { buffer = new Bitmap(400, 300, System.Drawing.Imaging.PixelFormat.Format24bppRgb); canvas = new Bitmap(400, 300, System.Drawing.Imaging.PixelFormat.Format24bppRgb); canvasGraphics = Graphics.FromImage(canvas); bufferGraphics = Graphics.FromImage(buffer); color = Color.DarkCyan; operation = "circle"; canvasGraphics.Clear(Color.White); bufferGraphics.Clear(Color.White); panel1.Cursor = Cursors.Cross; } private void panel1_MouseDown(object sender, MouseEventArgs e) { Ax = e.X; Ay = e.Y;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada drawMode = true; } private void panel1_MouseMove(object sender, MouseEventArgs e) { if (!drawMode) return; Bx = e.X; By = e.Y; bufferGraphics.Clear(Color.White); if (operation == "circle") drawCircle(); if (operation == "line") drawLine(); if (operation == "erase") erase(); if (operation == "brush") brush(); this.panel1.Invalidate(); // fortez redesenarea panel-ului } private void panel1_MouseUp(object sender, MouseEventArgs e) { drawMode = false; // salvez figura curenta pe poza principala (canvas) : ImageAttributes attr = new ImageAttributes(); attr.SetColorKey(Color.White, Color.White); Rectangle dstRect = new Rectangle(0, 0, buffer.Width, buffer.Height); canvasGraphics.DrawImage(buffer, dstRect, 0, 0, buffer.Width, buffer.Height, GraphicsUnit.Pixel, attr); bufferGraphics.Clear(Color.White); this.panel1.Invalidate(); } private void panel1_Paint(object sender, PaintEventArgs e) { Graphics objGraphics = e.Graphics; // afisez mai intai poza principala : objGraphics.DrawImage(canvas, 0, 0); // fac bufferul (ce contine figura curenta) transparent si il afisez : ImageAttributes attr = new ImageAttributes(); attr.SetColorKey(Color.White, Color.White); Rectangle dstRect = new Rectangle(0, 0, buffer.Width, buffer.Height); objGraphics.DrawImage(buffer, dstRect, 0, 0, buffer.Width, buffer.Height, GraphicsUnit.Pixel, attr); } private void newToolStripMenuItem_Click(object sender, EventArgs e) { // sterg totul: canvasGraphics.Clear(Color.White); bufferGraphics.Clear(Color.White); this.panel1.Invalidate(); }

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada /* * - functii grafice -----------------------------------*/ void drawCircle() { int radius = (int)Math.Round(Math.Sqrt((Bx - Ax) * (Bx Ax) + (By - Ay) * (By - Ay))); Bitmap bm = new Bitmap(1, 1); bm.SetPixel(0, 0, color); int D = 1 - radius; int x = 0; int y = radius; int i = 0; while (x <= y) { ++i; x++; if (D < 0) { D += 2 * x + 3; } else { y--; D += 2 * (x - y) + 5; } bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm, bufferGraphics.DrawImage(bm,

Ax Ax Ax Ax Ax Ax Ax Ax

+ + + + -

x, y, y, x, x, x, y, y,

Ay Ay Ay Ay Ay Ay Ay Ay

+ + + +

y); x); x); y); y); y); x); x);

} } void drawLine() // algoritmul bresenham { Bitmap bm = new Bitmap(1, 1); bm.SetPixel(0, 0, color); int x0 = Ax; int y0 = Ay; int x1 = Bx; int y1 = By; bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); if (steep) // daca panta dreptei e mai mare ca 1 inversez coordonatele x si y { swap(ref x0, ref y0); swap(ref x1, ref y1); } if (x0 > x1) // daca linia se indreapta spre stanga inversez capetele { swap(ref x0, ref x1);

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada swap(ref y0, ref y1); } int deltax = x1 - x0; int deltay = Math.Abs(y1 - y0); int error = -deltax / 2; int ystep; int y = y0; if (y0 < y1) // daca linia se indreapta in sus adaug -1 variabilei y la fiecare pas ystep = 1; else ystep = -1; for (int x = x0; x<= x1; x++) { if (steep) bufferGraphics.DrawImage(bm, y, x); else bufferGraphics.DrawImage(bm, x, y); error = error + deltay; if (error >= 0) { y = y + ystep; error = error - deltax; } } } void erase() { Bitmap bm = new Bitmap(20, 20); Graphics objGraphics = Graphics.FromImage(bm); objGraphics.Clear(Color.White); canvasGraphics.DrawImage(bm, Bx, By); } void brush() { Bitmap bm = new Bitmap(5, 5); Graphics objGraphics = Graphics.FromImage(bm); objGraphics.Clear(color); canvasGraphics.DrawImage(bm, Bx, By); } private void button15_Click(object sender, EventArgs e) { info.BackColor = this.color = button15.BackColor; } private void button2_Click(object sender, EventArgs e) { info.BackColor = this.color = button2.BackColor; } private void button3_Click(object sender, EventArgs e) { info.BackColor = this.color = button3.BackColor; } private void button4_Click(object sender, EventArgs e) { info.BackColor = this.color = button4.BackColor;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada } private void button7_Click(object sender, EventArgs e) { info.BackColor = this.color = this.color = button7.BackColor; } private void button6_Click(object sender, EventArgs e) { info.BackColor = this.color = button6.BackColor; } private void button5_Click(object sender, EventArgs e) { info.BackColor = this.color = button5.BackColor; } private void button9_Click(object sender, EventArgs e) { info.BackColor = this.color = button9.BackColor; } private void button10_Click(object sender, EventArgs e) { info.BackColor = this.color = button10.BackColor; } private void button11_Click(object sender, EventArgs e) { info.BackColor = this.color = button11.BackColor; } private void button12_Click(object sender, EventArgs e) { info.BackColor = this.color = button12.BackColor; } private void button13_Click(object sender, EventArgs e) { info.BackColor = this.color = button13.BackColor; } private void button14_Click(object sender, EventArgs e) { info.BackColor = this.color = button14.BackColor; } private void button1_Click(object sender, EventArgs e) { info.BackColor = this.color = button1.BackColor; } private void button8_Click(object sender, EventArgs e) { info.BackColor = this.color = button8.BackColor; }

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada private { int y = x = }

void swap(ref int x, ref int y) a = y; x; a;

private void button16_Click(object sender, EventArgs e) { operation = "circle"; } private void button18_Click(object sender, EventArgs e) { operation = "line"; } private void button19_Click(object sender, EventArgs e) { operation = "erase"; } private void button20_Click(object sender, EventArgs e) { operation = "brush"; } private void newToolStripMenuItem1_Click(object sender, EventArgs e) { canvasGraphics.Clear(Color.White); bufferGraphics.Clear(Color.White); panel1.Invalidate(); } private void exitToolStripMenuItem1_Click(object sender, EventArgs e) { this.Close(); } } // un panel special, ce nu clipeste atunci cand se deseneaza pe el public class NewPanel : System.Windows.Forms.Panel { public NewPanel() { this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.UpdateStyles(); } } }

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada

PROIECT – aplicatie privind aria uni poligon oarecare Nota: Codul Visual Studio (Visual

C++); Visual Studio .NET 2003

Într-un sistem cartezian de axe XOY, considerăm un domeniu ce este determinat de o linie poligonală oarecare şi închisă P = P1P2 ... Pn , unde punctele Pi (xi , yi ), i= 1…n sunt determinate de coordonatele carteziene (xi , yi ), i= 1…n . Aria domeniului este data de urmatoarea formula:

Ca exemplu, prezentăm în figura de mai jos un domeniu oarecare determinat de 11 puncte date prin coordonate carteziene. Valoarea absolută din formula de mai sus este necesară, deoarece introducerea coordonatelor punctelor ce determină domeniu poate fi în sens trigonometric sau în sens invers celui trigonometric, aşa cum este în figura de mai jos.

Programul va afisa fereastra prezentata mai jos (Height = 300, Width = 450) si care ofera un meniu in partea inferioara, format din butoane pentru actiuni utile pentru aplicatie: - stergerea tuturor elementelor din zona de editare • Erase all (New) • Load from file - incarcarea unui fisier deja creat - salvarea coordonetelor punctelor intr-un fisier • Save to a file • Edit – modificarea / editarea punctelor deja introduse • Compute Area – activ (se va calcula aria domeniului poligonal) dupa introducerea in zona de editare a punctelor poligonului

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada

Erase Load from file Save to a file Introducerea punctelor se face folosind mouse-ul prin actiunea de click-stanga in zona de editare, fiecare punct fiid numerotat si colorat cu verde (punctul initial fiind colorat cu albastru). Ultimul punt trebuie sa fie obtinut prin click-stanga pe primul introdus in scopul inchiderii domeniului poligonal. Dupa obtinerea poligonului dorit se pot face modificari ale coordonatelor punctelor prin click-stanga pe punct si „tragere” in zona dorita.

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada EXEMPLU:

Calculul ariei Program.cs using System; using System.Collections.Generic; using System.Windows.Forms; namespace PolygonalArea { static class Program { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault( false ); Application.Run( new Form1() ); } } } Form1.cs using using using using

System; System.Collections.Generic; System.ComponentModel; System.Data;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada using System.Drawing; using System.Text; using System.Windows.Forms; namespace PolygonalArea { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private graphicArea mainZone; private void Form1_Load( object sender, EventArgs e ) { mainZone = new graphicArea( graphicAreaMode.Polygon ); mainZone.Location = placeHolder.Location; this.Controls.Add( mainZone ); } private void Form1_Resize( object sender, EventArgs e ) { if( this.Height < 300 ) this.Height = 300; if( this.Width < 450 ) this.Width = 450; mainZone.Height = this.Height - 60; mainZone.Width = this.Width - 35; } private void Form1_FormClosing( object sender, FormClosingEventArgs e ) { mainZone.closingASAP = true; } } }

graphicArea.cs using using using using using using using using using using

System; System.Collections; System.Collections.Generic; System.ComponentModel; System.Drawing; System.Drawing.Drawing2D; System.Drawing.Imaging; System.Data; System.Text; System.Windows.Forms;

namespace PolygonalArea {

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada internal struct Edge { public int v1, v2; public Edge( int v1, int v2 ) { this.v1 = v1; this.v2 = v2; } } public enum graphicAreaMode { Graph, Polygon, Count } public enum graphicAreaStatus { Place, Edit, Compute, Count } public partial class graphicArea : UserControl { private List v = new List(); private List<Edge> e = new List<Edge>(); graphicAreaMode mode; internal bool closingASAP = false; public graphicArea( graphicAreaMode mode ) { this.mode = mode; InitializeComponent(); cmdAction.Text = actionName; cmdAction.Enabled = chkEdit.Checked = false; picBox.Image = new Bitmap( picBox.Width, picBox.Height, PixelFormat.Format32bppPArgb ); tooltips.SetToolTip( cmdNew, "Erase all (New)" ); tooltips.SetToolTip( cmdLoad, "Load from file" ); tooltips.SetToolTip( cmdSave, "Save to a file" ); } public graphicAreaStatus status() { if( !chkEdit.Checked ) return graphicAreaStatus.Place; return graphicAreaStatus.Edit; //to-do: other statuses? } private Point startedAt; private Label editing = null;

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada private void picBox_MouseDown( object sender, MouseEventArgs e ) { if( ( chkEdit.Checked ) && ( editing != null ) ) { editing.BackColor = Color.LightGreen; editing = null; } startedAt = e.Location; } private void vertex_MouseDown( object sender, MouseEventArgs e ) { if( chkEdit.Checked ) { editing = ( Label )sender; editing.BackColor = Color.Yellow; } startedAt = ( ( Label )sender ).Location; startedAt.Offset( e.Location ); //updates the global variable } private /*const*/ int RADIUS = 10; private List getTouchyPoints( int x, int y ) { return getTouchyPoints( x, y, -1 ); } private List getTouchyPoints( int x, int y, int excluding ) { List result = new List(); int minDist = 7 * RADIUS / 2; for( int i = 0; i < v.Count; i++ ) if( i != excluding ) if( distance( x, y, v[ i ].X, v[ i ].Y ) < minDist ) result.Add( i ); return result; } private double distance( int x1, int y1, int x2, int y2 ) { return Math.Sqrt( ( ( x1 - x2 ) * ( x1 - x2 ) ) + ( ( y1 - y2 ) * ( y1 - y2 ) ) ); } private double getDistance( Point p1, Point p2 ) { return distance( p1.X, p1.Y, p2.X, p2.Y ); } private Label makeVertex( int x, int y, string tag ) { return makeVertex( x, y, tag, Color.LightGreen );

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada } private Label makeVertex( int x, int y, string tag, Color c ) { Label vertex = new Label(); vertex.BackColor = c; vertex.Height = vertex.Width = 2 * RADIUS; vertex.Location = new Point( x - RADIUS, y - RADIUS ); vertex.Tag = tag; //todo: use a flag to set if the number is shown or not vertex.TextAlign = ContentAlignment.MiddleCenter; vertex.Text = tag; //shape GraphicsPath path = new GraphicsPath(); //System.Drawing.Drawing2D path.AddEllipse( 0, 0, 2 * RADIUS, 2 * RADIUS ); vertex.Region = new Region( path ); //event handlers vertex.MouseDown += new MouseEventHandler( vertex_MouseDown ); vertex.MouseUp += new MouseEventHandler( vertex_MouseUp ); vertex.MouseMove += new MouseEventHandler( vertex_MouseMove ); //the end return vertex; } private void makeLine( int p ) { makeLine( p, p + 1, Pens.Black ); } private void makeLines( int point, Pen pen ) { if( point < 0 ) return; int max = v.Count - 1; if( point > 0 ) makeLine( point - 1, point, pen ); else makeLine( max, 0, pen ); if( point < max ) makeLine( point, point + 1, pen ); else makeLine( max, 0, pen ); } private void makeLine( int p1, int p2, Pen pen ) { //Pen p = new Pen( Color.Black, 1 ); //Graphics g = picBox.CreateGraphics(); //g.DrawLine( p, v[ p1 ], v[ p2 ] ); //g.Dispose(); //p.Dispose();

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada Graphics.FromImage( picBox.Image ).DrawLine( pen, v[ p1 ], v[ p2 ] ); picBox.Invalidate(); } private void vertex_MouseUp( object sender, MouseEventArgs e ) { Point displacement = ( ( Label )sender ).Location; MouseEventArgs actualEvent = new MouseEventArgs( e.Button, e.Clicks, e.X + displacement.X, e.Y + displacement.Y, e.Delta ); picBox_MouseUp( sender, actualEvent ); } private void cmdNew_Click( object sender, EventArgs e ) { v.Clear(); this.e.Clear(); picBox.Controls.Clear(); Graphics.FromImage( picBox.Image ).Clear( Color.White ); picBox.Invalidate(); cmdAction.Enabled = chkEdit.Checked = false; } private void cmdLoad_Click( object sender, EventArgs e ) { OpenFileDialog dialog = new OpenFileDialog(); dialog.CheckFileExists = true; dialog.Multiselect = false; dialog.Title = "Select the input file..."; if( dialog.ShowDialog() == DialogResult.Cancel ) return; List<Edge> incomingLines = null; List newData = loadDataFromFile( dialog.FileName, ref incomingLines ); if( newData.Count < 3 ) { MessageBox.Show( "Not enough points were specified!" ); return; } if( v.Count > 0 ) { DialogResult res = MessageBox.Show( "You have already drawn some points! Replace them?", "Caution: overwriting existing data", MessageBoxButtons.YesNo ); if( res == DialogResult.No ) return; cmdNew_Click( null, null ); } v = newData; this.e = incomingLines; //create labels and lines: recreatePicture();

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada } int minXpt, maxXpt, minYpt, maxYpt; private List loadDataFromFile( string fileName, ref List<Edge> edges ) { System.IO.TextReader reader = new System.IO.StreamReader( fileName ); string count = reader.ReadLine(); if( notAnInt( count ) ) return new List(); List result = new List( System.Convert.ToInt32( count ) ); progressBarContainer.Text = "Loading Vertices..."; progressBarContainer.Visible = true; progressBar.Maximum = result.Capacity; readPoints( result, reader ); progressBarContainer.Text = "Analyzing Vertices..."; double minDist = findExtremes( result ); { lblResult.Text = "d: " + minDist.ToString(); } if( minDist < ( 3 * RADIUS ) ) RADIUS = ( int )Math.Round( minDist / 3 ); { lblResult.Text = "new r: " + RADIUS.ToString(); } //debug: //Graphics.FromImage( picBox.Image ).DrawRectangle( Pens.LightGray, result[ minXpt ].X - 1, result[ minYpt ].Y - 1, 2 + result[ maxXpt ].X - result[ minXpt ].X, 2 + result[ maxYpt ].Y result[ minYpt ].Y ); //resize to fit: int dx = 0, dy = 0; if( ( result[ maxXpt ].X + 2 * RADIUS ) > picBox.Width ) dx = result[ maxXpt ].X + 2 * RADIUS picBox.Width; if( ( result[ maxYpt ].Y + 2 * RADIUS ) > picBox.Height ) dy = result[ maxYpt ].Y + 2 * RADIUS picBox.Height; if( ( dx > 0 ) || ( dy > 0 ) ) { this.Parent.Width += dx; this.Parent.Height += dy; } count = reader.ReadLine(); if( notAnInt( count ) ) return new List(); edges = new List<Edge>( System.Convert.ToInt32( count ) ); progressBarContainer.Text = "Loading Edges..."; progressBar.Maximum = edges.Capacity; for( int j = 0; j < edges.Capacity; j++ )

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada { progressBar.Value = j; string endPoints = reader.ReadLine(); string[] index = endPoints.Split( ' ' ); int v1 = 0, v2 = 0; if( notAnInt( index[ 0 ] ) || notAnInt( index[ 1 ] ) ) { //todo: warn: not an int } else { v1 = Convert.ToInt32( index[ 0 ] ); v2 = Convert.ToInt32( index[ 1 ] ); edges.Add( new Edge( v1, v2 ) ); } } progressBarContainer.Visible = false; reader.Close(); checkIntersections(); chkEdit.Enabled = true; return result; } private void readPoints( List points, System.IO.TextReader reader ) { for( int i = 0; i < points.Capacity; i++ ) { progressBar.Value = i; string location = reader.ReadLine(); string[] coords = location.Split( ' ' ); int x = 0, y = 0; if( notAnInt( coords[ 0 ] ) || notAnInt( coords[ 1 ] ) ) { //todo: warn: not an int } else { x = Convert.ToInt32( coords[ 0 ] ); y = Convert.ToInt32( coords[ 1 ] ); points.Add( new Point( x, y ) ); } } } private double findExtremes( List points ) { double minDist = -1.0; minXpt = maxXpt = minYpt = maxYpt = 0; for( int i = 0; i < points.Count; i++ ) { progressBar.Value = i; if( points[ i ].X < points[ minXpt ].X ) minXpt = i; if( points[ i ].X > points[ maxXpt ].X )

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada maxXpt = i; if( points[ i ].Y < points[ minYpt ].Y ) minYpt = i; if( points[ i ].Y > points[ maxYpt ].Y ) maxYpt = i; if( minDist < 0 ) { if( i == 1 ) minDist = getDistance( points[ 0 ], points[ 1 ] ); } else { int j = i - 1; double currentDist = 0; for( int k = 0; k < j; k++ ) { currentDist = getDistance( points[ k ], points[ j ] ); if( currentDist < minDist ) minDist = currentDist; } } } return minDist; } private bool notAnInt( string count ) { try { int i = System.Convert.ToInt32( count ); return false; } catch( FormatException ) { return true; } catch( OverflowException ) { return true; } } private void cmdSave_Click( object sender, EventArgs e ) { SaveFileDialog dialog = new SaveFileDialog(); dialog.OverwritePrompt = true; dialog.Title = "Select the input file..."; if( dialog.ShowDialog() == DialogResult.Cancel ) return; System.IO.TextWriter writer = new System.IO.StreamWriter( dialog.FileName, false ); writer.WriteLine( v.Count ); for( int i = 0; i < v.Count; i++ ) writer.WriteLine( "{0} {1}", v[ i ].X, v[ i ].Y );

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada writer.WriteLine( this.e.Count ); for( int j = 0; j < this.e.Count; j++ ) writer.WriteLine( "{0} {1}", this.e[ j ].v1, this.e[ j ].v2 ); writer.Close(); } private void tmrRefresher_Tick( object sender, EventArgs e ) { picBox.Refresh(); picBox.Invalidate(); } private void graphicArea_Resize( object sender, EventArgs e ) { picBox.Height = this.Height - 60; picBox.Width = this.Width - 20; panelTools.Top = picBox.Top + picBox.Height; //instead of moving all of: //cmdNew //cmdLoad + cmdSave //chkEdit //cmdAction + chkShowAll //lblResult //also, do something about the bitmap too: //picBox.Image = new Bitmap( picBox.Width, picBox.Height, PixelFormat.Format32bppPArgb ); Bitmap old = ( Bitmap )picBox.Image; int newWidth = ( picBox.Width > old.Width ? picBox.Width : old.Width ); int newHeight = ( picBox.Height > old.Height ? picBox.Height : old.Height ); picBox.Image = new Bitmap( newWidth, newHeight, PixelFormat.Format32bppPArgb ); Graphics.FromImage( picBox.Image ).DrawImage( old, new Point( 0, 0 ) ); } } } polygonalArea.cs using using using using using

System; System.Collections.Generic; System.Drawing; System.Text; System.Windows.Forms;

namespace PolygonalArea { //class polygonalArea : action //{ //} public partial class graphicArea : UserControl

Conf. Dr. Marin Vlada, Universitatea din Bucuresti

www.ad-astra.ro/marinvlada { private string actionName = "Compute Area"; private List

Related Documents


More Documents from ""