我试图打印出中心点的位置。比较点的半径必须为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);
}
}
答案 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;
}
}
最后两行是您要搜索的中心。