用c++与easyx实现Nicholl–Lee–Nicholl直线裁剪
时间: 2023-12-13 19:05:19 浏览: 77
以下是一个使用EasyX图形库和C++语言实现Nicholl–Lee–Nicholl直线裁剪算法的示例代码:
```cpp
#include <graphics.h>
#include <iostream>
using namespace std;
// 定义窗口边界
const int XMIN = 100;
const int YMIN = 100;
const int XMAX = 500;
const int YMAX = 400;
// 定义直线端点
int x1, y1, x2, y2;
// 计算直线与x轴正半轴的夹角(弧度制)
double angle() {
double dx = x2 - x1;
double dy = y2 - y1;
if (dx == 0) { // 垂直于x轴
if (dy > 0)
return 90.0;
else
return 270.0;
}
double theta = atan(dy / dx) * 180.0 / M_PI;
if (dx < 0) // 第二、三象限
theta += 180.0;
else if (dy < 0) // 第四象限
theta += 360.0;
return theta;
}
// 计算直线端点是否在窗口内
bool inside(int x, int y) {
return (x >= XMIN && x <= XMAX && y >= YMIN && y <= YMAX);
}
// 计算直线端点到窗口边界的距离(沿直线方向)
double distance(int x, int y, int code) {
double dist = 1e9;
if (code & 1) { // 左边界
double d = (XMIN - x) / cos(angle() * M_PI / 180.0);
if (d >= 0 && d < dist)
dist = d;
}
if (code & 2) { // 上边界
double d = (YMIN - y) / sin(angle() * M_PI / 180.0);
if (d >= 0 && d < dist)
dist = d;
}
if (code & 4) { // 右边界
double d = (XMAX - x) / cos(angle() * M_PI / 180.0);
if (d >= 0 && d < dist)
dist = d;
}
if (code & 8) { // 下边界
double d = (YMAX - y) / sin(angle() * M_PI / 180.0);
if (d >= 0 && d < dist)
dist = d;
}
return dist;
}
// 裁剪直线
void clipLine(int& x1, int& y1, int& x2, int& y2) {
int code1 = 0;
int code2 = 0;
while (true) {
code1 = 0;
code2 = 0;
if (inside(x1, y1))
code1 = 0;
else
code1 = (x1 < XMIN) * 1 + (x1 > XMAX) * 4 + (y1 < YMIN) * 2 + (y1 > YMAX) * 8;
if (inside(x2, y2))
code2 = 0;
else
code2 = (x2 < XMIN) * 1 + (x2 > XMAX) * 4 + (y2 < YMIN) * 2 + (y2 > YMAX) * 8;
if (code1 == 0 && code2 == 0) { // 全部在窗口内
line(x1, y1, x2, y2);
break;
}
if (code1 & code2) { // 全部在窗口外
break;
}
double dist1 = distance(x1, y1, code1);
double dist2 = distance(x2, y2, code2);
if (dist1 <= dist2) { // 裁剪端点1
x1 += dist1 * cos(angle() * M_PI / 180.0);
y1 += dist1 * sin(angle() * M_PI / 180.0);
}
if (dist2 <= dist1) { // 裁剪端点2
x2 += dist2 * cos(angle() * M_PI / 180.0);
y2 += dist2 * sin(angle() * M_PI / 180.0);
}
}
}
int main() {
initgraph(600, 500);
setbkcolor(WHITE);
cleardevice();
x1 = 50;
y1 = 50;
x2 = 550;
y2 = 450;
// 绘制窗口
rectangle(XMIN, YMIN, XMAX, YMAX);
// 绘制直线
line(x1, y1, x2, y2);
// 裁剪直线
clipLine(x1, y1, x2, y2);
getch();
closegraph();
return 0;
}
```
在这个示例中,我们使用Nicholl–Lee–Nicholl算法对一条直线进行裁剪,并使用EasyX图形库绘制出裁剪前后的直线和窗口边界。
阅读全文