如何画斜的椭圆啊

bbs008 2005-09-22 01:16:16
如何画斜的椭圆啊,一般矩形内切圆都是水平的。
...全文
648 点赞 收藏 8
写回复
8 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
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)

{

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(...).

填充椭圆

当然,无论是不是旋转,四条贝塞尔曲线只完成了椭圆的轮廓。幸运的是,Win32路径功能可用于填充椭圆。你只在需要调用PolyBezier(...)来封闭路径。完成的路径是一笔画出的,而且能被让人满意的填充。假如有人觉得还不够,比如更特殊的填充,比如斜线、用户位图或不规则碎片等。这些能由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个主要函数
定义12个基准点给12个点附值
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;


}
//按照角度 radians 旋转12个基准点
void CColorTestView::Rotate(double radians,const CPoint& c ,CPoint* vCtrlPt,unsigned Cnt)
{
double sinAng = sin(radians);
double cosAng = cos(radians);
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
如果用GDI那么只能画点了,如果是GDI+,那么就可以用矩阵转换。直接将画好的椭圆旋转所需要的角度就可以了。
回复
legendhui 2005-09-22
ms-help://MS.MSDNQTR.2003FEB.2052/gdi/cordspac_0jg3.htm
看看MSDN中几种坐标系的转换
回复
saliors 2005-09-22
这篇文章有怎么画斜的椭圆。
http://www.goalercn.com/html/article/3879f0b0cf2d5ac95ab6.html
回复
ming6424 2005-09-22
算出椭圆的边界上的每个点的座标再画啊
回复
相关推荐
发帖
界面
创建于2007-09-28

1.5w+

社区成员

VC/MFC 界面
申请成为版主
帖子事件
创建了帖子
2005-09-22 01:16
社区公告
暂无公告