海龟绘图
凸包计算 convexHull()
什么是凸包
如何计算凸包
1.判断点集内元素的个数
2.当多于三个点,寻找起始点
for(Point point : points) {//blPoint为左下角的点
if(blPoint == null){
blPoint = point;
continue;
}
if(blPoint.x() > point.x())
blPoint = point;
else if(blPoint.x() == point.x())
{
if(point.y() < blPoint.y())
blPoint = point;
}
}
turnPoint.add(blPoint); //最左下角点一定为凸包点集内的点,加入集合
nowPoint = blPoint;
angle = 0.0; //起始角度
点集遍历,按顺时针找到凸包点集的点
while(true)
{
nextangle = 360;
nextLength = Double.MAX_VALUE;
for(Point point : points)
{
if(point.equals(nowPoint))
continue;
nowangle = calculateBearingToPoint(angle,(int)nowPoint.x(),(int)nowPoint.y(),(int)point.x(),(int)point.y());
if(nowangle<0){//**nowangle为负数是要转换成正数**要不然会出现死循环
nowangle=360.0+nowangle;
}
if(nextangle == nowangle){//角度相等时 比较长度 选取较长的
if(nextLength < ((point.x()-nowPoint.x())*(point.x()-nowPoint.x())+(point.y()-nowPoint.y())*(point.y()-nowPoint.y()))
{
nextLength = (point.x()-nowPoint.x())*(point.x()-nowPoint.x())+(point.y()-nowPoint.y())*(point.y()-nowPoint.y());
nextPoint = point;
}
}
else if(nextangle > nowangle) {//角度不同时 选取角度较小的
nextLength = (point.x()-nowPoint.x())*(point.x()-nowPoint.x())+(point.y()-nowPoint.y())*(point.y()-nowPoint.y());
nextangle = nowangle;
nextPoint = point;
}
}
if(blPoint.equals(nextPoint))//当循环回到左下角的点时说明结束了
{
break;
}
nowPoint = nextPoint;
angle += nextangle;
angle =angle%360;//防止大于360度,但好像没用
turnPoint.add(nextPoint);
}
4.calculateBearingToPoint函数
写的较为繁琐...
public static double calculateBearingToPoint(double currentBearing, int currentX, int currentY,
int targetX, int targetY) {//计算两点旋转角度角度
if(currentX==targetX&¤tY==targetY){
System.out.println("是同一个点");
return 0.0;
}
double sum=0.0;
if(currentX<targetX¤tY<targetY){
double angle;
double b=targetY-currentY;
double c=targetX-currentX;
double a=Math.sqrt(c*c+b*b);
angle = Math.toDegrees(Math.acos((a * a + b * b - c * c) / (2 * a * b)));
sum = angle - currentBearing;
} else if (currentX>targetX¤tY<targetY) {
double angle;
double b=targetY-currentY;
double c=currentX-targetX;
double a=Math.sqrt(c*c+b*b);
angle = Math.toDegrees(Math.acos((a * a + b * b - c * c) / (2 * a * b)));
sum = 360.0 - currentBearing - angle;
} else if (currentX<targetX¤tY>targetY) {
double angle;
double b=currentY-targetY;
double c=targetX-currentX;
double a=Math.sqrt(c*c+b*b);
angle = Math.toDegrees(Math.acos((a * a + b * b - c * c) / (2 * a * b)));
sum = 180.0 - angle - currentBearing;
} else if (currentX>targetX & currentY>targetY) {
double angle;
double b=currentY-targetY;
double c=currentX-targetX;
double a=Math.sqrt(c*c+b*b);
angle = Math.toDegrees(Math.acos((a * a + b * b - c * c) / (2 * a * b)));
sum = 180 - currentBearing + angle;
}else if (targetX==currentX&targetY>currentY) {
sum=360.0-currentBearing;
} else if (targetX==currentX&targetY<currentY) {
sum=180-currentBearing;
} else if (targetX<currentX&targetY==currentY) {
sum=270-currentBearing;
} else if (targetX>currentX&targetY==currentY) {
sum=90-currentBearing;
}
if(sum%360==0.0){
sum=0.0;
}
return sum;
//throw new RuntimeException("implement me!");
}
返回数据
return turnlPoint;
测试类
@Test
public void convexHullTest() {
Set<Point> points = new HashSet<Point>();
Set<Point> convexHull = new HashSet<Point>();
assertEquals(convexHull, TurtleSoup.convexHull(points));
Point p11 = new Point(1, 1);
Point p1010 = new Point(10, 10);
Point p110 = new Point(1, 10);
Point p12 = new Point(1, 2);
Point p23 = new Point(2, 3);
Point p32 = new Point(3, 2);
points.add(p11);
convexHull.add(p11);
assertEquals(convexHull, TurtleSoup.convexHull(points));
points.add(p1010);
convexHull.add(p1010);
assertEquals(convexHull, TurtleSoup.convexHull(points));
points.add(p110);
convexHull.add(p110);
assertEquals(convexHull, TurtleSoup.convexHull(points));
points.add(p12);
assertEquals(convexHull, TurtleSoup.convexHull(points));
points.add(p23);
assertEquals(convexHull, TurtleSoup.convexHull(points));
points.add(p32);
convexHull.add(p32);
assertEquals(convexHull, TurtleSoup.convexHull(points));
}
CSDN-Ada助手: 恭喜您写了第6篇博客,正则表达式是一个非常实用的工具,相信您的文章一定能够帮助到很多人。在接下来的创作中,建议您可以扩展一下正则表达式的应用场景,或者分享一些实际案例,更加生动有趣地让读者理解和学习。期待您的更多好文! CSDN 会根据你创作的博客的质量,给予优秀的博主博客红包奖励。请关注 https://bbs.csdn.net/forums/csdnnews?typeId=116148&utm_source=csdn_ai_ada_blog_reply6 看奖励名单。
CSDN-Ada助手: 人生不过如此,且行且珍惜。自己永远是自己的主角,不要总在别人的戏剧里充当着配角。
CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)增加除了各种控件外,文章正文的字数;(2)使用标准目录;(3)增加内容的多样性(例如使用标准目录、标题、图片、链接、表格等元素)。
CSDN-Ada助手: 哇, 你的文章质量真不错,值得学习!不过这么高质量的文章, 还值得进一步提升, 以下的改进点你可以参考下: (1)使用标准目录;(2)增加内容的多样性(例如使用标准目录、标题、图片、链接、表格等元素)。