线交叉矩形 – 如何找到交叉点?

我在canvas上画一个矩形,从矩形的中心到坐标空间中的一个随机点画一条线。

现在,我想按行矩形内的长度截断行,以便行从矩形边开始。

我怎么能这样做?

  • 矩形可以由2个点定义: Pstart(1, 3)Pend(3, 1)
  • 中心点可以计算为: P(2, 2)
  • 现在画出从P(2, 2)Q(10, 2)

我知道矩形的宽度是2,我可以告诉该行从P(4, 2)而不是P(2, 2)

当该点与XY轴之一不平行时,这会变得更复杂。 此外,矩形内部的长度对于对角线而言将是不同的量。

如何计算线点相对于矩形中心和线的终点的起始偏移?

可能我必须找到线穿过矩形的点,然后让线从交叉点开始。 但我怎么能得到这一点呢?

老实说,我不懂数学,但……

基本上,你有5行。 原始线和矩形的4条线。 因此,如果你将它分解为一个简单的线路交叉线问题,它应该变得更容易……

在此处输入图像描述

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class IntersectPoint { public static void main(String[] args) { new IntersectPoint(); } public IntersectPoint() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int x = (int) (getWidth() * 0.2f); int y = (int) (getHeight() * 0.2f); int width = (int) (getWidth() * 0.6f); int height = (int) (getHeight() * 0.6f); int x1 = x; int y1 = 0; int x2 = x + width; int y2 = getHeight(); Line2D line = new Line2D.Double(x1, y1, x2, y2); Rectangle2D rect = new Rectangle2D.Double(x, y, width, height); Graphics2D g2d = (Graphics2D) g.create(); g2d.draw(rect); g2d.draw(line); g2d.setColor(Color.RED); Point2D[] ps = getIntersectionPoint(line, rect); for (Point2D p : ps) { if (p != null) { g2d.fill(new Ellipse2D.Double(p.getX() - 4, p.getY() - 4, 8, 8)); } } g2d.dispose(); } public Point2D[] getIntersectionPoint(Line2D line, Rectangle2D rectangle) { Point2D[] p = new Point2D[4]; // Top line p[0] = getIntersectionPoint(line, new Line2D.Double( rectangle.getX(), rectangle.getY(), rectangle.getX() + rectangle.getWidth(), rectangle.getY())); // Bottom line p[1] = getIntersectionPoint(line, new Line2D.Double( rectangle.getX(), rectangle.getY() + rectangle.getHeight(), rectangle.getX() + rectangle.getWidth(), rectangle.getY() + rectangle.getHeight())); // Left side... p[2] = getIntersectionPoint(line, new Line2D.Double( rectangle.getX(), rectangle.getY(), rectangle.getX(), rectangle.getY() + rectangle.getHeight())); // Right side p[3] = getIntersectionPoint(line, new Line2D.Double( rectangle.getX() + rectangle.getWidth(), rectangle.getY(), rectangle.getX() + rectangle.getWidth(), rectangle.getY() + rectangle.getHeight())); return p; } public Point2D getIntersectionPoint(Line2D lineA, Line2D lineB) { double x1 = lineA.getX1(); double y1 = lineA.getY1(); double x2 = lineA.getX2(); double y2 = lineA.getY2(); double x3 = lineB.getX1(); double y3 = lineB.getY1(); double x4 = lineB.getX2(); double y4 = lineB.getY2(); Point2D p = null; double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (d != 0) { double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d; double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d; p = new Point2D.Double(xi, yi); } return p; } } } 

看看用于矩形线裁剪的Liang-Barsky算法 。

矩形的顶点:a,b,c,d。 代表每个人的x和y坐标,如ax,ay等。

线的端点:x,y

该线跟随y = mx + b,向上或向下,向右或向左移动。 这会缩小您可能的矩形边缘以便穿越到2。

使用y = mx + b确定与水平线交叉的垂直坐标,以及与垂直线交叉的水平分量。 其中只有一个实际上会在您的矩形上(即包含在其中一个矩形边缘内),或者它将在一个角上相交。