Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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