GDI DrawArc vs. OutOfMemoryException

Tachográf korongot kell generálnom kódból. A dolog jellegéből fakadóan körcikkek rajzolgatásával terveztem megoldani a feladatot: vettem egy üres tachográf korongot, elkértem belőle a Graphics-ot, amire DrawArc-okat hivogattam. Szépen működött a tesztfázisban: generáltam hozzá sebesség-idő grafikont és kirajzolta.

Na, de aztán kipróbáltuk éles adatokkal... Kiderült, hogy néhány ezer időpont-sebesség pontpár jut egy napra, szemben a teszidőszakban általam generált kb. hússzal. Először arra gondoltam, hogy tuti lassú lesz. Aztán ez nem derült ki, mert a rajzoló kódrészlet OutOfMemoryException-t dobott a DrawArc soron!

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.OutOfMemoryException: Out of memory.
   at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
   at System.Drawing.Graphics.DrawArc(Pen pen, Single x, Single y, Single width, Single height, Single startAngle, Single sweepAngle)

Meggoogléztam, mások is belefutottak már a jelenségbe, viszont sehol sem találtam rá megoldást. Legjobb esetben is azt írta a válaszoló, hogy nem sikerült a hibát reprodukálnia.

Azt azért a fenti linkeken is megfigyelték, hogy a jelenség nem a sok rajzolandó körcikktől van, hanem attól, hogy túl kis szöget próbáltunk a DrawArc-kal kirajzoltatni! Tetszikérteni.

Arra gondoltam, hogy ha túl kicsi a körcikk, akkor jól közelíthető egyenessel. Szemre Tudományosan megállapítottam, hogy 1 fok az a kritikus határ, ami fölött a DrawArc sem száll el, és aminél kisebb szögek esetén nem megkülönböztethető, hogy az inkriminált vonalat DawArc-kal, vagy DrawLine-nal húzták-e.

Jó, akkor tehát annyi dolgom van, hogy a körcikk teljes körét befoglaló négyzetből, a startAngle és sweepAngle szögekből kiszámolom, hogy hol a körcikk eleje (x0,y0) és vége (x1,y1) és rajzolok helyette vonalat:

float x0 = ( float ) Math.Cos( startAngle / 180.0 * Math.PI ) * r + CenterX;
float y0 = ( float ) Math.Sin( startAngle / 180.0 * Math.PI ) * r + CenterY;
float x1 = ( float ) Math.Cos( ( startAngle + sweepAngle ) / 180.0 * Math.PI ) * r + CenterX;
float y1 = ( float ) Math.Sin( ( startAngle + sweepAngle ) / 180.0 * Math.PI ) * r + CenterY;

// erre csak azert van szukseg, mert a DrawArc elszallhat kis szogekre...
if( sweepAngle > 1 )
    g.DrawArc( pen, CenterX - r, CenterY - r, 2 * r, 2 * r, startAngle, sweepAngle );
else
    g.DrawLine( pen, x0, y0, x1, y1 );

tachograf-reszlet

Úgy tűnik a módszer kielégítő, egész jóképű tachográfokat tudok így rajzolni.



Dávid Zoltán

Dávid Zoltán Mérnök Informatikusként végeztem a BME-n, jelenleg webfejlesztéssel és gépi tanulással foglalkozom.

2008.01.22. 10:54:02 | Permalink | Hozzászólások: 0 | Tárgyszavak: ,


  • Activation Error: Code 0x8007232b

    Balássy György (MS RD, ASP.NET MVP, MCTS) Épp egy Windows Server 2008 VPC-t telepítek és aktiválás közben az alábbi sokat mondó hibaüzenetet kaptam. Tovább »
  • XAMPP futtatása IIS mellett, Windows 7-en

    Dávid Zoltán Van egy kiváló Apache-PHP-MySql futtatókörnyezet Windowsra: a XAMPP. Azért tetszik, mert xcopy-val másolható, nem kell telepíteni és egy mappában ellakik az egész. Csak elindítom, és indulhat a PHP fejlesztés. A régi XP-s gépeimen, ahol nincs IIS telepítve problémamentes volt a használat. A nagy gépemen viszont az Apache nem indult el, mert a 80-as portot már fogta az IIS. Tovább »


Írja meg Ön is véleményét!


Hozzászólásokat csak regisztrált, bejelentkezett felhasználóktól tudunk elfogadni!

Hozzászólások