转动的椭圆,看起来像原子符号。如果是三个的话是以前央视标志

    技术2022-05-11  151

    Rotated EllipsesDecember 2005There is no native Windows function to draw ellipses at rotated angles, so every programmer has to do the drawing themselves. It took me a while to find some decent code on the internet. However, I did find this excellent C++ code which I've used as the basis of my Delphi code below. The codeguru site linked to above also has a good summary of other ways to draw ellipses so I wont repeat here what was said there.The rotated ellipse is constructed by a series of 4 bezier curves. Although not demonstrated in the code below, a reasonable approximation of bounding rectangle of the ellipse (aligned with the x-y axis) can be derived by finding both the minimum and maximum values for x and y from the 13 points used to define the bezier curves. Anyhow, here's my Delphi function to draw rotated ellipses. The calling function Button1Click() also demonstrates how to assign a record constant, something newcomers to Delphi may not be aware is possible. Code snippet ... uses Math; procedure RotatePts(var pts: array of TPoint; origin: TPoint; radians: single); var i,x,y: integer; cosAng, sinAng: single; begin cosAng := cos(radians); sinAng := sin(radians); for i := low(pts) to high(pts) do begin x := pts[i].X - origin.X; y := pts[i].Y - origin.Y; pts[i].X := round((x * cosAng) - (y * sinAng)) + origin.X; pts[i].Y := round((x * sinAng) + (y * cosAng)) + origin.Y; end; end; //-------------------------------------------------------------- //see - http://www.codeguru.com/Cpp/G-M/gdi/article.php/c131 procedure DrawRotatedEllipse(canvas: TCanvas; rec: TRect; degrees: integer); const //Magic constant = 2/3*(sqrt(2)-1) offset: single = 0.27614237; var midx, midy, offx, offy: integer; pts: array [0..12] of TPoint; radians: single; begin degrees := degrees mod 360; if degrees < 0 then inc(degrees, 360); radians := degrees *pi / 180; //if there's no rotation, use the standard Windows function if radians = 0 then canvas.Ellipse(rec) else begin with rec do begin dec(right); dec(bottom); //empirically this seems better midx := (right + left) div 2; midy := (bottom + top) div 2; offx := round((right - left) * offset); offy := round((bottom - top) * offset); pts[0] := Point(left, midy); pts[1] := Point(left, midy - offy); pts[2] := Point(midx - offx, top); pts[3] := Point(midx, top); pts[4] := Point(midx + offx, top); pts[5] := Point(right, midy - offy); pts[6] := Point(right, midy); pts[7] := Point(right, midy + offy); pts[8] := Point(midx + offx, bottom); pts[9] := Point(midx, bottom); pts[10] := Point(midx - offx, bottom); pts[11] := Point(left, midy + offy); pts[12] := pts[0]; //rotate all points about the ellipse center ... RotatePts(pts, Point(midx,midy), radians); end; with canvas do begin beginPath(Handle); canvas.PolyBezier(pts); EndPath(Handle); if canvas.Brush.Style = bsClear then StrokePath(Handle) else StrokeAndFillPath(Handle); end; end; end; //-------------------------------------------------------------- procedure TForm1.Button1Click(Sender: TObject); const rec: TRect = (left:100; top:100; right:300; bottom:200); begin canvas.Pen.Width := 2; canvas.Brush.Color := clWhite; DrawRotatedEllipse(Canvas, rec, 0); //now overlay the same sized ellipse, //but rotated at several angles ... canvas.Brush.Style := bsClear; DrawRotatedEllipse(Canvas, rec, -45); DrawRotatedEllipse(Canvas, rec, 45); DrawRotatedEllipse(Canvas, rec, 90); end;

    最新回复(0)