明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 869|回复: 3

分享一个点集求凸包的算法

[复制链接]
发表于 2020-1-15 16:05 | 显示全部楼层 |阅读模式
  1. #include "stdafx.h"
  2. #include "MyTuBao.h"
  3. #include"MathUtil.h"
  4. MyTuBao::MyTuBao()
  5. {
  6. }

  7. MyTuBao::MyTuBao(AcGePoint3dArray arr)
  8. {
  9.   this->ptArr = arr;
  10. }


  11. MyTuBao::~MyTuBao()
  12. {
  13.   ptArr.removeAll();

  14. }

  15. void   MyTuBao::GetTuBao(AcGePoint3dArray &pArray)
  16. {
  17.   int nums = 0;
  18.   optimizePointsArray(ptArr);
  19.   nums = ptArr.length();
  20.   if (nums > 3) {
  21.     selectMinPoint(ptArr);//寻找最小的点
  22.     quickSort(ptArr, 1, nums - 1);//用来根据极角排序点
  23.     pArray.append(ptArr[0]);
  24.     pArray.append(ptArr[1]);
  25.     pArray.append(ptArr[2]);
  26.     int top = pArray.length() - 1;
  27.     for (int i = 3; i < nums; i++)
  28.     {
  29.       while (xmul(ptArr, pArray[top], pArray[top - 1]) >= 0)  //是否左转,是继续判断,不是,就入栈  
  30.       {
  31.         pArray.removeLast();
  32.         top = pArray.length() - 1;
  33.       }
  34.       pArray.append(ptArr);

  35.       top = pArray.length() - 1;
  36.     }

  37.   }
  38. }

  39. void MyTuBao::GetRec(AcGePoint3dArray &pArray){
  40.   selectMinPoint(ptArr);//寻找最小的点
  41.   int nums = 0;
  42.   optimizePointsArray(ptArr);
  43.   nums = ptArr.length();
  44.   quickSort(ptArr, 1, nums - 1);//用来根据极角排序点
  45.   pArray = ptArr;

  46. }
  47. void MyTuBao::optimizePointsArray(AcGePoint3dArray &points, double tol /*= 1.0E-7*/) {
  48.   
  49.   for (int i = points.length() - 1; i > 0; i--)
  50.   {
  51.     for (int j = 0; j < i; j++)
  52.     {
  53.       if (CMathUtil::IsEqual(points.x, points[j].x, tol) && CMathUtil::IsEqual(points.y, points[j].y, tol))
  54.       {
  55.         points.removeAt(i);
  56.         break;
  57.       }
  58.     }
  59.   }
  60. }

  61. long long  MyTuBao::dist(AcGePoint3d p1, AcGePoint3d p2) //两点距离的平方  
  62. {
  63.   return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);
  64. }

  65. bool MyTuBao::cmp1(AcGePoint3d p1, AcGePoint3d p2)   //找到第一个点,返回 true->p1比较小,false->p2比较小
  66. {
  67.   if (p1.y == p2.y)
  68.     return p1.x<p2.x;
  69.   else
  70.     return p1.y<p2.y;
  71. }

  72. bool MyTuBao::cmp2(AcGePoint3d p1, AcGePoint3d p2, AcGePoint3d pointMin)   //极角排序的比较函数  
  73. {
  74.   if (xmul(p1, p2, pointMin)>0)
  75.     return true; //证明 p1小 选中p1
  76.   else if (xmul(p1, p2, pointMin) == 0 && dist(p1, pointMin)<dist(p2, pointMin))  //相等的按距离近的  
  77.     return true; //证明 p1小 选中p1
  78.   return false;
  79. }

  80. double MyTuBao::xmul(AcGePoint3d p1, AcGePoint3d p2, AcGePoint3d  p0)
  81. {
  82.   return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
  83. }

  84. void MyTuBao::selectMinPoint(AcGePoint3dArray &s) {
  85.   int nums = s.length();
  86.   int cur = 0;
  87.   AcGePoint3d Min = s[0];
  88.   for (int i = 1; i<nums; i++) {
  89.     if (cmp1(s, Min)) {
  90.       Min = s;
  91.       cur = i;
  92.     }
  93.   }
  94.   s[cur] = s[0];
  95.   s[0] = Min;
  96.   acutPrintf(L"\n寻找后最小点为x=%f,y=%f", s[0].x, s[0].y);
  97. }

  98. void  MyTuBao::quickSort(AcGePoint3dArray &s, int l, int r) {
  99.   if (l< r)
  100.   {
  101.     int i = l, j = r;
  102.     AcGePoint3d x = s[l];
  103.     while (i < j)
  104.     {
  105.       while (i < j && cmp2(x, s[j], s[0])) // 从右向左找第一个小于x的数
  106.         j--;
  107.       if (i < j)
  108.         s[i++] = s[j];
  109.       while (i < j && cmp2(s, x, s[0])) // 从左向右找第一个大于等于x的数
  110.         i++;
  111.       if (i < j)
  112.         s[j--] = s;
  113.     }
  114.     s = x;
  115.     quickSort(s, l, i - 1); // 递归调用
  116.     quickSort(s, i + 1, r);
  117.   }
  118. }

 楼主| 发表于 2020-1-15 16:06 | 显示全部楼层
#include "stdafx.h"
#include "MyTuBao.h"
#include"MathUtil.h"
MyTuBao::MyTuBao()
{
}

MyTuBao::MyTuBao(AcGePoint3dArray arr)
{
        this->ptArr = arr;
}


MyTuBao::~MyTuBao()
{
        ptArr.removeAll();

}

void   MyTuBao::GetTuBao(AcGePoint3dArray &pArray)
{
        int nums = 0;
        optimizePointsArray(ptArr);
        nums = ptArr.length();
        if (nums > 3) {
                selectMinPoint(ptArr);//寻找最小的点
                quickSort(ptArr, 1, nums - 1);//用来根据极角排序点
                pArray.append(ptArr[0]);
                pArray.append(ptArr[1]);
                pArray.append(ptArr[2]);
                int top = pArray.length() - 1;
                for (int i = 3; i < nums; i++)
                {
                        while (xmul(ptArr[i], pArray[top], pArray[top - 1]) >= 0)  //是否左转,是继续判断,不是,就入栈  
                        {
                                pArray.removeLast();
                                top = pArray.length() - 1;
                        }
                        pArray.append(ptArr[i]);

                        top = pArray.length() - 1;
                }

        }
}

void MyTuBao::GetRec(AcGePoint3dArray &pArray){
        selectMinPoint(ptArr);//寻找最小的点
        int nums = 0;
        optimizePointsArray(ptArr);
        nums = ptArr.length();
        quickSort(ptArr, 1, nums - 1);//用来根据极角排序点
        pArray = ptArr;

}
void MyTuBao::optimizePointsArray(AcGePoint3dArray &points, double tol /*= 1.0E-7*/) {
       
        for (int i = points.length() - 1; i > 0; i--)
        {
                for (int j = 0; j < i; j++)
                {
                        if (CMathUtil::IsEqual(points[i].x, points[j].x, tol) && CMathUtil::IsEqual(points[i].y, points[j].y, tol))
                        {
                                points.removeAt(i);
                                break;
                        }
                }
        }
}

long long  MyTuBao::dist(AcGePoint3d p1, AcGePoint3d p2) //两点距离的平方  
{
        return (p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y);
}

bool MyTuBao::cmp1(AcGePoint3d p1, AcGePoint3d p2)   //找到第一个点,返回 true->p1比较小,false->p2比较小
{
        if (p1.y == p2.y)
                return p1.x<p2.x;
        else
                return p1.y<p2.y;
}

bool MyTuBao::cmp2(AcGePoint3d p1, AcGePoint3d p2, AcGePoint3d pointMin)   //极角排序的比较函数  
{
        if (xmul(p1, p2, pointMin)>0)
                return true; //证明 p1小 选中p1
        else if (xmul(p1, p2, pointMin) == 0 && dist(p1, pointMin)<dist(p2, pointMin))  //相等的按距离近的  
                return true; //证明 p1小 选中p1
        return false;
}

double MyTuBao::xmul(AcGePoint3d p1, AcGePoint3d p2, AcGePoint3d  p0)
{
        return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
}

void MyTuBao::selectMinPoint(AcGePoint3dArray &s) {
        int nums = s.length();
        int cur = 0;
        AcGePoint3d Min = s[0];
        for (int i = 1; i<nums; i++) {
                if (cmp1(s[i], Min)) {
                        Min = s[i];
                        cur = i;
                }
        }
        s[cur] = s[0];
        s[0] = Min;
        acutPrintf(L"\n寻找后最小点为x=%f,y=%f", s[0].x, s[0].y);
}

void  MyTuBao::quickSort(AcGePoint3dArray &s, int l, int r) {
        if (l< r)
        {
                int i = l, j = r;
                AcGePoint3d x = s[l];
                while (i < j)
                {
                        while (i < j && cmp2(x, s[j], s[0])) // 从右向左找第一个小于x的数
                                j--;
                        if (i < j)
                                s[i++] = s[j];
                        while (i < j && cmp2(s[i], x, s[0])) // 从左向右找第一个大于等于x的数
                                i++;
                        if (i < j)
                                s[j--] = s[i];
                }
                s[i] = x;
                quickSort(s, l, i - 1); // 递归调用
                quickSort(s, i + 1, r);
        }
}
发表于 2020-1-15 16:11 | 显示全部楼层
MyTuBao 哈哈
论坛搞arx开发的太少了
业余的也就搞搞lisp

点评

satan421你就是个彻头彻尾的杂碎。一毛不拨,对别人指手画脚。垃圾。  发表于 2020-5-30 22:05
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-27 15:49 , Processed in 0.560906 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表