MFC绘制有理柱面和圆锥面





上面四幅图为分别从正视图和斜二测视图绘制的1/4柱面和圆锥面
绘制类如下:

#pragma once
#include"P3.h"
#include"P2.h"
#include"math.h"
#define ROUND(h) int(h+0.5)
/***************************************************function:绘制柱面,圆锥面,用有理2*1次Bezier曲线绘制
**************************************************/
class RationalBezierPatch2_1
{public:RationalBezierPatch2_1(void);~RationalBezierPatch2_1(void);void ReadControlPoint(void);//读入控制点,权值void ReadWeight(void);CP3 ctrPnt[3][2];//定义数组储存控制点权值double weight[2][3];double weightT[3][2];void LeftMultiplyMatrix(double m[][3],CP3 pm[][2]);//矩阵左乘void LeftMultiplyMatrix(double m[][3],double w[][2]);void RightMultiplyMatrix(CP3 pm[][2],double m[][2]);//矩阵右乘void RightMultiplyMatrix(double w[][2],double m[][2]);CP2 OrthogonalProjection(CP3 Point3);//处理正交void DrawControlPoint(CDC*pDC);void DrawPatch(CDC*pDC);void Transpose(double m[][3],double T[][2]);
};
#include "StdAfx.h"
#include "RationalBezierPatch2_1.h"RationalBezierPatch2_1::RationalBezierPatch2_1(void)
{ReadControlPoint();ReadWeight();
}RationalBezierPatch2_1::~RationalBezierPatch2_1(void)
{}void RationalBezierPatch2_1::ReadControlPoint(void)
{ctrPnt[0][0].SetValue(0,200,100),ctrPnt[0][1].SetValue(0,0,100);//圆柱面ctrPnt[1][0].SetValue(100,200,100),ctrPnt[1][1].SetValue(100,0,100);ctrPnt[2][0].SetValue(100,200,0),ctrPnt[2][1].SetValue(100,0,0);//ctrPnt[0][0].SetValue(0,200,0),ctrPnt[0][1].SetValue(0,0,100);//圆锥面//ctrPnt[1][0].SetValue(0,200,0),ctrPnt[1][1].SetValue(100,0,100);//ctrPnt[2][0].SetValue(0,200,0),ctrPnt[2][1].SetValue(100,0,0);
}void RationalBezierPatch2_1::ReadWeight(void)
{weight[0][0]=1,weight[0][1]=sqrt(2.0)/2, weight[0][2]=1;weight[1][0]=1,weight[1][1]=sqrt(2.0)/2,weight[1][2]=1;weightT[0][0]=1,weightT[1][0]=sqrt(2.0)/2,weightT[2][0]=1;weightT[0][1]=1,weightT[1][1]=sqrt(2.0)/2,weightT[2][1]=1;}void RationalBezierPatch2_1::LeftMultiplyMatrix(double m[][3],CP3 pm[][2])
{CP3 T[3][2];for(int i=0;i<3;i++){for(int j=0;j<2;j++){T[i][j]=m[i][0]*pm[0][j]+m[i][1]*pm[1][j]+m[i][2]*pm[2][j];}}for(int i=0;i<3;i++){for(int j=0;j<2;j++){pm[i][j]=T[i][j];}}
}
//重载左乘
void RationalBezierPatch2_1::LeftMultiplyMatrix(double m[][3],double w[][2])
{double T[3][2];for(int i=0;i<3;i++){for(int j=0;j<2;j++){T[i][j]=m[i][0]*w[0][j]+m[i][1]*w[1][j]+m[i][2]*w[2][j];}}for(int i=0;i<3;i++){for(int j=0;j<2;j++){w[i][j]=T[i][j];}}
}void RationalBezierPatch2_1::RightMultiplyMatrix(CP3 pm[][2],double m[][2])
{CP3 T[3][2];for(int i=0;i<3;i++){for(int j=0;j<2;j++){T[i][j]=pm[i][0]*m[0][j]+pm[i][1]*m[1][j];}}for(int i=0;i<3;i++){for(int j=0;j<2;j++){pm[i][j]=T[i][j];}}
}//重载右乘函数
void RationalBezierPatch2_1::RightMultiplyMatrix(double w[][2],double m[][2])
{double T[3][2];for(int i=0;i<3;i++){for(int j=0;j<2;j++){T[i][j]=w[i][0]*m[0][j]+w[i][1]*m[1][j];}}for(int i=0;i<3;i++){for(int j=0;j<2;j++){w[i][j]=T[i][j];}}
}CP2 RationalBezierPatch2_1::OrthogonalProjection(CP3 Point3)
{CP2 tempPoint;//tempPoint.x=Point3.x;//正交投影//tempPoint.y=Point3.y;tempPoint.x=Point3.x-Point3.z*sqrt(2.0)/2.0;//斜二测投影tempPoint.y=Point3.y-Point3.z*sqrt(2.0)/2.0;return tempPoint;
}void RationalBezierPatch2_1::DrawControlPoint(CDC*pDC)
{CP2 P2[3][2];for(int i=0;i<3;i++){for(int j=0;j<2;j++){P2[i][j]=OrthogonalProjection(ctrPnt[i][j]);}}CPen NewPen,*pOldPen;NewPen.CreatePen(PS_SOLID,3,RGB(0,0,0));pOldPen=pDC->SelectObject(&NewPen);for(int i=0;i<3;i++){pDC->MoveTo(ROUND(P2[i][0].x),ROUND(P2[i][0].y));for(int j=0;j<2;j++){pDC->LineTo(ROUND(P2[i][j].x),ROUND(P2[i][j].y));}}for(int i=0;i<2;i++){pDC->MoveTo(ROUND(P2[0][i].x),ROUND(P2[0][i].y));for(int j=0;j<3;j++){pDC->LineTo(ROUND(P2[j][i].x),ROUND(P2[j][i].y));}}pDC->SelectObject(pOldPen);NewPen.DeleteObject();
}void RationalBezierPatch2_1::DrawPatch(CDC*pDC)
{DrawControlPoint(pDC);double lm[3][3];lm[0][0]=1,lm[0][1]=-2,lm[0][2]=1;lm[1][0]=-2,lm[1][1]=2,lm[1][2]=0;lm[2][0]=1,lm[2][1]=0,lm[2][2]=0;double rm[2][2];rm[0][0]=-1,rm[0][1]=1;rm[1][0]=1,rm[1][1]=0;CP3 ctrPW[3][2];//控制点乘以权重for(int i=0;i<3;i++){for(int j=0;j<2;j++){ctrPW[i][j]=ctrPnt[i][j]*weightT[i][j];}}LeftMultiplyMatrix(lm,ctrPW);RightMultiplyMatrix(ctrPW,rm);LeftMultiplyMatrix(lm,weightT);RightMultiplyMatrix(weightT,rm);double step=0.1;//步长double u0,u1,u2,v0,v1;for(double u=0;u<=1.0;u+=step){for(double v=0;v<=1.0;v+=step){u2=u*u,u1=u,u0=1;v1=v,v0=1;CP3 numerator=(u2*ctrPW[0][0]+u1*ctrPW[1][0]+u0*ctrPW[2][0])*v1+(u2*ctrPW[0][1]+u1*ctrPW[1][1]+u0*ctrPW[2][1])*v0;double denominator=(u2*weightT[0][0]+u1*weightT[1][0]+u0*weightT[2][0])*v1+(u2*weightT[0][1]+u1*weightT[1][1]+u0*weightT[2][1])*v0;CP3 pt=numerator/denominator;CP2 point2=OrthogonalProjection(pt);                                                      if(v==0)pDC->MoveTo(ROUND(point2.x),ROUND(point2.y));elsepDC->LineTo(ROUND(point2.x),ROUND(point2.y));}                                    }for(double v=0;v<=1.0;v+=step){for(double u=0;u<=1.0;u+=step){u2=u*u,u1=u,u0=1;v1=v,v0=1;CP3 numerator=(u2*ctrPW[0][0]+u1*ctrPW[1][0]+u0*ctrPW[2][0])*v1+(u2*ctrPW[0][1]+u1*ctrPW[1][1]+u0*ctrPW[2][1])*v0;double denominator=(u2*weightT[0][0]+u1*weightT[1][0]+u0*weightT[2][0])*v1+(u2*weightT[0][1]+u1*weightT[1][1]+u0*weightT[2][1])*v0;CP3 pt=numerator/denominator;CP2 point2=OrthogonalProjection(pt);if(u==0)pDC->MoveTo(ROUND(point2.x),ROUND(point2.y));elsepDC->LineTo(ROUND(point2.x),ROUND(point2.y));}}
}void RationalBezierPatch2_1::Transpose(double m[][3],double T[][2])
{for(int i=0;i<2;i++){for(int j=0;j<3;j++){T[j][i]=m[i][j];}}
}

参考《计算几何算法与实现》–孔令德

MFC绘制有理柱面和圆锥面相关推荐

  1. MFC绘制双有理Bezier曲面

    MFC绘制双有理Bezier曲面 双有理Bezier曲面可以精确表示任意二次曲面,如球面.柱面及圆锥面等,下面给出1/8球面的绘制类. 参考<计算几何算法与实现>–孔令德 #pragma ...

  2. MFC绘制实心圆(点)、坐标轴及参数显示、直线

    MFC绘制实心圆(点).坐标轴及参数显示.直线 在myTestview.cpp中绘制,通过以下步骤,可以实现基本绘制操作,如果搭积木般,函数实现还需自己构造. void CmyTestView::Dr ...

  3. MFC绘制旋转Bezier曲面

    MFC绘制旋转Bezier曲面 给出一条Bezier曲线,通过旋转64个控制点,4个曲面片,绘制出一个完整曲面 已知四个控制点:(50,100)(150,70)(120,-30)(90,-80) 理论 ...

  4. CSS 魔法系列:纯 CSS 绘制基本图形(圆、椭圆等)

    我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...

  5. MFC绘制动态曲线,用双缓冲绘图技术防闪烁

    转载自:ZHY_ongu的博客:MFC绘制动态曲线,用双缓冲绘图技术防闪烁 先上效果图    随着时间的推移,曲线向右平移,同时X轴的时间坐标跟着更新. 一.如何绘制动态曲线. 所谓动画,都是一帧一帧 ...

  6. 问题三十六:ray tracing中的Inverse Mapping(5)——圆锥面Inverse Mapping

    36.5 圆锥面Inverse Mapping 36.5.1 数学推导 36.5.2 看C++代码实现 ----------------------------------------------qu ...

  7. MFC 绘制半透明图片

    用MFC绘制半透明图片其实根本没有必要,因为有美工:哈哈,当然了我们自己练手的时候没有美工,自己也不会ps,只能用代码了 void  类名::DrawClearImage(Graphics *pGra ...

  8. openlayers根据半径绘制圆形,多圆连线并标记距离

    openlayers根据半径绘制圆形,多圆连线并标记距离 实现一个什么效果呢,就是在openlayers上面,绘制三个圆形,绘制完成之后,三个圆心连接起来,然后标记出每两个圆心之间的距离. 期望效果: ...

  9. 使用python绘制一个渐变色的圆

    1,引入海龟绘图 import turtle as t 2,基本操作,绘制一个蓝色的圆 #设置圆颜色 t.color('blue') #开始绘制 t.begin_fill() #参数redius=10 ...

最新文章

  1. Python学习总结(一)
  2. 用springmvc作接口时返回json数据中文乱码
  3. 苏宁css代码生成器,【前端】06 - rem + less + 媒体查询 - 制作苏宁首页
  4. 红旗linux安装oracle,Redflag Linux安装Oracle 10gR2 RAC记事
  5. exit、break、continue的区别
  6. 大数据下,谁来保护裸奔的个人隐私
  7. yamdi 实现添加元数据的注入flv文件,实现Nginx搭建flv视频浏览器上点播拖拽
  8. linux下添加定时任务
  9. 最高人民法院 最高人民检察院 关于办理非法利用信息网络、帮助信息网络犯罪活动等刑事案件适用法律若干问题的解释(重点学习标注)...
  10. 留给10年后的自己观看,T4-7生活就像那条小巷!
  11. 腾讯地图路线规划 vue
  12. react基础之--样式设置
  13. IM开发快速入门(一):什么是IM系统?
  14. FPGA可以转行数字IC验证吗?
  15. Android 文字转语音2种方式
  16. Javascript里EQ、NE、GT、LT、GE、LE含义
  17. Win10系统桌面图标突然变成白色如何恢复
  18. 知三点求平面 || 点到平面的距离
  19. 李云大连理工计算机系2015级,大连理工大学考研研究生导师简介-李秀英
  20. Android 百度鹰眼 SDK

热门文章

  1. 联通的无限流量套餐,比移动好很多
  2. latex 字体大小
  3. 管道公司襄樊处隐患治理注重“回头看”
  4. macos+win10切换到ubuntu的全记录
  5. java打字游戏_Java仿金山打字通打字母游戏《Java就该这样学》
  6. 「Luogu2495」 [SDOI2011]消耗战 虚树
  7. SCI论文解读复现【NO.2】基于注意机制的YOLOv5改进算法在行星图像中的应用(代码已复现)
  8. SpO2、SaO2、PaO2、低氧血症概念及标准的总结
  9. 猿创征文|JAVA 实现《连连看》游戏
  10. 阿里云 MNS 切换为 自建 RabbitMQ