如何找到半径为16(x; z)的给定点的中心点?

时间:2016-04-04 12:39:37

标签: java coordinates coordinate-systems

我试图打印出中心点的位置。比较点的半径必须为16.只有当从中心计算一个位置的点数超过5个时才打印出来。

Center dot is, which is nearest to all nearby dots

我的代码给了我好处的正面和重复。方法:

HashMap<Location, HashSet<Location>> map = new HashMap<Location, HashSet<Location>>();
for (LocationCopy loc : locs) {
        HashSet<LocationCopy> locsCopy = new HashSet<LocationCopy>(locs);
        locsCopy.remove(loc);
        for (LocationCopy loc2 : locsCopy) {
            if (distance(loc2.getX(),loc.getX(),loc2.getZ(),loc.getZ()) <= 16) {
                if (!map.containsKey(loc.getLoc())) {
                    HashSet<Location> hs = new HashSet<Location>();
                    hs.add(loc2.getLoc());
                    map.put(loc2.getLoc(), hs);
                } else {
                    HashSet<Location> hs = map.get(loc.getLoc());
                    hs.add(loc2.getLoc());
                    map.put(loc2.getLoc(), hs);
                }
            }
        }

    }

    for (Location loc : map.keySet()) {
        if (map.get(loc).size() > 5) {
            write("More than " + map.get(loc).size() + locToString(loc) + ": " + getLocs(map.get(loc)) + "<br>", fileName, beta);
        }
    }

private double distance(double x1, double x2, double z1, double z2){
    return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(z2-z1,2));
}

类别:

public class LocationCopy {
    private int x, y, z;
    private String world;

    public LocationCopy(int x, int y, int z, String world) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.world = world;
    }

    public LocationCopy(Location spawner) {
        this.x = spawner.getBlockX();
        this.y = spawner.getBlockY();
        this.z = spawner.getBlockZ();
        this.world = spawner.getWorld().getName();
    }

    public int getX(){
        return x;
    }

    public int getZ(){
        return z;
    }

    public Location getLoc() {
        return new Location(Bukkit.getWorld(world), x, y, z);
    }

}

1 个答案:

答案 0 :(得分:0)

您的代码中存在一些小问题:

  • internal static Project GetActiveProject() { DTE dte = Package.GetGlobalService(typeof(SDTE)) as DTE; return GetActiveProject(dte); } internal static Project GetActiveProject(DTE dte) { Project activeProject = null; Array activeSolutionProjects = dte.ActiveSolutionProjects as Array; if (activeSolutionProjects != null && activeSolutionProjects.Length > 0) { activeProject = activeSolutionProjects.GetValue(0) as Project; } return activeProject; } 应该改为map.put(loc2.getLoc(), hs);
  • 您需要向类中添加map.put(loc.getLoc(), hs);方法,因为您使用的其他hashCode不能识别代表相同位置的对象
  • 您仅搜索点组,而不搜索其中心

一种解决方案如下所示(在LocationCopy类中实现了您的方法,因为您的问题中未显示任何类):

HashSet

Location类(重要的部分是import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; public class LocationCopy { private int x, y, z; //private String world; public LocationCopy(int x/*, int y*/, int z/*, String world*/) { this.x = x; //this.y = y; this.z = z; //this.world = world; } public LocationCopy(Location spawner) { this.x = spawner.getBlockX(); this.y = spawner.getBlockY(); this.z = spawner.getBlockZ(); //this.world = spawner.getWorld().getName(); } //EDIT added toString method (just for better printing and debugging) @Override public String toString() { return "LocationCopy [x=" + x + ", y=" + y + ", z=" + z + "]"; } //EDIT: added hashCode method that is needed for the HashSets to identify objects that represent the same location @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + x; result = prime * result + y; result = prime * result + z; return result; } //EDIT: added equals method (not really needed, but better to have one...) @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; LocationCopy other = (LocationCopy) obj; if (x != other.x) return false; if (y != other.y) return false; if (z != other.z) return false; return true; } public int getX() { return x; } public int getZ() { return z; } public Location getLoc() { return new Location(x, y, z); } public static void main(String[] args) { List<LocationCopy> locs = createLocs(); HashMap<Location, HashSet<Location>> map = new HashMap<Location, HashSet<Location>>(); for (LocationCopy loc : locs) { HashSet<LocationCopy> locsCopy = new HashSet<LocationCopy>(locs); locsCopy.remove(loc); for (LocationCopy loc2 : locsCopy) { if (distance(loc2.getX(), loc.getX(), loc2.getZ(), loc.getZ()) <= 16) { if (!map.containsKey(loc.getLoc())) { HashSet<Location> hs = new HashSet<Location>(); hs.add(loc2.getLoc()); map.put(loc.getLoc(), hs);//EDIT: changed loc2 to loc } else { HashSet<Location> hs = map.get(loc.getLoc()); hs.add(loc2.getLoc()); map.put(loc.getLoc(), hs);//EDIT: changed loc2 to loc } } } } //EDIT: selecting groups for finding the center Set<Set<Location>> groups = new HashSet<Set<Location>>(); for (Location loc : map.keySet()) { if (map.get(loc).size() > 5) { //EDIT: don't know what write does -> using System.out.println instead //write("More than " + map.get(loc).size() + locToString(loc) + ": " + getLocs(map.get(loc)) + "<br>", fileName, beta); System.out.println("More than " + map.get(loc).size() + " " + locToString(loc) + ": " + /*getLocs(map.get(loc)) + */"<br>"); //EDIT: create groups to find the center points Set<Location> group = new HashSet<Location>(); group.addAll(map.get(loc)); group.add(loc); groups.add(group); } } //EDIT: find the center of the group for (Set<Location> group : groups) { Location center = findCenter(group); System.out.println("center found: " + center); } } /** * Find the center of each group by calculating the summed distance from each point to every other point. * * The point that has the minimum summed distance to every other point is the center. */ private static Location findCenter(Set<Location> group) { if (group.isEmpty()) { throw new IllegalArgumentException("The group mussn't be empty"); } List<LocationDistance> summedDistances = new ArrayList<LocationDistance>(group.size()); for (Location loc : group) { LocationDistance dist = new LocationDistance(loc, 0); //sum up the distance to each location in the group for (Location loc2 : group) { double distance = distance(loc.getBlockX(), loc2.getBlockX(), loc.getBlockZ(), loc2.getBlockZ()); dist.setDistance(dist.getDistance() + distance); } summedDistances.add(dist); } //sort the list (LocationDistance implements Comparable to do this) Collections.sort(summedDistances); //the first item in the list is the center return summedDistances.get(0).getLocation(); } private static List<LocationCopy> createLocs() { List<LocationCopy> locs = new ArrayList<LocationCopy>(); //trying to create the example from the image in your question locs.add(new LocationCopy(0, 0)); locs.add(new LocationCopy(2, 0)); locs.add(new LocationCopy(5, 0)); locs.add(new LocationCopy(1, 2)); locs.add(new LocationCopy(2, 1));//center locs.add(new LocationCopy(4, 1)); locs.add(new LocationCopy(3, 2));//adding a new point because otherwhise it will never be enough for a group greater than 5 locs.add(new LocationCopy(10, 30)); locs.add(new LocationCopy(12, 31)); locs.add(new LocationCopy(15, 31)); locs.add(new LocationCopy(8, 36)); locs.add(new LocationCopy(13, 33));//center locs.add(new LocationCopy(18, 34)); locs.add(new LocationCopy(15, 36));//adding a new point because otherwhise it will never be enough for a group greater than 5 return locs; } private static String locToString(Location loc) { return loc.getBlockX() + " " + loc.getBlockY() + " " + loc.getBlockZ(); } private static double distance(double x1, double x2, double z1, double z2) { return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(z2 - z1, 2)); } } 方法):

hashCode

和一个用于比较距离的新类LocationDistance:

public class Location {

    public int x, y, z;

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

    public int getBlockX() {
        return x;
    }

    public int getBlockY() {
        return y;
    }

    public int getBlockZ() {
        return z;
    }

    @Override
    public String toString() {
        return "Location [x=" + x + ", y=" + y + ", z=" + z + "]";
    }

    //EDIT here the hashCode is also important for the HashSets you use in your code
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + x;
        result = prime * result + y;
        result = prime * result + z;
        return result;
    }

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

输出为:

/**
 * A class for comparing the distances for locations
 */
public class LocationDistance implements Comparable<LocationDistance> {

    private Location location;
    private double distance;

    public LocationDistance(Location location, double distance) {
        this.location = location;
        this.distance = distance;
    }

    @Override
    public String toString() {
        return "LocationDistance [location=" + location + ", distance=" + distance + "]";
    }

    @Override
    public int compareTo(LocationDistance other) {
        return Double.compare(distance, other.getDistance());
    }

    public Location getLocation() {
        return location;
    }
    public void setLocation(Location location) {
        this.location = location;
    }

    public double getDistance() {
        return distance;
    }
    public void setDistance(double distance) {
        this.distance = distance;
    }
}

最后两行是您要搜索的中心。