找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 637|回复: 1

[每日一码] 由CAD截面图形得到其节线数据

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-9-26 17:35:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
  1. void varyL()
  2. {
  3.     ArxDbgUiPrEntity prEnt(_T("请选择截面外轮廓"), NULL);
  4.     prEnt.addAllowedClass(AcDbPolyline::desc());

  5.     if (prEnt.go() != ArxDbgUiPrBase::kOk)
  6.     {
  7.         return;
  8.     }

  9.     AcDbEntity* pEnt1 = NULL;
  10.     acdbOpenObject(pEnt1,prEnt.objectId(),AcDb::kForRead);

  11.     //获得封闭形顶点
  12.     AcDbPolyline *Polygon = NULL ;
  13.     Polygon = AcDbPolyline::cast(pEnt1);
  14.     ASSERT( Polygon != NULL );
  15.     if (Polygon == NULL)
  16.     {
  17.         AfxMessageBox(_T("线型不为多义线"));
  18.         pEnt1->close();
  19.         return;
  20.     }

  21.     if( !Polygon->isClosed() )
  22.     {
  23.         Polygon->close();
  24.         AfxMessageBox(_T("外轮廓不封闭"));
  25.         return;
  26.     }

  27.     AcGePoint3dArray PtArray;//记录外轮廓上的点
  28.     AcGePoint3dArray keyPtArray; //记录 “任一高度” 所有的 点(最后节线高度值)

  29.     int VertNum = (int)Polygon->numVerts() ;
  30.     int i;
  31.     for( i = 0; i < VertNum; i ++ )
  32.     {
  33.         AcGePoint3d    Temp;
  34.         Polygon->getPointAt(i,Temp);

  35.         PtArray.append(Temp);//外轮廓上的点

  36.         //如果此点与之前所有点的Y值不同,则增加为 关键点
  37.         BOOL bAdd = TRUE;

  38.         for (int k = 0; k < keyPtArray.length(); k ++)
  39.         {
  40.             if (fabs(keyPtArray[k].y - Temp.y) < 1e-6)
  41.             {
  42.                 bAdd = FALSE;

  43.                 Temp.y += 1e-4;
  44.                 keyPtArray.append(Temp);
  45.                 break;
  46.             }
  47.         }
  48.         if (bAdd == TRUE)
  49.         {
  50.             keyPtArray.append(Temp);//高度 关键点
  51.         }
  52.         
  53.     }
  54.     pEnt1->close();

  55.     //////////////////////////////////////////////////////////////////////////
  56.     //////////////////////////////////////////////////////////////////////////


  57.     //获得空腔个数
  58.     int nHoll;

  59.     ArxDbgUiPrIntDef prInt(_T("输入空腔个数"), NULL,ArxDbgUiPrInt::kRange, 0);
  60.     prInt.setRange(0, 10);

  61.     if(prInt.go() != ArxDbgUiPrBase::kOk)
  62.         return;
  63.     else
  64.         nHoll = prInt.value();

  65.     AcGePoint3dArray ptHollArray[10];

  66.     //依次选择全部空腔
  67.     for (i = 0; i < nHoll; i ++)
  68.     {
  69.         CString strTemp;
  70.         strTemp.Format(_T("选择第个 %d 内腔"), i + 1);
  71.         prEnt.setMessage(strTemp);

  72.         if (prEnt.go() != ArxDbgUiPrBase::kOk)
  73.             return;

  74.         AcDbEntity* pEnt1 = NULL;
  75.         acdbOpenObject(pEnt1, prEnt.objectId(), AcDb::kForRead);

  76.         //获得封闭形顶点
  77.         AcDbPolyline *Polygon = NULL ;
  78.         Polygon = AcDbPolyline::cast(pEnt1);
  79.         ASSERT( Polygon != NULL );
  80.         if (Polygon == NULL)
  81.         {
  82.             AfxMessageBox(_T("线型不为多义线"));
  83.             pEnt1->close();
  84.             return;
  85.         }
  86.         if( !Polygon->isClosed() )
  87.         {
  88.             Polygon->close();
  89.             AfxMessageBox(_T("内腔不封闭"));
  90.             return;
  91.         }
  92.       
  93.         int VertNum = (int)Polygon->numVerts();
  94.         int k;
  95.         for( k=0; k<VertNum; k++ )
  96.         {
  97.             AcGePoint3d    Temp;
  98.             Polygon->getPointAt(k,Temp);

  99.             if(PointIsInPolygon(Temp,PtArray) != 1)
  100.             {
  101.                 AfxMessageBox(_T("内腔不在外内轮廓内!"));
  102.                 pEnt1->close();
  103.                 return;
  104.             }
  105.             ptHollArray.append(Temp);

  106.             //如果此点与之前所有点的Y值不同, 则加入到高度关键点中(多个内腔时)
  107.             BOOL bAdd = TRUE;

  108.             for (int j = 0; j < keyPtArray.length(); j ++)
  109.             {
  110.                 if (fabs(keyPtArray[j].y - Temp.y) < 1e-6)//精度控制
  111.                 {
  112.                     bAdd = FALSE;

  113.                     //精度控制
  114.                     Temp.y += 1e-4;
  115.                     keyPtArray.append(Temp);

  116.                     break;
  117.                 }           
  118.             }
  119.             if (bAdd == TRUE)
  120.             {
  121.                 keyPtArray.append(Temp);//高度 关键点
  122.             }
  123.         }
  124.         pEnt1->close();

  125.     }
  126.    
  127.    
  128.    

  129.     CArray <varyLine, varyLine> varyLineArray;

  130.     AcGePoint3dArray sortedkeyPtArray;   
  131.     arrangePointArray(keyPtArray, sortedkeyPtArray, FALSE);//高度关键点数组 Y值升序排列

  132.     sortedkeyPtArray[0].y += 1e-5;
  133.     sortedkeyPtArray[sortedkeyPtArray.length() - 1].y -= 1e-5;

  134.     AcGePoint3d tempPt;
  135.     varyLine tempVaryLine;//节线结构体   

  136.     //节线结构体中的节线编号,但是其中有很多重合的节线,故不予输出
  137.     int nVaryIndex = 1;//添加一条节线后,就加1   

  138.     int wk = sortedkeyPtArray.length();
  139.     if (nHoll == 0)
  140.     {
  141.         for (i = 0; i < sortedkeyPtArray.length();  i ++)
  142.         {
  143.             AcGePoint3d temp1 = sortedkeyPtArray, temp2 = sortedkeyPtArray;
  144.             temp1.x -= 50000;
  145.             temp2.x += 50000;
  146.             double length = 0;
  147.            
  148.             CAD_POINT *tempPt = NULL;//外、内轮廓线所有点的另一种存储方式
  149.             tempPt = new AcGePoint3d[PtArray.length()];
  150.             for (int k = 0; k<PtArray.length(); k ++)
  151.             {
  152.                 tempPt[k]=PtArray[k];
  153.             }

  154.             length = lengthThroughRegion(tempPt, PtArray.length(), temp1,temp2);

  155.             tempVaryLine.N = nVaryIndex;
  156.             nVaryIndex ++;

  157.             tempVaryLine.Y = sortedkeyPtArray.y ;
  158.             tempVaryLine.relativeY = sortedkeyPtArray.y - sortedkeyPtArray[0].y ;
  159.             tempVaryLine.Length = length;

  160.             varyLineArray.Add(tempVaryLine);

  161.             delete []tempPt;
  162.         }
  163.                
  164.     }
  165.     //空腔个数不为0
  166.     else
  167.     {   
  168.         for (i = 0; i < sortedkeyPtArray.length(); i ++)
  169.         {
  170.             AcGePoint3d temp1 = sortedkeyPtArray, temp2 = sortedkeyPtArray;
  171.             temp1.x -= 5000;
  172.             temp2.x += 5000;
  173.             double length = 0;
  174.            
  175.             CAD_POINT *tempPt = NULL;
  176.             tempPt = new AcGePoint3d[PtArray.length()];
  177.             int k;
  178.             for (k = 0; k<PtArray.length(); k ++)
  179.             {
  180.                 tempPt[k]=PtArray[k];
  181.             }
  182.             //得到总长
  183.             length = lengthThroughRegion(tempPt, PtArray.length(), temp1,temp2);
  184.             delete []tempPt;

  185.             //////////////////////////////////////////////////////////////////////////
  186.             //减去所有空腔
  187.             for (k = 0; k < nHoll; k ++)
  188.             {
  189.                 tempPt = new AcGePoint3d[ptHollArray[k].length()];
  190.                 int wk = ptHollArray[k].length();
  191.                 for (int j = 0; j<ptHollArray[k].length(); j ++)
  192.                 {
  193.                     tempPt[j]=ptHollArray[k][j];
  194.                 }
  195.                 length -= lengthThroughRegion(tempPt, ptHollArray[k].length(), temp1,temp2);
  196.             }

  197.             tempVaryLine.N = nVaryIndex;
  198.             nVaryIndex ++;

  199.             tempVaryLine.Y = sortedkeyPtArray.y ;
  200.             tempVaryLine.relativeY = sortedkeyPtArray.y - sortedkeyPtArray[0].y ;
  201.             tempVaryLine.Length = length;

  202.             varyLineArray.Add(tempVaryLine);

  203.             delete []tempPt;
  204.                        
  205.         }
  206.     }

  207.     //去掉节线宽度一样的节线
  208.     for (i = 0; i < varyLineArray.GetSize() - 1; i ++)
  209.     {
  210.         for (int j = varyLineArray.GetSize() - 1; j >= i + 1 ; j --)
  211.         {
  212.             if (fabs(varyLineArray.Length - varyLineArray[j].Length) < 1e-2 &&
  213.                 fabs(varyLineArray.relativeY - varyLineArray[j].relativeY) < 1e-2)
  214.             {
  215.                 varyLineArray.RemoveAt(j);
  216.             }
  217.         }
  218.     }

  219.     //对于上下边界,如果是水平线,则应去掉一条宽度高度均为0的节线
  220.     if ( fabs(varyLineArray[1].Y - varyLineArray[0].Y) < 1e-3 )
  221.     {
  222.         varyLineArray.RemoveAt(0);
  223.     }

  224.     if ( fabs(varyLineArray[ varyLineArray.GetSize() -1 ].Y - varyLineArray[ varyLineArray.GetSize() - 2 ].Y) < 1e-3 )
  225.     {
  226.         varyLineArray.RemoveAt( varyLineArray.GetSize() - 1);
  227.     }

  228.     //因为上面几行删除掉了相同的节线,因而varyLineArray.N就有间隔了
  229.     //所以不能输出varyLineArray的N值了

  230.     CFileDialog OpenFile(FALSE,_T(".txt"),_T("节线数据.txt"),
  231.                      OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
  232.                      _T("文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*||"));
  233.              OpenFile.m_ofn.lpstrTitle=_T("新建数据文件");
  234.     if (OpenFile.DoModal() == IDCANCEL)
  235.                  return ;
  236.     CString pathName=OpenFile.GetPathName();

  237.     ofstream ofile(pathName);
  238.     ofile<<"节线编号\t"<<"宽度\t\t" <<"高度\n";
  239.     for (i = 0; i < varyLineArray.GetSize(); i ++)
  240.     {      
  241.         TCHAR outStr[200];
  242.         _stprintf(outStr,_T("%d\t\t%.2f\t\t%.2f\n"), i+1,varyLineArray.Length,varyLineArray.relativeY);
  243.         ofile << outStr;
  244.     }

  245.     ofile.close();

  246.     //询问用户是否要打开已生成的文本
  247.     bool bOpen = true;
  248.     if (ArxDbgUtils::yesNoPromptDef(_T("是否要打开生成的内容"), bOpen, true) != ArxDbgUiPrBase::kOk)
  249.         return;

  250.     if(bOpen)
  251.         ShellExecute(::GetDesktopWindow(), _T("open"), pathName, NULL, NULL, SW_SHOWNORMAL);
  252. }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1757个

财富等级: 堆金积玉

发表于 2016-9-27 08:03:15 | 显示全部楼层
                                                                    
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-26 07:40 , Processed in 0.452012 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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