MFC有理二次Bezier曲线绘制

MFC有理二次Bezier曲线绘制


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
非有理Bezier曲线曲线无法精确表示所有的二次曲线和二次曲面,引入了有理Bezier曲线曲面,来精确表示。如图,通过控制权重,可以获取不同的二次有理Bezier曲线(蓝色线条),虚线为非有理Bezier曲线,作为对照。
理论与算法参考《计算几何算法与实现》–孔令德
代码实现如下:

#pragma once
#include"P2.h"
#include"math.h"

#define ROUND(h) int(h+0.5)
class RationalQuadraticBezier
{
public:
	RationalQuadraticBezier(void);
	~RationalQuadraticBezier(void);

	void ReadPoint(void);//赋值控制点
	CP2 point[3];//控制点数组
	void DrawCurve(CDC*pDC);//绘制曲线
	void DrawControlPoint(CDC*pDC);//绘制控制点
	void RationalCurve(CDC*pDC);
};
#include "StdAfx.h"
#include "RationalQuadraticBezier.h"


RationalQuadraticBezier::RationalQuadraticBezier(void)
{
	ReadPoint();
}


RationalQuadraticBezier::~RationalQuadraticBezier(void)
{
}

void RationalQuadraticBezier::ReadPoint(void)
{
	point[0].x=-200,point[0].y=-100;
	point[1].x=0,point[1].y=100;
	point[2].x=200,point[2].y=-100;
}


void RationalQuadraticBezier::DrawCurve(CDC*pDC)
{
	DrawControlPoint(pDC);//绘制控制点
	RationalCurve(pDC);//绘制有理二次Bezier样条
}


void RationalQuadraticBezier::DrawControlPoint(CDC*pDC)
{
	CPen NewPen,*pOldPen;//画笔
	NewPen.CreatePen(PS_SOLID,3,RGB(0,0,0));
	pOldPen=pDC->SelectObject(&NewPen);

	CBrush NewBrush,*pOldBrush;
	pOldBrush=(CBrush*)pDC->SelectStockObject(BLACK_BRUSH);//画刷
	pDC->MoveTo(ROUND(point[0].x),ROUND(point[0].y));
	for(int i=0;i<3;i++)
	{
		pDC->LineTo(ROUND(point[i].x),ROUND(point[i].y));
		pDC->Ellipse(ROUND(point[i].x)-5,ROUND(point[i].y)-5,ROUND(point[i].x)+5,ROUND(point[i].y)+5);
	}
	pDC->SelectObject(pOldBrush);
	pDC->SelectObject(pOldPen);
}


void RationalQuadraticBezier::RationalCurve(CDC*pDC)
{
	CPen NewPen,*pOldPen;
	NewPen.CreatePen(PS_SOLID,1,RGB(0,0,255));
	pOldPen=pDC->SelectObject(&NewPen);
	double Bern02,Bern12,Bern22;//定义伯恩斯坦基函数
	double weight0=1.0,weight2=1.0,weight1=-0.5;//权因子赋值
	double tStep=0.01;//绘制步长
	pDC->MoveTo(ROUND(point[0].x),ROUND(point[0].y));
	for(double t=0;t<=1.0;t=t+tStep)
	{
		Bern02=(1-t)*(1-t);//伯恩斯坦基函数值
		Bern12=2*t*(1-t);
		Bern22=t*t;
		CP2 tempPoint(0,0);//计算插值点
		double denominator=Bern02*weight0+Bern12*weight1+Bern22*weight2;//分母
		tempPoint.x=(Bern02*weight0*point[0].x+Bern12*weight1*point[1].x+Bern22*weight2*point[2].x)/denominator;//分子/分母
		tempPoint.y=(Bern02*weight0*point[0].y+Bern12*weight1*point[1].y+Bern22*weight2*point[2].y)/denominator;
		pDC->LineTo(ROUND(tempPoint.x),ROUND(tempPoint.y));
	}
	pDC->SelectObject(pOldPen);
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值