简体   繁体   English

查找给定坐标的四边形的面积

[英]Find area of quadrilateral given coordinates the of vertices

I'm a student learning Java, and I had a question about an example we did in class. 我是一名学习Java的学生,并且对我们在课堂上做的一个示例有疑问。

The goal of the exercise was to get the (x, y) coordinates of the 4 vertices of a quadrilateral through user interaction, with which we would then find the area of the shape. 练习的目的是通过用户交互来获取四边形的4个顶点的(x,y)坐标,然后我们可以通过该坐标找到形状的面积。

I think I'm on the right track with my logic: start with the Scanner class in order to initiate user interaction to get the coordinates, then once you have all 4 X-values and Y-values, do the appropriate subtractions to figure out the length of each side at which point you can figure out the area. 我认为我的逻辑是正确的:从Scanner类开始以启动用户交互以获取坐标,然后在获得所有4个X值和Y值后,进行适当的减法计算每边的长度,您可以在该点算出面积。

I'm stuck on where I'm supposed to save the user inputs of each vertex's coordinates. 我被困在应该保存每个顶点坐标的用户输入的位置。 Initializing different integer variables for each coordinate seems a little excessive and redundant but I cannot figure out how he wants us to complete this. 为每个坐标初始化不同的整数变量似乎有点多余和多余,但是我无法弄清楚他希望我们如何完成此工作。

So far my code looks like this: 到目前为止,我的代码如下所示:

    import java.util.Scanner;
    public class Assign03OOP {
        public static void main (String args []) {
            Scanner userInputStream = new Scanner(System.in);
            int vertexA, vertexB, vertexC, vertexD, (x, y);
            double area, userInput;
            double [] pointA = {,}, pointB = {,}, pointC = {,}, pointD = 
                      {,};
            System.out.println("Recording Vertex A: \nEnter X Value: ");
            userInput = userInputStream.nextDouble();
            while (x != 0; y!0=;) {
                pointA = (x * y)
            }
    }
}

Decompose the quadrilateral in two triangles. 将四边形分解为两个三角形。 The area of a triangle is half the area of the parallelogram constructed on two sides, itself obtained as the cross product of the two corresponding vectors. 三角形的面积是在两侧构造的平行四边形面积的一半,平行四边形本身是作为两个相应矢量的叉积获得的。

Another way to do it is to convert the area integral to a contour integral using Green's Theorem . 另一种方法是使用格林定理将面积积分转换为轮廓积分。 You can use Gaussian quadrature to integrate along the edges of the quadrilateral to get the area. 您可以使用高斯求积沿四边形的边缘进行积分以获得面积。 This works with any flat polygon: triangle, quadrilateral, etc. 这适用于任何平面多边形:三角形,四边形等。

I think it would be appropriate to use actual objects to represent your points and quadrilaterals. 我认为使用实际对象表示您的点和四边形是合适的。

Using objects can make the code much clearer and easier to test. 使用对象可以使代码更加清晰和易于测试。

package com.stackoverflow.so47518648;

import java.util.Arrays;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@SuppressWarnings("javadoc")
public class Answer {

    // Allow user to quit by entering Q or q
    static final Pattern SCANNER_QUIT_PATTERN = Pattern.compile("^q$", Pattern.CASE_INSENSITIVE);

    // Use of named-capturing groups, in this case 'x' and 'y' requires java 7
    static final Pattern SCANNER_INPUT_PATTERN = Pattern.compile("(?<x>\\d+),\\s*(?<y>\\d+)");

    public static void main(String... args) {

        try (Scanner sc = new Scanner(System.in)) {

            Quadrilateral quadrilateral = promptForQuadrilateral(sc);
            System.out.println("Finding area for: " + quadrilateral);

            double area = quadrilateral.area();
            System.out.println("The area of " + quadrilateral + " is :" + area);

        } catch (UserQuit userQuit) {
            System.out.println(userQuit.getMessage());
        }
    }

    static Quadrilateral promptForQuadrilateral(Scanner sc) {

        Point a = promptForPoint(sc, "A");
        Point b = promptForPoint(sc, "B");
        Point c = promptForPoint(sc, "C");
        Point d = promptForPoint(sc, "D");

        Quadrilateral q = new Quadrilateral(a, b, c, d);

        return q;
    }

    static Point promptForPoint(Scanner sc, String vertexName) {

        while (true) {

            System.out.println("Enter the coordinates for " + vertexName + " (x,y) or q to quit: ");

            String coordinates = sc.findInLine(SCANNER_INPUT_PATTERN);

            if (coordinates != null) {
                sc.nextLine();

                Matcher matcher = SCANNER_INPUT_PATTERN.matcher(coordinates);
                matcher.matches();

                int x = Integer.parseInt(matcher.group("x"));
                int y = Integer.parseInt(matcher.group("y"));

                Point point = new Point(x, y);

                System.out.println("For " + vertexName + " you entered: " + point);

                return point;
            } else if (sc.findInLine(SCANNER_QUIT_PATTERN) != null) {
                throw new UserQuit();
            } else {
                // Reprompt when invalid input is received
                sc.next();
            }

        }
    }

    public static class UserQuit extends RuntimeException {
        public UserQuit() {
            super("User quit.");
        }
    }

    public static class DuplicatePoints extends RuntimeException {
        public DuplicatePoints(Point... points) {
            super("Cannot create quadrilaterl with duplicate points: " + Arrays.toString(points));
        }
    }

    public static class Point {

        public final int x;
        public final int y;

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        double distance(Point p1, Point p2) {
            return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
        }

        /**
         * Distance from this point to the supplied point.
         *
         * @param that the that
         * @return the double
         */
        public double distance(Point that) {

            return distance(this, that);
        }

        @Override
        public String toString() {
            return "(x=" + this.x + ", y=" + this.y + ")";
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + this.x;
            result = prime * result + this.y;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

    }

    public static class Quadrilateral {

        public final Point a;
        public final Point b;
        public final Point c;
        public final Point d;

        public Quadrilateral(Point a, Point b, Point c, Point d) {

            validatePoints(a, b, c, d);

            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
        }

        static void validatePoints(Point a, Point b, Point c, Point d) {

            // throw exceptions if we can't construct a quadrilateral (duplicate points, etc)

            // Duplicate points check
            Point[] points = { a, b, c, d };
            if (Arrays.stream(points)
                .distinct()
                .count() != 4) {
                throw new DuplicatePoints(points);
            }

        }

        static double calulateArea(Quadrilateral quadrilateral) {

            return calulateArea(quadrilateral.a, quadrilateral.b, quadrilateral.c, quadrilateral.d);
        }

        static double calulateArea(Point a, Point b, Point c, Point d) {

            // do calculation here.
            return 0.0;

        }

        public double area() {
            return calulateArea(this);
        }

        @Override
        public String toString() {
            return "a=" + this.a + ", b=" + this.b + ", c=" + this.c + ", d=" + this.d;
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM