由高度场求法线

设高度场由函数z=h(x,y)给出,则问题就是求此曲面的法线。

注:文中d代表偏导数。

方法一:

把z=h(x,y)看成山坡,则在点P(x,y)处,其爬坡方向由二维梯度给出

gradh=(dh/dx,dh/dy,0)。

(gradh在XY平面内,由低海拔指向高海拔)。

根据“梯度的模等于方向导数”有:

|gradh|=tan(theta),theta为坡度角。

因为|gradh|=tan(theta),所以若设up=(0,0,1)(即让up的模为1),则恰有-gradh+up=normal。如图:

于是就有normal=-gradh+up=-(dh/dx,dh/dy,0)+(0,0,1)=(-dh/dx,-dh/dy,1)。

方法二:

构造三维标量场F(x,y,z)=h(x,y)-z。

则z=h(x,y)为F的0等值面。

F在点(x,y,z)处梯度为gradF=(dF/dx,dF/dy,dF/dz)=(dh/dx,dh/dy,-1)。

由于梯度必定垂直于等值面。

所以z=h(x,y)在点(x,y,z)处的法向量normal=gradF=(dh/dx,dh/dy,-1)。

注:

1,可见两种方法得出的结果是一致的。

2,是取(-dh/dx,-dh/dy,1)还是取(dh/dx,dh/dy,-1)根据需求而定,如本文由高度场求法线这种用于图形学用途,显然是会取(-dh/dx,-dh/dy,1),

3,以上两种方法都没有对结果进行归一化,在实际用于图形学时应进行归一化。

时间: 2025-01-16 14:21:06

由高度场求法线的相关文章

[原][osgearth]设置OE的高程,高度场的数据。修改设置高度值

for( unsigned int row=0; row < hf->getNumRows(); ++row ) { for( unsigned int col=0; col < hf->getNumColumns(); ++col ) { float val = hf->getHeight(col, row); if ( !isNoData( val ) ) { continue; } if ( col > 0 ) val = hf->getHeight(col

求二叉树的高度,叶子节点个数,第K层结点个数,求祖先结点问题

一.求二叉树的高度 类似归并排序的思想.先求最底层结点的高度,再分别比较生成更高的结点的高度.最后递归至根结点,求出根结点的高度. //求二叉树的高度 int Height() { return GetHeight(_root); } int GetHeight(Node<T> *root) { int left = 0; int right = 0; if (root->_leftchild != NULL) left += GetHeight(root->_leftchild)

高度图地形读取与漫游

地形系统在3d程序中是一个重要的部分,这里介绍一下我正在使用的一个简单的地形类.地形数据可以保存在一张灰度图里面,所谓的灰度图就是一张只有黑色和白色的图片,使用颜色深度代表数据大小.我们可以读取出图片上每个像素的颜色值作为地图中某个位置的高度,下面是地形网格投影在平面上的样子 嗯,也可以用三角形网格组织,我的地形类用的就是三角面. 看一下加载数据的方法: Terrain::Terrain(const char* strName,BYTE* pHeightMap) { int nSize=MAP_

二分求LIS并打印结果

1275: God's ladder [DP] 时间限制: 1 Sec 内存限制: 128 MB  Special Judge 题目描述 天明来到神之宫殿,在他眼前出现了若干个石柱,每个石柱上有1枚金币,天明可以任意选择一个石柱开始,然后向前方的石柱瞬移,而且他所瞬移到的石柱的高度必须要大于现在所在石柱的高度. 求天明所能获得的最大金币数以及任意一种可以获得这么多金币的路线(每个石柱的高度). 输入 第一行一个数n,表示石柱的个数. 然后2~n+1行,每行一个石柱的高度h[i],分别是1,2,,

线段求交点的算法

算法一: 求两条线段所在直线的交点, 再判断交点是否在两条线段上. 求直线交点时 我们可通过直线的一般方程 ax+by+c=0 求得(方程中的abc为系数,不是前面提到的端点,另外也可用点斜式方程和斜截式方程,此处暂且不论). 然后根据交点的与线段端点的位置关系来判断交点是否在线段上. 公式如下图: 算法一思路比较清晰易懂, 但是性能并不高. 因为它在不确定交点是否有效(在线段上)之前, 就先去计算了交点, 耗费了较多的时间. 如果最后发现交点无效, 那么之前的计算就白折腾了. 而且整个计算的过

求两条线段交点zz

"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说, 希望对大家有所帮助. 本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊 嘎嘎 引用 已知线段1(a,b) 和线段2(c,d) ,其中a b c d为端点, 求线段交点p .(平行或共线视作不相交) =============================== 算法一: 求两条线段所在直线的交点, 再判

谈谈&quot;求线段交点&quot;的几种算法(js实现,完整版)

"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法总结一下, 希望对大家有所帮助. 本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊 嘎嘎 引用 已知线段1(a,b) 和线段2(c,d) ,其中a b c d为端点, 求线段交点p .(平行或共线视作不相交) =============================== 算法一: 求两条线段所在直线的交点, 再

求线段交点&quot;的几种算法(js实现,完整版)

"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说, 希望对大家有所帮助. 本文讲的内容都很初级, 主要是面向和我一样的初学者, 所以请各位算法帝们轻拍啊 嘎嘎 引用 已知线段1(a,b) 和线段2(c,d) ,其中a b c d为端点, 求线段交点p .(平行或共线视作不相交) 算法一: 求两条线段所在直线的交点, 再判断交点是否在两条线段上. 求直线交点时 我们可通过直线的一般方程

unity 由两个向量求夹角

1. float angle = Vector3.Angle (fromVector, toVector); //求出两向量之间的夹角 Vector3 normal = Vector3.Cross (fromVector,toVector);//叉乘求出法线向量 angle *= Mathf.Sign (Vector3.Dot(normal,upVector)); //求法线向量与物体上方向向量点乘,结果为1或-1,修正旋转方向 2. Vector3 velocity = Quaternion.