From 843bfece295b61090966ad8365270a3c6e4aba8d Mon Sep 17 00:00:00 2001 From: John Robert McDonough Date: Mon, 8 Apr 2024 18:19:43 +0000 Subject: [PATCH] Update MyCanvas.java --- src/edu/bu/ec504/hw3/p2/MyCanvas.java | 89 +++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 6 deletions(-) diff --git a/src/edu/bu/ec504/hw3/p2/MyCanvas.java b/src/edu/bu/ec504/hw3/p2/MyCanvas.java index 9ad762a..76cd415 100644 --- a/src/edu/bu/ec504/hw3/p2/MyCanvas.java +++ b/src/edu/bu/ec504/hw3/p2/MyCanvas.java @@ -1,6 +1,11 @@ +// referencing: https://stackoverflow.com/questions/15882202/minimum-number-of-circles-with-radius-r-to-cover-n-points + package edu.bu.ec504.hw3.p2; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; public class MyCanvas extends Canvas { @@ -17,12 +22,84 @@ public class MyCanvas extends Canvas { @Override public ArrayList generateCovering() { - // This demo implementation generates a trivial covering, where there is - // a circle around each point. - ArrayList centers = new ArrayList<>(); - for (CanvasPoint pnt: this) { - centers.add(new CanvasPoint(pnt.x, pnt.y)); + + ArrayList coveredPoints = new ArrayList<>(); + ArrayList selectedCircles = new ArrayList<>(); + Map> circleCandidates = new HashMap<>(); + + // generate 10 circles for each point whose center is within a radius distance from the point + for (CanvasPoint point : this) { + // store generated circles in list + ArrayList circlesForPoint = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + // generate random distance, angle of new circle from current point + double angle = rand.nextDouble() * 2 * Math.PI; + double distance = rand.nextDouble(); + + // generate the center of the new circle based on the angle, distance, and current point + double centerX = point.x + distance * Math.cos(angle); + double centerY = point.y + distance * Math.sin(angle); + CanvasPoint circleCenter = new CanvasPoint(centerX, centerY); + circlesForPoint.add(circleCenter); + } + // add all generated circles for a given point to HashMap + circleCandidates.put(point, circlesForPoint); } - return centers; + + // trim the list of circles to the minimum number that covers all points + while (coveredPoints.size() < this.points.size()) { + + // find the current circle that covers most points + CanvasPoint bestCircle = null; + int maxCover = 0; + + // for every proposed circle... + for (Map.Entry> entry : circleCandidates.entrySet()) { + // ... track the number of points it covers... + for (CanvasPoint candidateCenter : entry.getValue()) { + // ... and update the number of new points it covers + int coverCount = 0; + for (CanvasPoint point : this.points) { + if (!coveredPoints.contains(point) && _distance(candidateCenter, point) < 1.0f) { + coverCount++; + } + } + + // track the circle found to cover the most points + if (coverCount > maxCover) { + maxCover = coverCount; + bestCircle = candidateCenter; + } + } + } + + // find the points covered by the selected circle + // add the circle to the list to return and update the points that are covered + if (bestCircle != null) { + selectedCircles.add(bestCircle); // Add the center of the selected circle to the list + for (CanvasPoint point : this.points) { + if (_distance(bestCircle, point) < 1.0f && !coveredPoints.contains(point)) { + coveredPoints.add(point); + } + } + } + + // exit if no new circle was found + else { + break; + } + } + + return selectedCircles; } + + private double _distance(CanvasPoint pnt1, CanvasPoint pnt2) { + return Math.sqrt( + Math.pow(pnt1.x - pnt2.x,2) + + Math.pow(pnt1.y - pnt2.y,2) + ); + } + + //FIELDS + private final Random rand = new Random(); } -- GitLab