7

キャンバスに長方形を描き、長方形の中心から座標空間のランダムな点まで線を描きます。

ここで、線が長方形の端から始まるように、長方形の内側の長さで線を切り捨てたいと思います。

どうすればこれを行うことができますか?

  • 長方形は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つに平行でない場合、これはより複雑になります。さらに、長方形の内側の長さは、対角線に対して異なる量になります。

長方形の中心と線の終点を基準にした線点の開始オフセットを計算するにはどうすればよいですか?

おそらく、線が長方形と交差する点を見つけて、線を交差点から開始する必要があります。しかし、どうすればこの点を得ることができますか?

4

3 に答える 3

14

正直なところ、数学はわかりませんが...

基本的に、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;
        }
    }
}
于 2013-03-24T03:10:58.267 に答える
3

長方形による線クリッピングに使用されるLiang-Barskyアルゴリズムを見てください。

于 2013-03-24T07:36:43.760 に答える
0

長方形の頂点:a、b、c、d。ax、ayなどのようにそれぞれのx座標とy座標を表します。

線の端点:x、y

線はy=mx + bに従い、上または下、右または左に移動します。これにより、交差する可能性のある長方形のエッジが2に絞り込まれます。

y = mx + bを使用して、水平線と交差する垂直座標と、垂直線と交差する水平成分を決定します。これらの1つだけが実際に長方形上にある(つまり、長方形のエッジの1つに含まれている)か、コーナーで交差します。

于 2013-03-24T02:30:52.457 に答える