CodeGuru
Earthweb Search
Forums Wireless Jars Gamelan Developer.com
CodeGuru Navigation
Member Sign In
User ID:
Password:
Remember Me:
Forgot Password?
Not a member?
Click here for more information and to register.

jobs.internet.com

internet.commerce
Partners & Affiliates
Promos and Premiums
GPS
Server Racks
Dental Insurance
Disney World Tickets
Web Design
Shop Online
Laptops
Phone Cards
Promotional Golf
KVM Switches
Online Shopping
Calling Cards
Desktop Computers


RSS Feeds

RSSAll

RSSVC++/C++

RSS.NET/C#

RSSVB

See more EarthWeb Network feeds

Home >> Visual C++ / C++ >> Graphics & Multimedia >> GDI

Best Practices for Developing a Web Site. Checklists, Tips, Strategies & More. Download Exclusive eBook Now.

Drawing Rotated and Skewed Ellipses
Rating:

Llew Goodstadt (view profile)
December 6, 1998


(continued)

Get FREE Intel Mobility Resources!
WHITEPAPER:
Increase Performance, Security with Intel Centrino Pro Processor Technology
Get 2x performance on your notebooks, with innovative power-saving features designed to extend battery life.

ROI ESTIMATOR:
Intel vPro Technology

WHITEPAPER:
Reduce Maintenance Costs While Increasing Notebook Security



Turbo Screen Sharing
Adobe Acrobat Connect Professional offers users the ability to have a more productive and engaging web conferencing experience while providing the IT department with a program that efficiently utilizes bandwidth and minimally impacts the infrastructure. Learn More! »

Informal Learning: Extending the Impact of Enterprise Ideas and Information
Forward-thinking organizations are turning to enterprise learning in their quest to be better informed, better skilled, better supported at the point of need, and more competitive in their respective marketplaces. Learn More! »

Rapid E-Learning: Maturing Technology Brings Balance and Possibilities
Rapid e-learning addresses both time and cost issues by using technology tools to shift the dynamics of e-learning development. Learn why more skilled learning professionals use these tools and how you can get a solution to keep pace with your business demands. »

Delivering on the Promise of ELearning
This white paper defines the framework to launch e-learning as a set of teaching, training, and learning practices not bound by a specific technology platform or learning management system. It offers practical suggestions for creating digital learning experiences that engage learners by building interest and motivation and providing opportunities for active participation. »

Introduction

Rectangles, Rounded Rectangles and Ellipses in Windows can only be drawn by GDI as axis-aligned figures. If one wishes to draw rotated or skewed figures under Windows NT, one can use World Transforms but they are unfortunately not available under Windows 95/98. For a cross-platform solution, one needs to do more of the work oneself. Rectangles can be simulated trivially using polygons with four vertices, which can then be rotated or skewed. However, what is one do for ellipses? There are basically three choices:

Alternatives

  • Use a custom function to draw the ellipse.

    The mathematics for ellipses are relatively simple and there are modified Bresenham equations for rotated ellipses in standard texts. However, this means that one must perform the rasterization oneself, which can get complicated for thick lines. This amount of effort is probably only worthwhile if one is already drawing to an off-screen surface (e.g. DirectDraw) or a bitmap.

  • Drawing ellipses as connected line segments.

    The actual lines can be drawn via LineTo(...) or Polyline(...) GDI calls. One can perform the approximation of the ellipses oneself or take advantage of the GDI FlattenPath(...) function.

  • Use cubic bezier curves to approximate ellipses.

    This is the method illustrated here.

Drawing ellipses as connected bezier curves

Using just four bezier curves, each representing 90 degrees of the original axis-aligned ellipse, one can arrive at a fair approximation with a maximum error of just 0.027%. This is equivalent to a maximum error of less than one pixel for ellipses with radii up to 3700, more than enough accuracy for our purposes.

Advantages

  1. Simplicity.

    Only four GDI calls are needed. The calculations of the bezier control points are trivial.

  2. Speed.

    One can take advantage of hardware support of curve drawing on newer video cards. On my system, this is as fast as, if not faster than, GDI calls to Ellipse(...)

  3. Transformations.

    Because bezier curves are invariant under rotation, scaling and translation, one only needs to transform the control points to apply the same transformations to one's ellipse. More precisely, since each point on a cubic bezier curve is a barycentric combination of the control points, the relationship of the curve to the control points is not changed under affine maps.

  4. Device independence.

    If one is converting ellipses to line segments or rasterizing oneself, each time the resolution of one's surfaces or device context changes (for example when drawing to a printer DC), one must re-rasterize. This is not necessary with bezier curves. An additional advantage is that the ellipses can be exported via metafiles to drawing programmes such as CORELDRAW, which can then scale the figures without gross distortions or artefacts.

Procedure

First start off with a rectangle bounding an axis aligned ellipse (as in a normal GDI call). The thirteen bezier control points (labelled 0-12 below) defining the four bezier curves making up the ellipse can be calculated easily using an empirically derived "magical constant". The following code produces the control points for mapping modes where +ve Y is downwards (e.g. MM_TEXT). Where the opposite is true, just have a negative y value for the offset variable as indicated in the comments.

    // Create points to simulate ellipse using beziers void EllipseToBezier(CRect& r, CPoint* cCtlPt) { // MAGICAL CONSTANT to map ellipse to beziers // 2/3*(sqrt(2)-1) const double EToBConst = 0.2761423749154; CSize offset((int)(r.Width() * EToBConst), (int)(r.Height() * EToBConst)); // Use the following line instead for mapping systems where +ve Y is upwards // CSize offset((int)(r.Width() * EToBConst), -(int)(r.Height() * EToBConst)); CPoint centre((r.left + r.right) / 2, (r.top + r.bottom) / 2); cCtlPt[0].x = //------------------------/ cCtlPt[1].x = // / cCtlPt[11].x = // 2___3___4 / cCtlPt[12].x = r.left; // 1 5 / cCtlPt[5].x = // | | / cCtlPt[6].x = // | | / cCtlPt[7].x = r.right; // 0,12 6 / cCtlPt[2].x = // | | / cCtlPt[10].x = centre.x - offset.cx; // | | / cCtlPt[4].x = // 11 7 / cCtlPt[8].x = centre.x + offset.cx; // 10___9___8 / cCtlPt[3].x = // / cCtlPt[9].x = centre.x; //------------------------* cCtlPt[2].y = cCtlPt[3].y = cCtlPt[4].y = r.top; cCtlPt[8].y = cCtlPt[9].y = cCtlPt[10].y = r.bottom; cCtlPt[7].y = cCtlPt[11].y = centre.y + offset.cy; cCtlPt[1].y = cCtlPt[5].y = centre.y - offset.cy; cCtlPt[0].y = cCtlPt[12].y = cCtlPt[6].y = centre.y; }
Rotation of the Ellipse can be accomplished using code similar to:
    // LDPoint is an equivalent type to CPoint but with floating point precision void Rotate(double radians, const CPoint& c, CPoint* vCtlPt, unsigned Cnt) { double sinAng = sin(radians); double cosAng = cos(radians); LDPoint constTerm( c.x - c.x * cosAng - c.y * sinAng, c.y + c.x * sinAng - c.y * cosAng); for (int i = Cnt-1; i>=0; --i) { vCtlPt[i] = (LDPoint( vCtlPt[i].x * cosAng + vCtlPt[i].y * sinAng, -vCtlPt[i].x * sinAng + vCtlPt[i].y * cosAng) + constTerm).GetCPoint(); } } // Create Ellipse CRect rect; GetClientRect(&rect); CPoint ellipsePts[13]; EllipseToBezier(ellipseR, ellipsePts); // Rotate Rotate(m_Radians, midPoint, ellipsePts, 13);

Filled Ellipses

Of course, four bezier curves together only make up the outline of an ellipse, whether rotated or not. Thankfully, Win32 Path functions are there for filled ellipses. One only needs to enclose the PolyBezier(...) call in a Path Bracket. The resulting path can be stroked and filled to one's satisfaction. If one is feeling adventurous, further special fills like gradients, custom bitmaps or fractals etc. can be achieved by first setting the clipping region to the path via SelectClipPath(...).

    dc.BeginPath(); dc.PolyBezier(ellipsePts); dc.EndPath(); dc.StrokePath; // or FillPath(); // or StrokeAndFillPath(); // or PathToRegion(dc.m_hDC);

Thick Dashed or Dotted Ellipses Outlines under Win95/8

Win95/8 only supports solid thick lines. However, dashed or dotted ellipse outlines can easily be simulated with a series of bezier segments.

Tools:
Add www.codeguru.com to your favorites
Add www.codeguru.com to your browser search box
IE 7 | Firefox 2.0 | Firefox 1.5.x
Receive news via our XML/RSS feed

Improve How You Manage Information: Becoming a Better Project Manager. Exclusive eBook - Download Now.
Is it time to make your move to the multi-threaded and parallel processing world? Find out!
Becoming a Better Project Manager. Checklists, Tips & Strategies. Download Exclusive eBook Now.
Best Practices for Developing a Web Site. Checklists, Tips & Strategies. Download Exclusive eBook Now.
Guide to Developing a Web Site. Best Practices, Tips and Strategies. Download Exclusive eBook Now.


RATE THIS ARTICLE:   Excellent  Very Good  Average  Below Average  Poor  

(You must be signed in to rank an article. Not a member? Click here to register)

Latest Comments:
How can I find a intersection - marenko (08/12/2004)
Drawing rotated and skewed ellipses - Legacy CodeGuru (01/04/2004)
GDI resource leak.... - Legacy CodeGuru (06/30/2003)
How to use the code?Any exmaple? - Legacy CodeGuru (06/05/2003)
http://www.ucancode.net - Legacy CodeGuru (03/23/2003)

View All Comments
Add a Comment:
Title:
Comment:
Pre-Formatted: Check this if you want the text to display with the formatting as typed (good for source code)



(You must be signed in to comment on an article. Not a member? Click here to register)


JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers