查看“︁梁友栋-柏世奇算法”︁的源代码
←
梁友栋-柏世奇算法
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
'''梁友栋—柏世奇算法'''(以[[梁友栋]]和{{link-en|柏世奇|Brian A. Barsky}}的名字命名)是[[计算机图形学]]中的一个[[线段裁剪算法]]。梁友栋—柏世奇算法使用直线的参数方程和不等式组来描述线段和裁剪窗口的交集。求解出的交集将被用于获知线的哪些部分是应当绘制在屏幕上的。这一算法比[[科恩-苏泽兰算法]]({{Lang|en|Cohen-Sutherland algorithm}})要更加高效,梁友栋—柏世奇算法的基本思想是:在计算线段与裁剪窗交集之前做尽可能多的判断。 ==算法描述== 考虑直线的参数方程: :<math>x = x_0 + t (x_1 - x_0) = x_0 + t \Delta x,</math> :<math>y = y_0 + t (y_1 - y_0) = y_0 + t \Delta y.</math> 点在裁剪窗内,若 :<math>x_\text{min} \le x_0 + t \Delta x \le x_\text{max}</math> 且 :<math>y_\text{min} \le y_0 + t \Delta y \le y_\text{max},</math> 其可用4个不等式表达: :<math>t p_i \le q_i, \quad i = 1, 2, 3, 4,</math> 其中 :<math> \begin{align} p_1 &= -\Delta x, & q_1 &= x_0 - x_\text{min}, & &\text{( 左 )} \\ p_2 &= \Delta x, & q_2 &= x_\text{max} - x_0, & &\text{( 右 )} \\ p_3 &= -\Delta y, & q_3 &= y_0 - y_\text{min}, & &\text{( 下 )} \\ p_4 &= \Delta y, & q_4 &= y_\text{max} - y_0. & &\text{( 上 )} \end{align} </math> 计算最终线段: # 与裁剪窗平行的直线在平行的边界上有 <math>p_i = 0</math> # 若对于这样的 <math>i</math><math>q_i < 0</math>,则线段全部在裁剪窗的外面,可以被消除 # 当 <math>p_i < 0</math>时,线从裁剪窗外向内走;<math>p_i > 0</math> # 对非零的 <math>p_k</math>, <math>u = q_i / p_i</math> # 对每条线,计算 <math>u_1</math> 和 <math>u_2</math>。对 <math>u_1</math>检查 <math>p_i < 0</math> 的边界(即从外向内)。令 <math>u_1</math> 为 <math>\{0, q_i / p_i\}</math> <math>u_2</math>检查 <math>p_i > 0</math> 的边界(即从内向外)。令 <math>u_2</math> 为 <math>\{1, q_i / p_i\}</math> <math>u_1 > u_2</math> ==示例代码== <syntaxhighlight lang="c++"> // Liang--Barsky line-clipping algorithm #include<iostream> #include<graphics.h> #include<math.h> using namespace std; // this function gives the maximum float maxi(float arr[],int n) { float m = 0; for (int i = 0; i < n; ++i) if (m < arr[i]) m = arr[i]; return m; } // this function gives the minimum float mini(float arr[], int n) { float m = 1; for (int i = 0; i < n; ++i) if (m > arr[i]) m = arr[i]; return m; } void liang_barsky_clipper(float xmin, float ymin, float xmax, float ymax, float x1, float y1, float x2, float y2) { // defining variables float p1 = -(x2 - x1); float p2 = -p1; float p3 = -(y2 - y1); float p4 = -p3; float q1 = x1 - xmin; float q2 = xmax - x1; float q3 = y1 - ymin; float q4 = ymax - y1; float posarr[5], negarr[5]; int posind = 1, negind = 1; posarr[0] = 1; negarr[0] = 0; rectangle(xmin, 467 - ymin, xmax, 467 - ymax); // drawing the clipping window if ((p1 == 0 && q1 < 0) || (p3 == 0 && q3 < 0)) { outtextxy(80, 80, "Line is parallel to clipping window!"); return; } if (p1 != 0) { float r1 = q1 / p1; float r2 = q2 / p2; if (p1 < 0) { negarr[negind++] = r1; // for negative p1, add it to negative array posarr[posind++] = r2; // and add p2 to positive array } else { negarr[negind++] = r2; posarr[posind++] = r1; } } if (p3 != 0) { float r3 = q3 / p3; float r4 = q4 / p4; if (p3 < 0) { negarr[negind++] = r3; posarr[posind++] = r4; } else { negarr[negind++] = r4; posarr[posind++] = r3; } } float xn1, yn1, xn2, yn2; float rn1, rn2; rn1 = maxi(negarr, negind); // maximum of negative array rn2 = mini(posarr, posind); // minimum of positive array if (rn1 > rn2) { // reject outtextxy(80, 80, "Line is outside the clipping window!"); return; } xn1 = x1 + p2 * rn1; yn1 = y1 + p4 * rn1; // computing new points xn2 = x1 + p2 * rn2; yn2 = y1 + p4 * rn2; setcolor(CYAN); line(xn1, 467 - yn1, xn2, 467 - yn2); // the drawing the new line setlinestyle(1, 1, 0); line(x1, 467 - y1, xn1, 467 - yn1); line(x2, 467 - y2, xn2, 467 - yn2); } int main() { cout << "\nLiang-barsky line clipping"; cout << "\nThe system window outlay is: (0,0) at bottom left and (631, 467) at top right"; cout << "\nEnter the co-ordinates of the window(wxmin, wxmax, wymin, wymax):"; float xmin, xmax, ymin, ymax; cin >> xmin >> ymin >> xmax >> ymax; cout << "\nEnter the end points of the line (x1, y1) and (x2, y2):"; float x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2; int gd = DETECT, gm; // using the winbgim library for C++, initializing the graphics mode initgraph(&gd, &gm, ""); liang_barsky_clipper(xmin, ymin, xmax, ymax, x1, y1, x2, y2); getch(); closegraph(); } </syntaxhighlight> == 参见 == 其他裁剪算法: * [[科恩-苏泽兰算法]] * [[Cyrus–Beck算法]] * [[Nicholl–Lee–Nicholl算法]] * [[快速裁剪]] == 参考文献 == * Liang, Y. D., and Barsky, B., "A New Concept and Method for Line Clipping", ''ACM Transactions on Graphics'', 3(1):1–22, January 1984. * Liang, Y. D., B. A., Barsky, and M. Slater, ''Some Improvements to a Parametric Line Clipping Algorithm'', CSD-92-688, Computer Science Division, University of California, Berkeley, 1992. * James D. Foley. ''Computer graphics: principles and practice''. Addison-Wesley Professional, 1996. p. 117. == 外部链接 == * http://hinjang.com/articles/04.html#eight {{Wayback|url=http://hinjang.com/articles/04.html#eight |date=20161121162859 }} * [http://www.skytopia.com/project/articles/compsci/clipping.html Skytopia: The Liang-Barsky line clipping algorithm in a nutshell!] {{Wayback|url=http://www.skytopia.com/project/articles/compsci/clipping.html |date=20180221041646 }} [[Category:计算机图形学]] [[Category:算法]]
该页面使用的模板:
Template:Lang
(
查看源代码
)
Template:Link-en
(
查看源代码
)
Template:Wayback
(
查看源代码
)
返回
梁友栋-柏世奇算法
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息