使用C++求出中心不在原点的矩形内接椭圆

最近在项目中解决问题时,有一个地方需要求得一个椭圆上的一组点。

已知是椭圆的外接矩形,求一组点。

解决思路:

  • 了解标准椭圆方程x^2/a^2+y^2/b^2=1,(a>b>0)
  • 在矩形范围内采样一组点x,自定义采样间隔
  • 根据采样点x,求得其对应的y值:y1,y2
  • 在picture control上画出来所有点,并连起来看效果。

不在原点的椭圆方程函数是:(x-x0)^2/a^2+(y-y0)^2/b^2=1,x0,y0是外接矩形的中心点。

从矩形左边界向右边界以自定义单位为间隔采样,我采样间隔是1,带入x,求得y

y1 = sqrt((abs((1-(x-x0)*(x-x0)/(a*a))*b*b))) + y0;

y2 = -sqrt((abs((1-(x-x0)*(x-x0)/(a*a))*b*b))) + y0;

abs其实没必要,因为在矩形内的点(x-x0)*(x-x0)/(a*a)肯定是<=1的。

求出所有的点后,然后在mfc picture control控件上画出来,并将每个点画出来看看效果。

效果图:

画椭圆的完整函数如下

void CPointInEllipseDlg::Draw()
{
	CRect rect;
	m_ellipse.GetClientRect(rect);

	double x0 =(rect.right + rect.left)/2;
	double y0 = (rect.top + rect.bottom)/2;

	double a = abs(rect.right - rect.left)/2;
	double b = abs(rect.top - rect.bottom)/2;
	multimap<double,double> point4,point5;
	int count=0;
	for(int x = rect.left;x<=rect.right;x++)
	{
		double y1 = sqrt((abs((1-(x-x0)*(x-x0)/(a*a))*b*b))) + y0;
		double y2 = -sqrt((abs((1-(x-x0)*(x-x0)/(a*a))*b*b))) + y0;
		point.insert(make_pair(x,y1));
		point.insert(make_pair(x,y2));
		count++;
		
	}
	CDC *pDC = m_ellipse.GetDC();
	CPen newPen,newPen2;
	newPen.CreatePen(PS_SOLID, 2, RGB(0,255,0));  
	pDC->SelectObject(&newPen);
	pDC->MoveTo(rect.left, rect.bottom/2);
	multimap<double,double> point1,point2,point3;

	for(auto pt = point.begin();pt!=point.end();pt++)
	{
//		AfxMessageBox("");
		if(pt->second >= y0)
			point1.insert(make_pair(pt->first,pt->second));
		else if(pt->second < y0)
			point2.insert(make_pair(pt->first,pt->second));
	}
	int ab=0;
	for(auto pt = point1.begin();pt!=point1.end();pt++)
	{
		ab++;
		pDC->LineTo(pt->first,pt->second);
		if(ab % 6 == 0)
		{
			COLORREF point_color = RGB(255, 0, 0);
			for (int j = -3; j <= 3; j++)
				for (int k = -3; k <= 3; k++)
			pDC->SetPixel(pt->first+j, pt->second+k, point_color);
		}
	vector<double> vp1,vp2;
	for(auto pt = point2.begin();pt!=point2.end();pt++)
	{
		vp1.insert(vp1.begin(),pt->first);
		vp2.insert(vp2.begin(),pt->second);
	}
	auto a1=vp1.begin();
	auto a2 = vp2.begin();
	for(;a1!=vp1.end();)
	{
		
		pDC->LineTo(*a1,*a2);
		ab++;
		if(ab % 6 == 0)
		{
			COLORREF point_color = RGB(255, 0, 0);
		for (int j = -3; j <= 3; j++)
			for (int k = -3; k <= 3; k++)
				pDC->SetPixel(*a1+j, *a2, point_color);
		}
		a1++;
		a2++;
	}
}

在项目中使用:

根据外接矩形求得的一组点,画出来后完美拟合椭圆,完工

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值