posts - 5,  comments - 1,  trackbacks - 0
  2011年8月12日
摘要: 转载自下面的blog,对作者表示感谢版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明http://thewhitemac.blogbus.com/logs/113396854.htmlInformations form : 知易 Cocos2D-iPhone 游戏开发教程 http://blog.sina.com.cn/carol游戏的整体架构,由不同的场景构成,每个场景由多个层组成,以及每个层上的精灵的运动。CCScene : 游戏中不同的画面可以用不同的场景展示出来,大致的可以分为以下的几类场景: 1. 展示类场景。游戏开场画面,游戏简介,胜利以及失败提示,帮助。 2. 选阅读全文
posted @ 2011-08-12 01:18 忘我和尚 阅读(450) 评论(0) 编辑
  2009年2月10日
 设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 P1,P2为对角顶点的矩形内。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上,对于这一步骤的判断可以用以下过程实现:

  ON-SEGMENT(pi,pj,pk)

  if min(xi,xj) <= xk <= max(xi,xj) and min(yi,yj) <= yk <= max(yi,yj)

  then return true;

  else return false;

  特别要注意的是,由于需要考虑水平线段和垂直线段两种特殊情况,min(xi,xj)<=xk<=max(xi,xj)和min(yi,yj)<=yk<=max(yi,yj)两个条件必须同时满足才能返回真值。

原文地址: http://dev.gameres.com/Program/Abstract/Geometry.htm

 

posted @ 2009-02-10 10:57 忘我和尚 阅读(850) 评论(0) 编辑
  2008年11月4日

设空间中的三点为M1,M2,M3,分别用矢量a,b表示方向向量M1M2和M1M3,则:  
  1.   M3到M1,M2连线的距离为|axb|/|a|,这里|.|表示向量的范数,axb表示a,b的叉乘。  
  2.   垂足为a-((a,b)/(a,a))a,这里(a,b)表示向量a,b的内积。

函数如下:

float GetDistance(tagCVector pt1, tagCVector pt2, tagCVector pt3)
{
      tagCVector pta = pt3 - pt1;
      tagCVector ptb = pt2 - pt1;
      tagCVector ptc = pta^ptb;
      float fDistance= sqrtf((ptc*ptc)/(ptb*ptb));
      return fDistance; 
}

采用这个办法计算量很小。感谢CSDN的Riemann在CSDN上提供此算法。

http://topic.csdn.net/t/20030505/09/1740223.html

posted @ 2008-11-04 17:09 忘我和尚 阅读(680) 评论(1) 编辑
下面的说明只注重对概念的表述和对实际操作过程的说明,并不进行严格的证明。

一般的贝塞尔曲线:
    对给定的 n+1 个点,可以作出 阶的贝塞尔曲线。其中最前和最后这两个点在曲线上,其余 n-1 个中间点是控制点,主要用于控制曲线的形状,不一定在曲线上。
    假如给定的 n+1 个点是 (x0,y0),...,(xn,yn), 以 作为参数,则生成的曲线上的所有点可以表示如下:
       n
   ∑ C(n,i) *t^i *(1-t)^(n-i) *xi
      i=0

       n
   ∑ C(n,i) *t^i *(1-t)^(n-i) *yi
      i=0
    其中 x,y 分别是生成的曲线上的点的 横坐标 和 纵坐标。
    是参数,其有效范围是 [0,1]。
    C(n,i)就是组合数,比如 C(3,1) 3。


实用 阶贝塞尔曲线:
    实际应用中,常用 阶的贝塞尔曲线,也就是要对 个点进行计算。
设 已知 的4点为 p0(x0,y0),p1(x1,y1),p2(x2,y2),p3(x3,y3),其中 和 是端点, 1,2是控制点,则 该曲线上的所有点表示为:
  (1-t)^3 *x0 3*t*(1-t)^2 *x1 3*t^2*(1-t) *x2 t^3 *x3
  (1-t)^3 *y0 3*t*(1-t)^2 *y1 3*t^2*(1-t) *y2 t^3 *y3
  其中 <= <= 1.


直接的简单实现:
    按照公式,对每个t,代入式子就可以得到曲线上对应点的坐标了。当然具体实现时,可根据适当的间隔取  值,然后用直线将这些值对应的点连起来就是了。
    类似于多项式的计算,在计算机上计算的时候,可以用 德卡斯特里奥算法 来求出,而不必直接计算高次幂。
设四个控制顶点是p0,p1,p2,p3,对每个具体的 t,可以做出下面的表:
p00
p10  p11
p20  p21  p22
p30  p31  p32  p33

其中:
p00 p0
p10 p1
p20 p2
p30 p3

p11 p00*(1-t) p10*t
p21 p10*(1-t) p20*t
p31 p20*(1-t) p30*t

p22 p11*(1-t) p21*t
p32 p21*(1-t) p31*t

p33 p22*(1-t) p32*t
通过验证可以知道,p33就是要求的值。

代码略。


简单实现遇到的问题:
    上面说的简单实现,t 的间距不好确定。因为曲线的形状可能千奇百怪,间隔太大则误差太大,太小的话则效率太低,难以确定一个对所有情况都合适的间隔值。而在实际应用中,则是用 递归 的方法来解决这个问题的。


实际中的递归处理:
    回头看上面求值的那个算法,当取 t=1/2 时, 1-t 1/2,计算过程可以简化如下:
p00
p10  p11
p20  p21  p22
p30  p31  p32  p33
其中:
pi0跟上面一样,分别就是那4个输入点p0,p1,p2,p3
pij p(i-1)(j-1) p(i-1)j    (简化的就是这个计算过程)

显然,p33就是 t=1/2 时所对应曲线上的点。
而且,
    如果以p00,p11,p22,p33为4个新的输入点,生成新的3阶贝塞尔曲线,则该曲线跟原来p0~p3生成的曲线在t∈[0,1/2]的部分“完全重合”。
    如果以p33,p32,p31,p30为4个新的输入点,生成新的3阶贝塞尔曲线,则该曲线跟原来p0~p3生成的曲线在t∈[1/2,1]的部分“完全重合”。
这里注意新输入点的输入顺序。

    上面漏了说贝塞尔曲线跟输入点的一个关系,就是贝塞尔曲线总是处在 输入点的凸包 内。那么可以得知,曲线上的点到 线段p0p3(就是两个端点) 的距离不大于 max(p1到p0p3的距离, p2到p0p3的距离)。
    而采用 德卡斯特里奥算法,取t=1/2 所求出来的中间点pij,其实就是 p(i-1)(j-1),pi(j-1) 的中点。比划一下也可以看出,中间点全部都在 p00,p10,p20,p30的凸包里面,也就是 p00,p11,p22,p33所形成的凸包 和 p33,p32,p21,p30的凸包也被包含在 p0,p1,p2,p3 的凸包里面。

综上所述:
    p00,p11,p22,p33 和 p33,p32,p31,p30 所生成的曲线拼起来,就是p0,p1,p2,p3生成的曲线。
    对p0,p1,p2,p3,用线段 p0p3 代替 生成的曲线,并以曲线上的点到线段的最大距离为误差,则 p00,p11,p22,p33 和 p33,p32,p31,p30的误差比 p0,p1,p2,p3 的要小。

所以,得到的递归生成曲线步骤如下:
1、
    对 p0,p1,p2,p3 4个点,先检查 
     max( d(p1, p0p3), d(p2, p0p3) (d()是点到直线距离,E是给定的误差范围,表示p0,p2,p3,p3的凸包的边跟生成曲线的最大差距。) 
    是否成立。
    如果 满足 条件,则简单用线段 p0p3 代替生成的曲线,返回。
    如果不满足,继续。

2、
    对 p0,p1,p2,p3 4个点,进行 t=1/2 的德卡里奥算法。
    对得到的 p00,p11,p22,p33,递归进行步骤 的操作;
    对得到的 p33,p32,p31,p30,递归进行步骤 的操作。
    返回。
 
http://blog.sina.com.cn/s/blog_4ff226280100aqmj.html 
posted @ 2008-11-04 11:12 忘我和尚 阅读(466) 评论(0) 编辑
  2008年10月30日

1.       什么时候使用显示列表:

多次重绘同一图形或需要多次调用用于更改状态的函数。由于显示列表本身也有一定的开销,所以当重绘图形太小时,使用显示列表不一定能提高效率

2.       哪些时候用显示列表:

a)         矩阵操作;

b)        对位图和图像进行光栅化;

c)        光晕、材质属性和光照模型;

d)        多边形电话模式

e)         我们常把纹理数据存在纹理对象而不使用显示列表是为了优化纹理图像

3.       它有哪些缺点:

a)         显示列表本身有一定的开销;

b)        显示列表一经定义不能修改;

c)        显示列表不能读取;

d)        在显示列表中,调用变换函数能对后面的绘图产生影响;

e)         当把表达式放在显示列表中时,实际上只有表达式的值存储在显示列表中,后期如果改变了表达式变量的值,这种变化不能体现在显示列表中

4.       如何定义一个显示列表:

通过glNewList(listName,mode) glEndList()界定一个显示列表,其中listName是一个整型索引值,由glGenList()函数产生,也可以通过glIsList() 判断某个指定的索引是不是被使用过的。mode 可以选用的值是GL_COMPILEGL_COMPILE_AND_EXECUTEGL_COMPILE表示将这些函数放在显示列表中,但不立即执行显示列表中的函数,GL_COMPILE_AND_EXECUTE表示将这些函数放在显示列表中并立即执行。

5.       如何调用一个显示列表

我们通过调用glCallList()来调用一个定义好的显示列表。显示列表支持嵌套调用但层次有限制,这个限制最少是64,这个限制取决于OpengGL的实现。

6.      为了在显示列表中进行状态变换又不改变原来的状态,我们可以调用glPushAttrib()glPushMatrix()来保存原来的状态,并使用glPopAttrib()glPopMatrix()来还原原来的状态。

posted @ 2008-10-30 14:50 忘我和尚 阅读(280) 评论(0) 编辑