# 如何画斜的椭圆啊

bbs008 2005-09-22 01:16:16

...全文
648 点赞 收藏 8

8 条回复

handwolf 2005-09-23
http://blog.csdn.net/handwolf/archive/2005/04/11/343546.aspx

yayafu 2005-09-23
// 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)

// 把椭圆映射为贝塞尔曲线的常量 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

// 在Y轴正方向向上时，使用下面一行

// 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

// LDPoint是一个和CPoint相当的类型，不过它还具有浮点精度。

void Rotate(double radians, const CPoint& c, CPoint* vCtlPt, unsigned Cnt)

{

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

// 旋转

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);

//

//或者 FillPath();

//或者StrokeAndFillPath();

//或者PathToRegion(dc.m_hDC);

ignoramuspp 2005-09-22

.h

struct LDPoint {
double x;
double y;
};

.cpp
//3个主要函数

void CColorTestView::EllipeseToBezier(CRect& r ,CPoint* cCtlPt)
{
const double EToBConst = 0.2761423749154;
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 =
cCtlPt[12].x = r.left;
cCtlPt[5].x =
cCtlPt[6].x =
cCtlPt[7].x = r.right;
cCtlPt[2].x =
cCtlPt[10].x = centre.x - offset.cx;
cCtlPt[4].x =
cCtlPt[8].x = centre.x + offset.cx;
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;

}
void CColorTestView::Rotate(double radians,const CPoint& c ,CPoint* vCtrlPt,unsigned Cnt)
{
LDPoint constTerm;
constTerm.x = c.x - c.x*cosAng - c.y *sinAng;
constTerm.y = c.y + c.x *sinAng - c.y*cosAng;
for(int i =Cnt -1 ;i>=0;--i)
{
double a = vCtrlPt[i].x*cosAng + vCtrlPt[i].y *sinAng + constTerm.x;
double b = -vCtrlPt[i].x *sinAng + vCtrlPt[i].y*cosAng + constTerm.y;
int a1 = a;
int b1 = b;
vCtrlPt[i] .x = a1;
vCtrlPt[i] .y = b1;
}
}

//点击事件触发绘制有角度的椭圆
void CColorTestView::OnOK()
{
CClientDC dc(this);
CBrush myBrush;
CPoint point[13];
CPoint po(100,100);
myBrush.CreateSolidBrush(RGB(0,0,255));
CRect rect(100,100,200,150);
//定义路径画贝塞尔曲线
dc.BeginPath();
EllipeseToBezier(rect,point);
Rotate(3.14/6,po,point,13);
dc.PolyBezier(point,13);
dc.EndPath();

dc.StrokePath();
}

ignoramuspp 2005-09-22

http://www.vchelp.net/itbookreview/view_paper.asp?paper_id=885

DentistryDoctor 2005-09-22

legendhui 2005-09-22
ms-help://MS.MSDNQTR.2003FEB.2052/gdi/cordspac_0jg3.htm

saliors 2005-09-22

http://www.goalercn.com/html/article/3879f0b0cf2d5ac95ab6.html

ming6424 2005-09-22

1.5w+

VC/MFC 界面

2005-09-22 01:16