public static class Coordinates {
public Coordinates() {
}
public Coordinates(double x, double y) {
this.x = x
this.y = y
}
protected double x, y
public double getX() {
return x
}
public void setX(double x) {
this.x = x
}
public double getY() {
return y
}
public void setY(double y) {
this.y = y
}
}
/**
* 有一个n边形(P0, P1, ..., Pn), 每一条边皆为垂直或水平线段。现给定数值k,以P0为起点将n边形的周长分为k段,每段的长度相等,请打印出k等分点的坐标(T0, T1, ..., Tk)的坐标。
*/
@Test
public void test1() {
List<Coordinates> list = new ArrayList<>()
list.add(new Coordinates(0, 0))
list.add(new Coordinates(0, 3))
list.add(new Coordinates(3, 3))
list.add(new Coordinates(3, 4))
list.add(new Coordinates(4, 4))
list.add(new Coordinates(4, 2))
list.add(new Coordinates(6, 2))
list.add(new Coordinates(6, 0))
//周长
int perimeter = 0
int num = 10
List<Coordinates> result = new ArrayList<>(num - 1)
for (int i = 0
Coordinates last = i == 0 ? list.get(list.size() - 1) : list.get(i - 1)
if (list.get(i).getX() == last.getX()) {
perimeter += Math.abs(list.get(i).getY() - last.getY())
} else {
perimeter += Math.abs(list.get(i).getX() - last.getX())
}
}
double diff = perimeter * 1.0 / num
double l = 0
//上个点位
Coordinates last = list.get(0)
//当前点位
Coordinates now
//多边形顶点序号
int i = 1
//多出长度,需算入下次计算
double t = 0
while (i <= list.size()) {
now = i == list.size() ? list.get(0) : list.get(i)
//两点 垂直水平
if (now.getX() == last.getX()) {
l = Math.abs(now.getY() - last.getY())
//上次计算多出长度+边长 > 平均值时,期间有均分点
if (t + l >= diff) {
//向上延伸 则 上一点y+均值-上次多出长度 = 均分点y 否则 上一点y—(均值-上次多出长度) = 均分点y
double y = now.getY() - last.getY() > 0 ? (last.getY() + diff - t) : (last.getY() + t - diff)
last = new Coordinates(now.getX(), y)
result.add(last)
t = 0
} else {
last = now
i++
t = t + l
}
} else {//两点水平
l = Math.abs(now.getX() - last.getX())
//上次计算多出长度+边长 > 平均值时,期间有均分点
if (t + l >= diff) {
//向右延伸 则 上一点x+均值-上次多出长度 = 均分点x 否则 上一点x—(均值-上次多出长度) = 均分点x
double x = now.getX() - last.getX() > 0 ? (last.getX() + diff - t) : (last.getX() + t - diff)
//以均分点为起点,进行下次计算
last = new Coordinates(x, now.getY())
result.add(last)
t = 0
} else {//期间没有均分点,寻找下个顶点
last = now
i++
t = t + l
}
}
}
JLogger.debug(JSONObject.toJSONString(result))
}