So, I had a task to create a graph in code
Not an easy task at you can see. It took me about 12 hours to get it done from scratch. My class takes the following parameters: 4 values – one for each color and bitmap size (width and height).
Here are some code samples:
Create a bitmap
Bitmap returnValue = new Bitmap(width, height);
Draw axes:
private static void DrawAxes(Bitmap result)
{
Pen axesPen = new Pen(Color.Black, 1);
Graphics worker = Graphics.FromImage(result);
worker.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// draw diagonal axis lines
worker.DrawLine(axesPen, GetTopLeftCorner(result), GetBottomRightCorner(result));
To draw red color polygon:
PointF[] coordinates = new PointF[] {
GetRedCorner(result, red),
redYellowIntersect,
middle,
greenRedIntersect};
worker.DrawLine(graphPen, redYellowIntersect, GetRedCorner(result, red));
worker.DrawLine(graphPen, greenRedIntersect, GetRedCorner(result, red));
worker.FillPolygon(redBrush, coordinates);
One fun part was to write a code to determine where two lines intersect. Here is entire function:
/// <summary>
/// Find a point at which two lines intersect
/// </summary>
/// <param name="line1">First line</param>
/// <param name="line2">Second line</param>
/// <param name="middle">Coordinates of the middle of the bitmap</param>
/// <param name="intersectionType">Does this intersect cross x or y axis</param>
/// <returns></returns>
private static PointF LinesIntersect(Line line1, Line line2, PointF middle, IntersectType intersectionType)
{
PointF returnValue = new PointF();
float a1, a2, b1, b2;
if (line1.End.X == line1.Start.X)
b1 = (line1.End.Y – line1.Start.Y);
else
b1 = (line1.End.Y – line1.Start.Y) / (line1.End.X – line1.Start.X);
if (line2.End.X == line2.Start.X)
b2 = (line2.End.Y – line2.Start.Y);
else
b2 = (line2.End.Y – line2.Start.Y) / (line2.End.X – line2.Start.X);
a1 = line1.Start.Y – b1 * line1.Start.X;
a2 = line2.Start.Y – b2 * line2.Start.X;
returnValue.X = -(a1 – a2) / (b1 – b2);
returnValue.Y = a1 + b1 * returnValue.X;
switch (intersectionType)
{
case IntersectType.Horizontal:
returnValue.Y = middle.Y;
break;
case IntersectType.Vertical:
returnValue.X = middle.X;
break;
default:
throw new Exception("Invalid type");
}
return returnValue;
}
Here are internal classes used in it:
/// <summary> /// Definition for a line - start and end points /// </summary> private struct Line { public PointF Start; public PointF End; public Line(PointF start, PointF end) { Start = start; End = end; } } /// <summary> /// Type of intersection - does cross y or x axis /// </summary> private enum IntersectType { Horizontal, Vertical }