QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1876|回复: 3

窗口裁减计算

[复制链接]
发表于 2006-5-10 17:47:23 | 显示全部楼层 |阅读模式
窗口裁减计算
  
1.   基于EGui窗口位置判断的基础上,做了窗口裁减的算法。到目前为止我还是认为这个算法非常好。

   窗口A和窗口B,C,D,E,F,G位置关系如图所示,深蓝色部分为相交部分。
   那么怎么计算它们是否相交呢?,相交的后矩形坐标是是什么呢?
   这是窗口移动时要考虑的问题。

2.
   这里介绍EGui的实现方法:

   首先再分辨率为1024x768的屏幕上,
   EGui的每个窗口都有 char width_in[1024],char height_in[768]
   其中窗口所占的空间设置为1,其他地方设置为0。
   
   拿 起始点20,30 ,终点400,200.的窗口坐标为例:

   memset(width_in,0,1024);
   memset(height_in,0,76;
   /* set erea that is inside as 1 */
   memset(width_in  + 20,1,400 - 20);
   memset(height_in + 30,1,200 - 30);

3. 相交计算

   看代码:
[code:1]
   int x1,x2;
   int i;

    x1 = x2 = 0;

  /* find x1 */
  for (i = 0; i< 1024 ;i ++)
    {
      if (a_width_in[i] && b_width_in[i])
        {
          x1 = i;
          break;
        }
    }
  /* no intersection */
  if (x1 == 1024)
    return NULL;

    /* find x2 */
  for (i = x1; i< 1024; i++)
    {
      if (!(a_width_in[i] && b_width_in[i]))
        {
          x2 = i;
          break;
        }
    }
[/code:1]

4.对代码的解释
  
  上述代码,计算了横坐标,纵坐标计算方法也一样。
  如果此代码没有返回NULL,就证明相交后横坐标为x1,x2

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2006-5-21 02:30:24 | 显示全部楼层
我的矩形相交算法,仅供参考(因为是浮点数的,所以和整数有所区别):
[code:1]
inline ERect rect_intersection(ERect r1, ERect r2)
{
        if(r1.IsValid() == false || r2.IsValid() == false) return ERect();

        ERect r3;
        r3.left = max_c(r1.left, r2.left);
        r3.top = max_c(r1.top, r2.top);
        r3.right = min_c(r1.right, r2.right);
        r3.bottom = min_c(r1.bottom, r2.bottom);

        return r3;
}

bool
ERect::Intersect(float l, float t, float r, float b) const
{
        if(!IsValid() || !(l <= r && t <= b)) return false;
        if(max_c(left, l) > min_c(right, r)) return false;
        if(max_c(top, t) > min_c(bottom, b)) return false;

        return true;
}
[/code:1]

不规则的区域,我用多个矩形来表示,所以存在和X Window的Region相同的弊病---耗cpu
回复

使用道具 举报

 楼主| 发表于 2006-5-21 16:37:37 | 显示全部楼层
你的这种做法需要先判断是否相交,在判断相交后的矩形。
这是最普通的方法。

我为了优化使用了上述方法,后来发现,其实要操作的次数更多。呵呵
。看来我要再想想怎么优化才行。
回复

使用道具 举报

发表于 2006-5-21 19:41:58 | 显示全部楼层
上面的rect_intersection函数返回值通过其返回值的IsValid()成员判定是否有相交区域即可,不用进行判断后再运算。
ERect::Intersect(float l, float t, float r, float b) const 只是示例如何最短时间内判断是否相交。
上面提交的两个函数都只用到 max或min,也就是 (a > b ? a : b) 的操作,所以个人认为效率较高。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-2 16:24 , Processed in 0.068498 second(s), 17 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表