Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6819407
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T21:18:11+00:00 2026-05-26T21:18:11+00:00

I have a program where an entity moves around in two-dimensional space. To move

  • 0

I have a program where an entity moves around in two-dimensional space. To move one step, the entity picks its next point, and then sets it as his current point.

Sometimes, however, the entity’s next point lies in an Area (java.awt.geom.Area) that is forbidden (the “forbidden area” is actually a velocity obstacle).

How can the entity pick the point outside the Area which is closest to the entity’s preferred point?

The Area is composed of different shapes (sometimes, the shapes are not touching).

My initial plan was to simply draw a line to the preferred point. Wherever the line intersected the Area first, this would be the next-best point. However, finding the intersection between a line and an Area turns out to be quite complex.

EDIT: This wouldn’t necessarily find the closest point. This would just find the closet point on the same trajectory. I’m looking for the closest possible point.

Perhaps Area isn’t the best class to use. All I require is something that can add multiple shapes, even when the shapes aren’t touching.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T21:18:11+00:00Added an answer on May 26, 2026 at 9:18 pm

    I’ve solved the problem:

    First, find all the line segments that constrain the Area. I’ve written code to do that on a different answer.

    Then, it’s just a matter of iterating through each line segment, and recording the point on the segment that’s closest to the entity’s desired point. Store these in the data structure of your choice (e.g., an ArrayList).

    See: Shortest distance between a point and a line segment

    Lastly, determine which of the points is closest to the desired point. Voilà!

    Here’s a demonstration:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.geom.Area;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Line2D;
    import java.awt.geom.Path2D;
    import java.awt.geom.PathIterator;
    import java.awt.geom.Point2D;
    import java.util.ArrayList;
    import java.util.Random;
    
    import javax.swing.JFrame;
    
    public class AreaTest extends JFrame{
        private static final long serialVersionUID = -2221432546854106311L;
    
        Area area = new Area();
        ArrayList<Line2D.Double> areaSegments = new ArrayList<Line2D.Double>();
        Point2D.Double insidePoint = new Point2D.Double(225, 225);
        Point2D.Double closestPoint = new Point2D.Double(-1, -1);
        Point2D.Double bestPoint = new Point2D.Double(-1, -1);
        ArrayList<Point2D.Double> closestPointList = new ArrayList<Point2D.Double>();
    
        AreaTest() {
            Path2D.Double triangle = new Path2D.Double();
            Random random = new Random();
    
            // Draw three random triangles
            for (int i = 0; i < 3; i++) {
                triangle.moveTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
                triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
                triangle.lineTo(random.nextInt(400) + 50, random.nextInt(400) + 50);
                triangle.closePath();
                area.add(new Area(triangle));
                triangle.reset();
            }
    
            // Place a point inside the area
            if (!area.contains(insidePoint)); {
                while (!area.contains(insidePoint)) {
                    insidePoint.setLocation(random.nextInt(400) + 50, random.nextInt(400) + 50);
                }
            }
    
            // Note: we're storing double[] and not Point2D.Double
            ArrayList<double[]> areaPoints = new ArrayList<double[]>();
            double[] coords = new double[6];
    
            for (PathIterator pi = area.getPathIterator(null); !pi.isDone(); pi.next()) {
    
                // Because the Area is composed of straight lines
                int type = pi.currentSegment(coords);
                // We record a double array of {segment type, x coord, y coord}
                double[] pathIteratorCoords = {type, coords[0], coords[1]};
                areaPoints.add(pathIteratorCoords);
            }
    
            double[] start = new double[3]; // To record where each polygon starts
            for (int i = 0; i < areaPoints.size(); i++) {
                // If we're not on the last point, return a line from this point to the next
                double[] currentElement = areaPoints.get(i);
    
                // We need a default value in case we've reached the end of the ArrayList
                double[] nextElement = {-1, -1, -1};
                if (i < areaPoints.size() - 1) {
                    nextElement = areaPoints.get(i + 1);
                }
    
                // Make the lines
                if (currentElement[0] == PathIterator.SEG_MOVETO) {
                    start = currentElement; // Record where the polygon started to close it later
                } 
    
                if (nextElement[0] == PathIterator.SEG_LINETO) {
                    areaSegments.add(
                            new Line2D.Double(
                                currentElement[1], currentElement[2],
                                nextElement[1], nextElement[2]
                            )
                        );
                } else if (nextElement[0] == PathIterator.SEG_CLOSE) {
                    areaSegments.add(
                            new Line2D.Double(
                                currentElement[1], currentElement[2],
                                start[1], start[2]
                            )
                        );
                }
            }
    
            // Calculate the nearest point on the edge
            for (Line2D.Double line : areaSegments) {
    
                // From: https://stackoverflow.com/questions/6176227
                double u = 
                  ((insidePoint.getX() - line.x1) * (line.x2 - line.x1) + (insidePoint.getY() - line.y1) * (line.y2 - line.y1))
                / ((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));
    
                double xu = line.x1 + u * (line.x2 - line.x1);
                double yu = line.y1 + u * (line.y2 - line.y1);
    
                if (u < 0) {
                    closestPoint.setLocation(line.getP1());
                } else if (u > 1) {
                    closestPoint.setLocation(line.getP2());
                } else {
                    closestPoint.setLocation(xu, yu);
                }
    
                closestPointList.add((Point2D.Double) closestPoint.clone());
    
                if (closestPoint.distance(insidePoint) < bestPoint.distance(insidePoint)) {
                    bestPoint.setLocation(closestPoint);
                }
            }
    
            setSize(new Dimension(500, 500));
            setLocationRelativeTo(null); // To center the JFrame on screen
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setResizable(false);
            setVisible(true);
        }
    
        public void paint(Graphics g) {
            // Fill the area
            Graphics2D g2d = (Graphics2D) g;
            g.setColor(Color.lightGray);
            g2d.fill(area);
    
            // Draw the border line by line
            g.setColor(Color.black);
            for (Line2D.Double line : areaSegments) {
                g2d.draw(line);
            }
    
            // Draw the inside point
            g.setColor(Color.red);
            g2d.fill(
                    new Ellipse2D.Double(
                            insidePoint.getX() - 3,
                            insidePoint.getY() - 3,
                            6,
                            6
                            )
                );
    
            // Draw the other close points
            for (Point2D.Double point : closestPointList) {
                g.setColor(Color.black);
                g2d.fill(
                        new Ellipse2D.Double(
                                point.getX() - 3,
                                point.getY() - 3,
                                6,
                                6
                                )
                    );
            }
    
            // Draw the outside point
            g.setColor(Color.green);
            g2d.fill(
                    new Ellipse2D.Double(
                            bestPoint.getX() - 3,
                            bestPoint.getY() - 3,
                            6,
                            6
                            )
                );
        }
    
        public static void main(String[] args) {
            new AreaTest();
        }
    }
    

    Here’s the result:

    enter image description here

    And again:

    enter image description here

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In my program I have two classes: Collector and Entity. Collector stores Entities in
I have two objects... and if I compile a program with either one, it
I have the following entity structure: Business --> Campaign --> Promotion, where ONE Business
In a vector graphics manipulation program, I have a Group entity which specifies groups
I'm developing a system in which I have an entity 'program' which has some
I have a pretty simple console project with an entity model (containing two simple
I have some Entities holding values for my program. E.g. a Person Entity has
I have program that has a variable that should never change. However, somehow, it
I have program, that must interact with a console program before my program can
I have program that runs fast enough. I want to see the number of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.