zoukankan      html  css  js  c++  java
  • [图形学] Chp8.7.2 梁友栋-Barsky线段裁剪算法

      这节简单介绍了梁友栋-Barsky裁剪算法的原理,只有结论并没有过程,看过http://blog.csdn.net/daisy__ben/article/details/51941608这篇文章后,大概有了新的认识。

    "

    假设点P1P2W1W2的横坐标分别是x1,x2,w1,w2,线段P1P2与蓝色裁剪窗口W1W2(蓝色的线之间)的存在公共部分(可见部分)的充要条件是:

    max(min(x1,x2), min(w1,w2))≤ min(max(x1,x2), max(w1,w2))
    即所谓左端点中大者<=右端点中的小者
    "
     
      线段上的点满足y=x1+u(x2-x1) = x1 + u*△x。 其中0<=u<=1。
      u1决定了线段在裁剪区域内的左侧点,u2决定了在裁剪区域内右侧的点。左点yl = x1 + u1 * △x,右点yr = x1 + u2 * △x,且必须满足0 <= u1 <= u2 <= 1.
      这时,求解u1和u2是梁友栋-Barsky线段裁剪算法的目的,
     
     
     
     
     
     
     
    (8.18)(8.19)
     
     
      对于书中的公式(8.18),求等式,即为线段与4个边界的交点u值。
     
    "
    r不等于0的时候,对于上面四个不等式,当rk < 0时 ,u >= qk/rk,当rk>0时 u <= qk/rk,则点P才能位于裁剪窗口之内。同理,假如P已经落在了裁剪窗口之内,u一定大于等于所有rk<0对应的uk的最大值,而小于等于所有rk>0时对应的uk最小值。
    "
      代码中因此就有了函数GLint clipTest(GLfloat p, GLfloat q, GLfloat * u1, GLfloat * u2)。当p<0时,要获得对应的u,如果这个u>u2,则舍弃;如果u<u2并且u>u1,则u1=u。若p>0时,如果这个u<u1则舍弃;如果u<u2,则u2=u。 传入的p,q分别由公式(8.19)确定。由此计算最多4次来获得u1和u2.
     
     1 #include <GLUT/GLUT.h>
     2 #include <iostream>
     3 #include "lineliangbarsk.h"
     4 #include "linebres.h"
     5 
     6 GLint clipTest (GLfloat p, GLfloat q, GLfloat * u1, GLfloat * u2)
     7 {
     8     GLfloat r;
     9     GLint returnValue = true;
    10     
    11     if(p < 0.0)
    12     {
    13         r = q / p;
    14         if(r > *u2)
    15         {
    16             returnValue = false;
    17         }
    18         else
    19         {
    20             if(r > *u1)
    21             {
    22                 *u1 = r;
    23             }
    24         }
    25     }
    26     else
    27     {
    28         if(p > 0.0)
    29         {
    30             r = q / p;
    31             if(r < *u1)
    32             {
    33                 returnValue = false;
    34             }
    35             else
    36             {
    37                 if(r < *u2)
    38                 {
    39                     *u2 = r;
    40                 }
    41             }
    42         }
    43         else
    44         {
    45             if(q < 0.0)
    46             {
    47                 returnValue = false;
    48             }
    49         }
    50     }
    51     return returnValue;
    52 }
    53 
    54 void lineClipLiangBarsk(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2)
    55 {
    56     GLfloat u1 = 0.0, u2 = 1.0, dx = p2.getx() - p1.getx(), dy;
    57     
    58     if(clipTest(-dx, p1.getx() - winMin.getx(), &u1, &u2))
    59     {
    60         if(clipTest(dx, winMax.getx() - p1.getx(), &u1, &u2))
    61         {
    62             dy = p2.gety() - p1.gety();
    63             if(clipTest(-dy, p1.gety() - winMin.gety(), &u1, &u2))
    64             {
    65                 if(clipTest(dy, winMax.gety() - p1.gety(), &u1, &u2))
    66                 {
    67                     if(u2 < 1.0)
    68                     {
    69                         p2.setCoords(p1.getx() + u2 * dx, p1.gety() + u2 * dy);
    70                     }
    71                     if(u1 > 0.0)
    72                     {
    73                         p1.setCoords(p1.getx() + u1 * dx, p1.gety() + u1 * dy);
    74                     }
    75                     lineBres(round(p1.getx()), round(p1.gety()), round(p2.getx()), round(p2.gety()));
    76                     std::cout << "liangbarsk : " << u1 << "," << u2 << std::endl;
    77                     std::cout << "liangbarsk : " << p1.getx() << "," << p1.gety() << "," << p2.getx() << "," << p2.gety() << std::endl;
    78                 }
    79             }
    80         }
    81     }
    82 }
    View Code

    https://github.com/p0e0o0p0l0e0/Computer_Graphics.git

    c05938b3e669c1a04f86a54a69b5e2bb3066bd4e

    参考:http://blog.csdn.net/daisy__ben/article/details/51941608

     
  • 相关阅读:
    LOJ2323. 「清华集训 2017」小 Y 和地铁 【搜索】【思维】【好】
    BZOJ2687 交与并/BZOJ2369 区间【决策单调性优化DP】【分治】
    BZOJ1563 NOI2009 诗人小G【决策单调性优化DP】
    LOJ6039. 「雅礼集训 2017 Day5」珠宝【决策单调性优化DP】【分治】【思维好题】
    BZOJ4709 Jsoi2011 柠檬【决策单调性+单调栈】
    BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
    BZOJ3675 Apio2014 序列分割 【斜率优化】
    BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】
    51nod 1600 Simple KMP【后缀自动机+LCT】【思维好题】*
    linux usermod
  • 原文地址:https://www.cnblogs.com/p0e0o0p0l0e0/p/6918179.html
Copyright © 2011-2022 走看看