JAVA语言实现CyrusBeck算法,须有图形显示,显示各阶段结果
时间: 2024-02-29 19:52:35 浏览: 66
java中如何显示图形
以下是Java实现的Cyrus-Beck算法,带有图形显示:
```java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CyrusBeckAlgorithmWithGraphics extends JPanel {
// 定义线段的两个端点
private Point p1, p2;
// 定义矩形剪裁窗口的四个顶点
private Point[] clipWindow = new Point[4];
// 定义当前鼠标拖动的点
private Point currentPoint;
public CyrusBeckAlgorithmWithGraphics() {
// 初始化线段和剪裁窗口
p1 = new Point(50, 50);
p2 = new Point(200, 200);
clipWindow[0] = new Point(150, 100);
clipWindow[1] = new Point(250, 100);
clipWindow[2] = new Point(250, 200);
clipWindow[3] = new Point(150, 200);
// 添加鼠标拖动事件监听器
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
currentPoint = e.getPoint();
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
p1.translate(e.getPoint().x - currentPoint.x, e.getPoint().y - currentPoint.y);
p2.translate(e.getPoint().x - currentPoint.x, e.getPoint().y - currentPoint.y);
currentPoint = e.getPoint();
repaint();
}
});
}
// 计算法向量
private Point computeNormal(Point p1, Point p2) {
int dx = p2.x - p1.x;
int dy = p2.y - p1.y;
return new Point(dy, -dx);
}
// 计算点积
private double dotProduct(Point a, Point b) {
return a.x * b.x + a.y * b.y;
}
// 计算线段起点到P点的向量
private Point computeVector(Point p) {
return new Point(p.x - p1.x, p.y - p1.y);
}
// 计算交点
private Point computeIntersection(Point p, Point d) {
Point e = new Point(p1.x - p.x, p1.y - p.y);
double t = dotProduct(computeNormal(p1, p2), e) / dotProduct(computeNormal(p1, p2), d);
return new Point((int) (p.x + t * d.x), (int) (p.y + t * d.y));
}
// 判断点是否在剪裁窗口内
private boolean isInside(Point p) {
Point d = new Point(p2.x - p1.x, p2.y - p1.y);
Point n = computeNormal(p1, p2);
Point w = computeVector(p);
double nd = dotProduct(n, d);
if (nd == 0) {
return false;
}
double t = -dotProduct(n, w) / nd;
return t >= 0 && t <= 1;
}
// 计算Cyrus-Beck剪裁后的线段
public Point[] cyrusBeckClip(Point p, Point q) {
Point d = new Point(q.x - p.x, q.y - p.y);
Point[] result = new Point[2];
int count = 0;
if (isInside(p)) {
result[count++] = p;
}
if (isInside(q)) {
result[count++] = q;
}
Point pi, qi;
pi = computeIntersection(p, d);
qi = computeIntersection(q, d);
if (isInside(pi)) {
result[count++] = pi;
}
if (isInside(qi)) {
result[count++] = qi;
}
if (count == 2) {
return result;
} else {
return null;
}
}
public void paint(Graphics g) {
// 绘制剪裁窗口
g.setColor(Color.RED);
for (int i = 0; i < 4; i++) {
g.drawLine(clipWindow[i].x, clipWindow[i].y, clipWindow[(i + 1) % 4].x, clipWindow[(i + 1) % 4].y);
}
// 绘制线段
g.setColor(Color.BLUE);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
// 剪裁线段
Point[] clippedLine = cyrusBeckClip(p1, p2);
if (clippedLine != null) {
// 绘制剪裁后的线段
g.setColor(Color.GREEN);
g.drawLine(clippedLine[0].x, clippedLine[0].y, clippedLine[1].x, clippedLine[1].y);
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setTitle("Cyrus-Beck Algorithm with Graphics");
CyrusBeckAlgorithmWithGraphics panel = new CyrusBeckAlgorithmWithGraphics();
frame.add(panel);
frame.setVisible(true);
}
}
```
在这个例子中,我们使用Java Swing框架创建一个窗口,并在窗口中绘制剪裁窗口和线段。我们还添加了鼠标拖动事件监听器,使得用户可以拖动线段。在每次绘制时,我们都会计算剪裁后的线段,并绘制出来。这样,用户就可以看到线段在剪裁窗口内部的变化过程。
阅读全文