我正在 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;
            }
        }
    }
    

    07-24 19:06
    查看更多