线穿过矩形 - 如何找到交叉点? [英] Line crosses Rectangle - how to find the cross points?

查看:143
本文介绍了线穿过矩形 - 如何找到交叉点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

现在,我想



我怎么能做到这一点? / b>

示例


  • 矩形可以由2分: Pstart(1,3) Pend(3,
    1)

  • 中心点可以计算为: P(2,2)

  • P(2,2) Q(10,2)

  • ul>

    据我所知矩形的宽度是2,我可以告诉行开始于 P(4,2)而不是 P(2,2)



    当点不平行于点的XY轴。此外,矩形内的长度对于对角线的数量将不同。



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



    也许我必须找到线穿过矩形的点,然后让在交叉点开始行。但是,我怎么能得到这一点?

    解决方案

老实说,我不明白数学,但...



基本上,你有5行。原始线和矩形的4行。所以,如果你把它分解成一个简单的线条交叉线问题,它应该变得更容易... ...
$ b


  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();

$ b $ public IntersectPoint(){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
尝试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
}

JFrame框架= 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); (Point2D p:ps){
if(p!= null){
g2d.fill(new Ellipse2D.Double(p.getX() - 4,p.getY() - 4,8,8));
}
}
g2d.dispose();


$ b public Point2D [] getIntersectionPoint(Line2D line,Rectangle2D rectangle){

Point2D [] p = new Point2D [4];
$ b $ //第一行
p [0] = getIntersectionPoint(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY (),
rectangle.getX()+ rectangle.getWidth(),
rectangle.getY()));
//底线
p [1] = getIntersectionPoint(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY()+ rectangle .getHeight(),
rectangle.getX()+ rectangle.getWidth(),
rectangle.getY()+ rectangle.getHeight()));
//左边...
p [2] = getIntersectionPoint(line,
new Line2D.Double(
rectangle.getX(),
rectangle.getY ),
rectangle.getX(),
rectangle.getY()+ rectangle.getHeight()));
//右侧
p [3] = getIntersectionPoint(line,
new Line2D.Double(
rectangle.getX()+ rectangle.getWidth(),
rectangle .getY(),
rectangle.getX()+ rectangle.getWidth(),
rectangle.getY()+ rectangle.getHeight()));

return p;


$ b $ 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); (x1 - x2)*(x3 * y4 - y3 * x4) ))/ d; (y3 - y4)*(x1 * y2 - y1 * x2) - (y1 - y2)*(x3 * y4 - y3 * x4))/ d;
double yi =

p = new Point2D.Double(xi,yi);

}
return p;
}
}
}


I'm drawing a rectangle onto a canvas and a line from the center of the rectangle to some random point in the coordinate space.

Now, I want to truncate the line by the length that is inside the rectangle so that the line starts at the rectangle edge.

How could I do this?

Example

  • The rectangle could be defined by 2 points: Pstart(1, 3), Pend(3, 1)
  • The center point can be computed to : P(2, 2)
  • Now draw the line from P(2, 2) to Q(10, 2).

As I know the width of the rectangle is 2, I could tell the line to start at P(4, 2) instead of P(2, 2).

This gets more complicated when the point is not parallel to one of the XY axis. Moreover the length inside the rectangle will be different amount for diagonal lines.

How can I calculate the start offset for the line point with respect to the center of the rectangle and the end point of the line?

Probably I'd have to find the point where the line would cross the rectangle, and then just let the line start at the cross point. But how could I get this point?

解决方案

Honestly, I don't understand the maths, but...

Essentially, you have 5 lines. The original line and the 4 lines of the rectangle. So if you break it down to a simple line intersection of line problem it should become a little easier...

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;
        }
    }
}

这篇关于线穿过矩形 - 如何找到交叉点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆