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 );

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