Download LinesCurvesFills

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Engineering drawing wikipedia , lookup

Line (geometry) wikipedia , lookup

Technical drawing wikipedia , lookup

Transcript
Lines, Curves, and Area Fill
Jim Fawcett
CSE778 – Advanced Windows Programming
Based on (unknown) student presentation
Lines, Curves and Area Fills
Computer Graphics are divided into 2 categories:
Vector Graphics – Lines, Curves and Areas I.e. Applications of analytical
geometry.

Raster Graphics – Bitmaps and Real World Images
We will be doing Vector Graphics as implemented in Windows Form's GDI+
Most Functions are implemented by the Graphics Object and use device
independent tools called Pens and Brushes !!
You cannot instantiate a graphics object and you cannot derive from a
graphics object !!!
How to get a graphics object !!!




When you override the OnPaint method you get the Graphics object
as a property of the PaintEventArgs which is an argument of the
Onpaint function which looks like this…..
Outside of the OnPaint method using the CreateGraphics Method.
Usually this is called in classes constructor to obtain information and
initialization. However, you should also call the Dispose() method of
the graphics method….
When you override the PrintPage method you get the Graphics
object as a property of the PrintPageEventArgs which is also an
argument. It looks like…
“owner draw” feature of some custom controls. For eg The
DrawItem event ‘s handler function has as an argument the
DrawItemEventArgs,which like above has the graphics object.
How to get a graphics object !!! (2)



To draw on a bitmap or metafile, you need to obtain a graphics object
with the static method Graphics.FromImage
If you need to obtain info about the Graphics object without actually
printing, you can use CreateMeasurementGraphics of the
PrinterSettings class.
If you are interfacing with Win32 code, you can use the static method
Graphics.FromHwnd and Graphics.FromHdc to obtain a graphics object.
The Tools – Pens and Brushes

Pens – just like the a real-world pen. The pen’s tip’s thickness and
the tip’s color determines the thickness and the color of the line on
paper.
Pen pen = new Pen(color); where color is an object of class Color
The Pens class has 141 static read-only properties that return objects
of the Pen class. Hence Pens.HotPink really returns a Pen Object.
The SystemPens classes’ static properties also return objects of type
Pen. The other constructor of Pen is Pen(Color c, float width).
For e.g., SystemPens.GrayText returns an object of type Pen.
The first argument to all the Draw methods is a Pen.
The Tools – Pens and Brushes (2)

Brushes:- When you “draw” text or “fill” areas with color, you use a
Brush. The Brush class is absract in that you cannot create instances
of type Brush,but you can create instances of 5 derived classes namely
SolidBrush,HatchBrush,TextureBrush, LinearGradientBrush
and PathGradientBrush.
eg. Brush brush = new SolidBrush(color) where color is of type Color.
The Brushes class has static properties which return objects of type
Brush. E.g.- Brushes.AliceBlue returns an object of type Brush.
The first argument to all the Fill methods is a Brush.
Drawing Basic Lines
Use the DrawLine Method of the Graphics class to draw straight Lines
Void
Void
Void
Void
DrawLine(Pen
DrawLine(Pen
DrawLine(Pen
DrawLine(Pen
pen, int x1, int y1, int x2, int y2);
pen, float x1, float y1, float x2, float y2);
pen, Point p1, Point p2);
pen,PointF p1, PointF p2);
Unlike Win32 GDI drawing, the DrawLine method draws a line from
the first point including the second point (in Win32 GDI, it’s up to but
not including the second point)
The program to draw a line across the screen is like…. And it’s screen
shot is on the next slide.
Snapshot
A little more on the GDI+ ……
The GDI+ is “stateless”….
Usually, a graphics system keeps a track of the “current point”. Then
a new line can be simply drawn to the “new point” with say a
MoveTo(…) function call. The “new” point now becomes the
“current point”. But in GDI+, this is NOT so. Every new line has
to be drawn with 2 points (there is no MoveTo function).
Also, DrawLine and DrawString calls (unlike Win32 GDI) include
arguments that specify font, brush and pen (in Win32 GDI, font,
brush & pen would be part of the Graphics object) However, GDI+
does have minimal state.
The Graphics Object has 12 read/write properties + 6 read-only
properties.
A little more on the GDI+ …… (2)
Four Important properties are :



PageScale and PageUnit determine the Units used for drawing. The
default is pixels.
The Transform Property is an object of type Matrix that defines a
matrix transform of all graphics output. It translates, scales, shears
and rotates co-ordinate points.
‘Clip’ is a clipping rectangular region in which the output of drawing
functions is limited (as against the entire drawing region).
Anti-Aliasing and smooth lines…..
A line “blown up”
A line “blown up”
after anti-aliasing…
Anti-Aliasing and smooth lines….. (2)
Anti-aliasing reduces sharp jagged edges of lines so they appear
smoother. You have two Enumerations of the graphics Class that
are SmoothingMode and PixelOffsetMode that you set so as to
smoothen up lines… (Click here for the list…..)
………………………………….
protected override void OnPaint(PaintEventArgs pea) {
Graphics g = pea.Graphics;
Pen pen = new Pen(ForeColor);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.DrawLine(pen,2,2,18,10);
}
Multiple Connected Lines & Curves

As mentioned previously, CGI+ does not keep a track of the “current
point” so drawing a rectangle with “DrawLine” is painful, as the end
point of the first line will be again have to be repeated as the starting
point of the next line.
We use “DrawLines” instead to draw multiple connected lines. The
format is :void DrawLines(Pen pen, Point[] apt);
void DrawLines(Pen pen, PointF[] apt); where Point[] is an
array of Point Objects.
NOTE: The Point[] array for a rectangle to be drawn will have 5
points, the fifth one being the same as the original point.
Use “DrawLines” for Curves…
It’s a performance issue… The real use of “DrawLines” is to really
draw curves, not straight lines. If the individual lines are very small and
there are hundreds, even thousands of them, then we can draw curves
very well. Click here for the SineCurve Program whose output would
look like…
Curves and Parametric Equations
Calculation “y” points for a range of “x” values (in the sinewave case) is
relatively straightforward. However the equation for circle is:
x2 + y2 = r2 where “r” is the radius of the circle.
and the equation of “y” in terms of “x” then becomes:
y = ± (r2-x2)1/2



This has the following problems though:
There are two values of y for every value of x
X must range between –r and r
There are problems of resolution
When x is around 0, changes of x produce small changes in y
When x approaches r or –r, changes in x produce much greater changes in y
Curves and Parametric Equations (2)
We define both variables of x and y in terms of a third parameter
called “t” and then you range the parameter “t” appropriately.
The parametric equations for a circle are:
x(t) = Rcos(t) , y(t) = Rsin(t). T then ranges from 0 - 2∏
The parametric equations for an ellipse are:
x(t) = CX + RX cos(t)
y(t) = CX + RX sin(t) where the horizontal axis is 2 x RX and the
vertical axis is 2 x RY. Here, (CX,CY) is the center of the ellipse.
The code for the drawing en ellipse with parametric equations is
here… and the screen shot is on the next slide.
Curves and Parametric Equations (3)
“DrawRectangle” and
“DrawRectangles”
“DrawRectangle” Draws a rectangle. There are 3 versions:
void DrawRectangle(Pen pen, int x, int y, int cx, int cy);
void DrawRectangle(Pen pen,float x, float y, float cx, float cy);
void DrawRectangle(Pen pen,Rectangle rect);
There is no version of the method with “RectangleF”
“DrawRectangles” draws many rectangles specified in an array:
Void DrawRectangles (Pen pen, Rectangle[] arect);
Void DrawRectangles (Pen pen, RectangleF arectf);
“DrawRectangle” “Off by 1” error
Generalized Polygons and Ellipses
The methods for drawing a polygon are as under:void DrawPolygon(Pen pen Point[] pt);
void DrawPolygon(Pen pen, PointF[] pt);
Unlike the DrawLines(…) method, you only have to specify 4 points in the array (as against
5 for the DrawLines method) as the line from “Point 4” back to “Point 1” will be
automatically drawn, thus “closing” the rectangle.
The methods to draw ellipses are as under:void DrawEllipse(Pen pen, int x, int y, int cx, int cy);
void DrawEllipse(Pen pen,float x. float y, float cx, float cy);
void DrawEllipse(Pen pen, Rectangle r);
void DrawEllipse(Pen pen, RectangleF rectf);
NOTE: The “Off by 1” rule for “DrawRectangle” should also be followed here.
Arcs and Pies
An arc is a segment of an ellipse – with a “starting angle” and it’s “sweep”
I.e. how much portion of the ellipse should the arc keep going…both above
quantities measured in angles…
The DrawArc methods are:
void DrawArc(Pen
void DrawArc(Pen
void DrawArc(Pen
void DrawArc(Pen
Please Note:
pen,int x, int y, int cx, int cy, int iAngleStart, int iAngleSweep);
pen,int x, float y, float cx, float cy, float iAngleStart, float iAngleSweep);
pen,R21ectangle rect, float iAngleStart, float iAngleSweep);
pen,RectangleF rect, float iAngleStart, float iAngleSweep);
Negative Angles
Positive Angles
Arcs and Pies (2)
The code to draw a “dashed ellipse” is here… and it’s snapshot is…
Arcs and Pies (3)
A “slice of pie” can be considered to be an arc with lines connecting
the endpoints of the ellipse to the center of the ellipse.
The methods are as under….
void
void
void
void
DrawPie(Pen pen,int x, int y, int cx, int cy, int iAngleStart, int iAngleSweep);
DrawPie (Pen pen,int x, float y, float cx, float cy, float iAngleStart, float iAngleSweep);
DrawPie (Pen pen,Rectangle rect, float iAngleStart, float iAngleSweep);
DrawPie (Pen pen,RectangleF rect, float iAngleStart, float iAngleSweep);
The code for the pie chart drawn is here…
NOTE, in the code that…..
The int[] aiValues contain the quantities to be plotted as “pie slices”.
and that fSweep = 360f * (current data val)/(Sum of values) This is used as the
next incremental angle for the next “slice” to be drawn in the loop.
Arcs and Pies (4) - Snapshot
Area Fills - Rectangles
For area fills, we need the bounds of the area AND an object of type
Brush.
To fill a rectangle with a color, we use the following methods:void FillRectangle(Brush b, int x, int y, int cx, int cy);
void FillRectangle(Brush b, float x, float y, float cx, float cy);
void FillRectangle(Brush b, Rectangle rect);
void FillRectangle(Brush b, RectangleF rectf);
NOTE: With FillRectangle, there’s no “Off by 1” error. The width & height of the resulting
rectangle is equal to the width & height passed in as parameters to this function.
There are also the “FillRectangles” methods for an array of rectangles:
void FillRectangles(Brush b, Rectangle[] arect);
void FillRectangles(Brush b,RectangleF[] arect);
Calling “FillRectangles” is like multiple calls to “FillRectangle”
Area Fills (2) - Ellipses
The methods for filling an Ellipse are :void
void
void
void
FillEllipse(Brush b, int x, int y, int cx, int cy);
FillEllipse (Brush b, float x, float y, float cx, float cy);
FillEllipse (Brush b, Rectangle rect);
FillEllipse (Brush b, RectangleF rectf);
FillEllipse’s “Off-by one” error is the reverse !!! The effective width
and height of the figure is one less than those specified as arguments.
The methods for “filling a pie” are as under:
void FillPie(Brush b, int x, int y, int cx, int cy, int iAngleStart, int iAngleSweep);
void FillPie (Pen pen, int x, float y, float cx, float cy, float fAngle, float fSweep);
void FillPie (Pen pen,Rectangle rect, float fAngle, float fSweep);
Polygons and the Filling Mode
We use the following methods to fill a generalized Polygon:void
void
void
void
FillPolygon(Brush b,
FillPolygon(Brush b,
FillPolygon(Brush b,
FillPolygon(Brush b,
Point[] apt);
PointF[] apt);
Point[] apt, FillMode fm);
PointF[] apt, FillMode fm);
Polygons are different because the points in a polygon can overlap
and cross…..
Polygons and the Filling Mode (2)
The “FillMode” parameter is an enumeration of the
System.Drawing.Drawing2D namespace and has 2 values:
Member
Value
Comments
--------------------------------------------------------------------------------------------Alternate
0
Default: Alternate Filled & Unfilled
Winding
1
Most Interior areas filled
--------------------------------------------------------------------------------------------Only when the lines overlap does the FillMode make a difference.
“Alternate” means that the area is filled only if there are an odd number of boundaries
between the enclosed area and infinity. Draw a line from a point in the enclosed area and
extend it to infinity in any direction. If the line crosses an odd number of boundary
surfaces, It gets filled or else not. With the “winding” mode, it’s the same for the odd
lines, however, if the number of boundaries that the imaginary line drawn crosses, the area
is filled only if the number of lines going in one direction(relative to the imaginary line
drawn) are not equal to the number of lines in the other direction…
Polygons and the Filling Mode (3)
The program for drawing a classical 5-point star is as shown with the
“alternate” mode used (left star) and the “winding” mode used
(right star) is here… and it looks like:
End of Presentation