使用C语言实现二维,三维绘图算法(2)-解析曲面的显示

---- 引言----

每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想, Win32中既然存在画线画点函数, 利用计算机图形学的知识, 我们用可以用纯C调用Win32实现三维绘图, 完全不用借助OpenGL和DirectX, 这有重复造轮子的嫌疑, 但是自己动手实现一遍, 毕竟也是有意义的.

[效果演示]

原始效果(100条浮动曲线)

加密以后的效果(200条浮动曲线)

[浮动水平线法绘图过程]

固定一个y值按步长变换给定一个x值, 从而可计算出平面截线一个点的z坐标值. 将改点投影到xoy平面上, 然后再变换到屏幕上. 如果是曲线端点要填充边界值. 接着检验此点的可见性,并用1表示上方可见, 0表示不可见, -1表示下方可见. 可见性检测就是用当前点的y值与上下浮动水平线数组中相应的元素值进行比较,y值大于上水平线数组中元素值或小于下水平线数组中元素值, 则当前点可见, 否则不可见. 往下再计算同一平面截线的另一点, 和上面点一样, 先投影到坐标平面上, 再变换到屏幕上. 先前的点叫紧前点, 当前的点为当前点. 紧前点和当前点的可见性主要有下面一些可能情形:

[编程实现要点]

曲面函数的定义

float SurfaceFun(float X, float Y)
{
float w1, w2, w3, FV;
w1=*(X-)*(X-) + (Y-)*(Y-) - ;
w2=(X-)*(X-)/ + *(Y-)*(Y-) - ;
w3=(X-)*(X-)/ + *(Y-)*(Y-) - ; if(w1>) w1=;
if(w2>) w2=;
if(w3>) w3=; FV=w1*w1*exp(-w1) + w2*w2*exp(-w2) + w3*w3*exp(-w3); return(FV); }

绘制曲面函数

void DrawSurface()
{
int Xe, Ye, Ln, Pt, XPre, YPre, XCur, YCur, Xi, Yi;
int *pi, LimY, VisCur, VisPre;
float X, Y, Z; LimY=GetWindowHeight();
SetLineColor(BLUE); for(Ln=; Ln<=LNo; ++Ln)
{
Y=Y2-Ln*IncY;
X=X1;
Z=SurfaceFun(X,Y);
CalcuProject(X, Y, Z);
XPre = 0.5 + (XProj-F1)*EchX + C1;
YPre = 0.5 + (YProj-F3)*EchY + C3; FillEdge(XPre, YPre, Xd, Yd); VisPre = VisibilityTest(XPre, YPre); for(Pt=; Pt<=PNo; ++Pt)
{
X=X1+Pt*IncX;
Z=SurfaceFun(X,Y);
CalcuProject(X, Y, Z);
XCur = 0.5 + (XProj-F1)*EchX + C1;
YCur = 0.5 + (YProj-F3)*EchY + C3;
VisCur = VisibilityTest(XCur, YCur); if( (HMax[XCur]==) || (HMin[XCur]==LimY) ) VisCur = VisPre; if(VisCur == VisPre)
{
if( (VisCur==) || (VisCur==-) )
{
if(<=XCur)
PlotLine(XPre, LimY--YPre, Xi, LimY--YCur);
else if(<=YCur)
PlotLine(XPre, LimY--YPre, XPre, LimY--YCur);
else
PlotLine(Xi, LimY--YPre, XPre, LimY--YPre); HorizonInc(XPre, YPre, XCur, YCur);
}
}
else // VisCur!=VisPre
{
if(VisCur==)
{
if(VisPre == )
{
pi = Inter(XPre, YPre, XCur, YCur, HMax);
Xi = *pi;
Yi = *(pi+);
}
else
{
pi = Inter(XPre, YPre, XCur, YCur, HMin);
Xi = *pi;
Yi = *(pi+);
} if(<=Xi)
PlotLine(XPre, LimY--YPre, Xi, LimY--Yi);
else if(<=Yi)
PlotLine(XPre, LimY--Yi, XPre, LimY--Yi);
else
PlotLine(XPre, LimY--YPre, XPre, LimY--YPre); HorizonInc(XPre, YPre, Xi, Yi);
}
else
{
if(VisCur == )
{
if(VisPre == )
{
pi = Inter(XPre, YPre, XCur, YCur, HMax);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(Xi, LimY--Yi, XCur, LimY--YCur);
else if(<=Yi)
PlotLine(XCur, LimY--YCur, XCur, LimY--YCur);
else
PlotLine(XCur, LimY--YCur, XCur, LimY--YCur); HorizonInc(Xi, Yi, XCur, YCur);
}
else
{
pi = Inter(XPre, YPre, XCur, YCur, HMin);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(XPre, LimY--YPre, Xi, LimY--Yi);
else if(<=Yi)
PlotLine(XPre, LimY--YPre, XPre, LimY--Yi);
else
PlotLine(XPre, LimY--YPre, XPre, LimY--YPre); HorizonInc(XPre, YPre, Xi, Yi); pi = Inter(XPre, YPre, XCur, YCur, HMax);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(Xi, LimY--YCur, XCur, LimY--YCur);
else if(<=Yi)
PlotLine(XCur, LimY--Yi, XCur, LimY--YCur);
else
PlotLine(XCur, LimY--YCur, XCur, LimY--YCur); HorizonInc(Xi, Yi, XCur, YCur);
}
}
else // VisCur!=0, VisCur!=1
{
if(VisPre == )
{
pi = Inter(XPre, YPre, XCur, YCur, HMin);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(Xi, LimY--YCur, XCur, LimY--YCur);
else if(<=Yi)
PlotLine(XCur, LimY--Yi, XCur, LimY--YCur);
else
PlotLine(XCur, LimY--YCur, XCur, LimY--YCur); HorizonInc(Xi, Yi, XCur, YCur);
}
else // VisCur!=0, VisCur!=1, VisPre!=0
{
pi = Inter(XPre, YPre, XCur, YCur, HMax);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(XPre, LimY--YPre, Xi, LimY--Yi);
else if(<=Yi)
PlotLine(XPre, LimY--YPre, XPre, LimY--Yi);
else
PlotLine(XPre, LimY--YPre, XPre, LimY--YPre); HorizonInc(XPre, YPre, Xi, Yi); pi = Inter(XPre, YPre, XCur, YCur, HMin);
Xi = *pi;
Yi = *(pi+); if(<=Xi)
PlotLine(Xi, LimY--Yi, XCur, LimY--YCur);
else
PlotLine(XCur, LimY--YCur, XCur, LimY--YCur); HorizonInc(Xi, Yi, XCur, YCur);
}
}
}
} VisPre = VisCur;
XPre = XCur;
YPre = YCur;
} FillEdge(XCur, YCur, Xg, Yg);
}
}

使用C语言实现二维,三维绘图算法(2)-解析曲面的显示的更多相关文章

  1. 使用C语言实现二维,三维绘图算法(1)-透视投影

    使用C语言实现二维,三维绘图算法(1)-透视投影 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想 ...

  2. 使用C语言实现二维,三维绘图算法(3)-简单的二维分形

    使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  3. ARCGIS二维三维导航

    在使用代码前需要先安装arcgis10.0    或者10.1都可以    不过本人建议初学者安装10.0比较容易安装.. 安装方式和二维三维地图的加载网上都有,就不在此一一赘述了. 先从基本的功能开 ...

  4. Atitit zxing二维码qr码识别解析

    Atitit zxing二维码qr码识别解析 1.1. qr码识别解析 by zxing1 1.2. 解码lib:qrcode.jar  2 1.3. atitit.二维码生成总结java zxing ...

  5. ZXing二维码的生成和解析

    Zxing是Google提供的关于条码(一维码.二维码)的解析工具,提供了二维码的生成与解析的方法, 现在我简单介绍一下使用Java利用Zxing生成与解析二维码 注意: 二维码的生成需要借助辅助类( ...

  6. [图形学] 习题8.12 NLN二维线段裁剪算法实现

    Nicholl-Lee-Nicholl二维线段裁剪算法相对于Cohen-Sutherland和Liang-Barsky算法来说,在求交点之前进行了线段端点相对于几个区域的判断,可以确切的知道要求交点的 ...

  7. .net core 的图片处理及二维码的生成及解析

    写代码这事,掐指算来已经十有余年. 从html到css到javascript到vbscript到c#,从兴趣到职业,生活总是失落与惊喜并存. 绝大部分时候,出发并不是因为知道该到哪里去,只是知道不能再 ...

  8. 关于java的二维码的生成与解析

    本文说的是通过zxing实现二维码的生成与解析,看着很简单,直接上代码 import java.io.File; import java.io.IOException; import java.nio ...

  9. C语言之二维数组

    二维数组 还是一个数组,只不过数组中得每一个元素又是一个数组 1). 声明语法 类型 数组名[行][列]; 例:  int nums[2][3];//2行3列的二维数组,保存的数据类型是int类型 c ...

随机推荐

  1. git初探

    1 Linux下Git和GitHub环境的搭建 第一步: 安装Git,使用命令 "sudo apt-get install git" 第二步: 到GitHub上创建GitHub帐号 ...

  2. 1043: [HAOI2008]下落的圆盘 - BZOJ

    Description有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求.Input n ri xi y1 ... rn xn y ...

  3. 成功解决Tomcat-JDBC-MySQL乱码

    0.MySQL-JDBC驱动文档 官方解释 1.数据库的字符编码和表内字段的编码 在MySQL中数据库的字符编码和表内字段的编码的要指定为utf8(utf8_general_ci) 2.jsp中 pa ...

  4. VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因

    VS 2005使用map文件查找程序崩溃原因 一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的 ...

  5. 如何定位Release 版本中程序崩溃的位置 ---利用map文件 拦截windows崩溃函数

    1       案例描述 作为Windows程序员,平时最担心见到的事情可能就是程序发生了崩溃(异常),这时Windows会提示该程序执行了非法操作,即将关闭.请与您的供应商联系.呵呵,这句微软的“名 ...

  6. HDU 2159 FATE (DP 二维费用背包)

    题目链接 题意 : 中文题不详述. 思路 : 二维背包,dp[i][h]表示当前忍耐值为i的情况下,杀了h个怪得到的最大经验值,状态转移方程: dp[i][h] = max(dp[i][h],dp[i ...

  7. linux命令之-pstree使用说明

    pstree  shows running processes as a tree. The tree is rooted at either pid or init if pid is omitte ...

  8. movzbl和movsbl

    汇编语言中最最常用的指令 -- 数据传送指令,也是我们接触的第一种类别的汇编指令.其指令的格式为:“mov 源操作数, 目的操作数”.mov系列支持从最小一个字节到最大双字的访问与传送.其中movb用 ...

  9. cmd启动tomcat

    1.安装jdk 2.安装tomcat 3.需要配置两个用户环境变量,仅仅配置系统变量没用. a)JAVA_HOME:D:\programing~tools\java~tools\JDK(tm)\jdk ...

  10. 不输入密码ssh直接登录阿里云Linux主机

    服务器环境:阿里云云服务器,Linux版本 - CentOS 客户端环境:Mac OSX Terminal 注意: 如果有3个账号都要无密码登录, 则3个账号都要这么操作 在Terminal中用ssh ...