最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Why is my javafx code not correctly identifying and connecting my maximal points? - Stack Overflow

programmeradmin1浏览0评论

I have been working on this for days and can't figure it out (it is a school project).

For this project, a maximal point is defined as any point that has no other points above it or to the right of it. Instructions state to determine the set of maximal points among a set of points displayed in a Java window. All maximal points are to be connected by lines.

For context, this is what the result SHOULD look like:

And this is the result I'm getting with my code:

This is the set of points that I was given to use and that should produce the Sample run's correct output:

200.0 300.0
250.0 300.0
330.0 270.0
150.0 380.0
126.0 172.0
397.0 379.0
334.0 441.0
53.0 288.0
89.0 433.0
182.0 215.0
251.0 414.0

Here's my code:

Main.java

//Main.java

package application;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        List<Point> points = readPointsFromFile("points.txt");
        MaximalPointsPane pane = new MaximalPointsPane(points);

        Scene scene = new Scene(pane);
        primaryStage.setTitle("Maximal Points Visualization");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private List<Point> readPointsFromFile(String filename) {
        List<Point> points = new ArrayList<>();
        try (Scanner scanner = new Scanner(new File(filename))) {
            while (scanner.hasNextDouble()) {
                double x = scanner.nextDouble();
                double y = scanner.nextDouble();
                points.add(new Point(x, y));
            }
        } catch (FileNotFoundException e) {
            System.out.println("File not found: " + filename);
        }
        return points;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

MaximalPointsPane.java

//MaximalPointsPane.java

package application;

import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseButton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MaximalPointsPane extends Pane {
    private List<Point> points = new ArrayList<>();

    public MaximalPointsPane(List<Point> initialPoints) {
        this.points.addAll(initialPoints);
        setPrefSize(500, 500);
        draw();

        setOnMouseClicked(event -> {
            double x = event.getX();
            double y = event.getY();

            if (event.getButton() == MouseButton.PRIMARY) {
                points.add(new Point(x, y)); // Add point
            } else if (event.getButton() == MouseButton.SECONDARY) {
                points.removeIf(p -> Math.hypot(p.getX() - x, p.getY() - y) < 10); // Remove closest point
            }

            draw();
        });
    }

    private void draw() {
        getChildren().clear();
        
        // Draw points
        for (Point p : points) {
            Circle circle = new Circle(p.getX(), p.getY(), 4, Color.BLACK);
            getChildren().add(circle);
        }

        // Find maximal points and draw connecting lines
        List<Point> maximalPoints = findMaximalPoints();
        for (int i = 0; i < maximalPoints.size() - 1; i++) {
            Point p1 = maximalPoints.get(i);
            Point p2 = maximalPoints.get(i + 1);
            Line line = new Line(p1.getX(), p1.getY(), p2.getX(), p2.getY());
            line.setStroke(Color.BLACK);
            getChildren().add(line);
        }
    }

    private List<Point> findMaximalPoints() {
        List<Point> maximal = new ArrayList<>();

        for (Point p1 : points) {
            boolean isMaximal = true;
            for (Point p2 : points) {
                if (p1.isDominatedBy(p2)) {
                    isMaximal = false;
                    break;
                }
            }
            if (isMaximal) maximal.add(p1);
        }

        Collections.sort(maximal);
        return maximal;
    }
}

Point.java

//Point.java

package application;

import java.util.Objects;

public class Point implements Comparable<Point> {
    private final double x;
    private final double y;

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

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public boolean isDominatedBy(Point other) {
        return (this.x < other.x && this.y <= other.y) || (this.x <= other.x && this.y < other.y);
    }

    @Override
    public int compareTo(Point other) {
        return Doublepare(this.x, other.x);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Point point = (Point) obj;
        return Doublepare(point.x, x) == 0 && Doublepare(point.y, y) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

I have been working on this for days and can't figure it out (it is a school project).

For this project, a maximal point is defined as any point that has no other points above it or to the right of it. Instructions state to determine the set of maximal points among a set of points displayed in a Java window. All maximal points are to be connected by lines.

For context, this is what the result SHOULD look like:

And this is the result I'm getting with my code:

This is the set of points that I was given to use and that should produce the Sample run's correct output:

200.0 300.0
250.0 300.0
330.0 270.0
150.0 380.0
126.0 172.0
397.0 379.0
334.0 441.0
53.0 288.0
89.0 433.0
182.0 215.0
251.0 414.0

Here's my code:

Main.java

//Main.java

package application;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        List<Point> points = readPointsFromFile("points.txt");
        MaximalPointsPane pane = new MaximalPointsPane(points);

        Scene scene = new Scene(pane);
        primaryStage.setTitle("Maximal Points Visualization");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private List<Point> readPointsFromFile(String filename) {
        List<Point> points = new ArrayList<>();
        try (Scanner scanner = new Scanner(new File(filename))) {
            while (scanner.hasNextDouble()) {
                double x = scanner.nextDouble();
                double y = scanner.nextDouble();
                points.add(new Point(x, y));
            }
        } catch (FileNotFoundException e) {
            System.out.println("File not found: " + filename);
        }
        return points;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

MaximalPointsPane.java

//MaximalPointsPane.java

package application;

import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseButton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MaximalPointsPane extends Pane {
    private List<Point> points = new ArrayList<>();

    public MaximalPointsPane(List<Point> initialPoints) {
        this.points.addAll(initialPoints);
        setPrefSize(500, 500);
        draw();

        setOnMouseClicked(event -> {
            double x = event.getX();
            double y = event.getY();

            if (event.getButton() == MouseButton.PRIMARY) {
                points.add(new Point(x, y)); // Add point
            } else if (event.getButton() == MouseButton.SECONDARY) {
                points.removeIf(p -> Math.hypot(p.getX() - x, p.getY() - y) < 10); // Remove closest point
            }

            draw();
        });
    }

    private void draw() {
        getChildren().clear();
        
        // Draw points
        for (Point p : points) {
            Circle circle = new Circle(p.getX(), p.getY(), 4, Color.BLACK);
            getChildren().add(circle);
        }

        // Find maximal points and draw connecting lines
        List<Point> maximalPoints = findMaximalPoints();
        for (int i = 0; i < maximalPoints.size() - 1; i++) {
            Point p1 = maximalPoints.get(i);
            Point p2 = maximalPoints.get(i + 1);
            Line line = new Line(p1.getX(), p1.getY(), p2.getX(), p2.getY());
            line.setStroke(Color.BLACK);
            getChildren().add(line);
        }
    }

    private List<Point> findMaximalPoints() {
        List<Point> maximal = new ArrayList<>();

        for (Point p1 : points) {
            boolean isMaximal = true;
            for (Point p2 : points) {
                if (p1.isDominatedBy(p2)) {
                    isMaximal = false;
                    break;
                }
            }
            if (isMaximal) maximal.add(p1);
        }

        Collections.sort(maximal);
        return maximal;
    }
}

Point.java

//Point.java

package application;

import java.util.Objects;

public class Point implements Comparable<Point> {
    private final double x;
    private final double y;

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

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    public boolean isDominatedBy(Point other) {
        return (this.x < other.x && this.y <= other.y) || (this.x <= other.x && this.y < other.y);
    }

    @Override
    public int compareTo(Point other) {
        return Doublepare(this.x, other.x);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Point point = (Point) obj;
        return Doublepare(point.x, x) == 0 && Doublepare(point.y, y) == 0;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}
Share Improve this question edited Feb 4 at 19:16 Gilbert Le Blanc 51.6k6 gold badges73 silver badges117 bronze badges asked Feb 4 at 18:58 Elaine ShieldsElaine Shields 511 silver badge1 bronze badge 3
  • 3 Elaine, the best thing to do with this kind of problem is to step through your code with your debugger. That will let you see the values of all your variables at each step, and will show you clearly what's going differently from what you expect. – Dawood ibn Kareem Commented Feb 4 at 19:51
  • In general, that is pretty good advice. I'm trying to decide if it would actually lead to the cause of the problem in this case and I'm not sure. You might need to do something such as highlighting the points that dominate a point which you expect to be maximal but which is not detected as such to get to understand the issue. – James_D Commented Feb 4 at 19:59
  • 1 I'm wondering if the problem description should be more clearly stated. Starting at the example's upper left, and following the line, what makes the 2nd point a maximal? How is the 1st point not above it? How is the 3rd point not to the right? Can a valid solution have the line continuing horizontally from the 1st line, and then turning straight down? Can a line be drawn directly from the 1st to the 2nd, rather than having right angle turns? – Old Dog Programmer Commented Feb 4 at 23:43
Add a comment  | 

1 Answer 1

Reset to default 5

You define a maximal point as one for which there no points that are both to its right and above it. Your Point method boolean isDominatedBy(Point other) is designed to check if other prevents this point from being maximal, i.e. if other is both to the right of and above this point.

Note that in computer graphics, the y coordinate increases as you move down, so the other point is above this point if this.y > other.y. So your definition of isDominatedBy(...) should be

public boolean isDominatedBy(Point other) {
    return (this.x < other.x && this.y >= other.y) || (this.x <= other.x && this.y > other.y);
}

This will give you the correct set of maximal points.

Also note that in the desired output image, maximal points are connected by two line segments (one vertical and one horizontal). The code in the question calculates only one line segment, directly joining two consecutive maximal points. Fixing this is left as an exercise for the reader.

发布评论

评论列表(0)

  1. 暂无评论