2013-03-24 55 views
5

私はキャンバスに矩形を描画しています。矩形の中心から座標空間のランダムな点まで直線を描画しています。線の交点矩形 - 交点を見つける方法?

ここで、矩形内にある長さで線を切り詰めて、矩形の端から線が始まるようにしたいとします。

どうすればいいですか?矩形が2点によって定義することができる

  • 例:Pstart(1, 3)Pend(3, 1)

  • 中心点に計算することができる。P(2, 2)
  • すぐP(2, 2)からQ(10, 2)に線を引きます。

私は長方形の幅は2である知っているように、私はP(4, 2)代わりのP(2, 2)に開始する行を言うことができます。

ポイントがXY軸のいずれかと平行でない場合、これはより複雑になります。さらに、矩形内の長さは対角線に対して異なる量になる。

どのようにして、矩形の中心と線の終点に関して線の始点のオフセットを計算できますか?

おそらく、私は、線が矩形を横切る点を見つけて、次に線をクロス点で開始させる必要があります。しかし、どうすればこの点を得ることができますか?

+1

は、このページのソリューションの束があります。com/questions/1585525/how-to-find-the-a-line-and-a-rectangle あなたに最も合ったページのソリューションを選んで取得します。 – Michael

答えて

12

正直なところ、私はあなたが5行を持って、基本的に

を数学を理解し、しかし...はありません。元の行と四角形の4行。あなたはラインの問題のシンプルなラインの交点にそれを打破するのであれば、それは少し楽になるはずです...

enter image description here

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

getIntersectionPoint()関数は、行の1つが垂直か水平かを知っていれば大幅に簡略化できます。 –

+1

素敵な答え!ありがとう – user3197818

0

矩形の頂点:a、b、c、d。ラインの

エンドポイントなど、AY、斧のようなそれぞれのxおよびy COORDを表す:X、Y

線は、Y = MX + Bに従い、上下いずれか進み、右または左。これは、交差する可能性のある矩形の端を2に制限します。

y = mx + bを使用して、水平線を横切る垂直座標と垂直線を横切る水平成分を決定します。これらのうちの1つだけが実際にあなたの矩形上にある(つまり、矩形の辺の1つに含まれている)か、または角に交差します。

+0

実際には、直線が四角形の中央で始まるので、 'y = mx'だけ使うことができます – Breavyn

+0

私は数学を完全には取り上げていませんが、それはうまくいくとは思いません。 'b'オフセットは、x = 0、つまり傾き 'm'の線の垂直位置の 'y'座標を示します。これは、一般的な場合、どの矩形の辺が線で交差するかにはっきりと影響します。私は、これらのポイントのいずれかが原点にあると仮定していません。 – arcy

+0

矩形が原点を中心にしている場合は、b = 0と仮定できます。 –

3

矩形でラインクリッピングに使用Liang-Barsky algorithmを見てください。 ます。http:// stackoverflowの

関連する問題