找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 480|回复: 3

[ARX程序]:小弟遇到难题了,白思不得其解啊!!

[复制链接]
发表于 2004-5-10 18:24:02 | 显示全部楼层 |阅读模式

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

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

×
小弟遇到难题了,百思不得其解啊
最近想做一条多段线顶点压缩,条件如下:首先将一条多段线的首尾相连,然后求出个点到该连线的距离,求出最大值的点,用该最大值和事先给定的阀值比较,若大于阀值,则保留该点,若小于阀值,则删除该点,再将该点和首尾点各自相连,设起点到该点的连线为L1,该点到结束点的连线为L2,然后用同样的方法依次求出在起点到该点之间的点到L1的距离,求出最大值的点,同理,求出到L2最大距离的点,继续和阀值比较,依次类推,求出满足条件的所有的点,最后将这些点连成一条新的多段线,这就是压缩过的多段线,部分代码如下://
#include "StdAfx.h"
#include "StdArx.h"
#include"acedads.h"
#include"adscodes.h"
#include <stdlib.h>
#include <rxobject.h>
#include <rxregsvc.h>
#include <aced.h>
#include <dbents.h>
#include <adslib.h>
#include <geassign.h>
#include "math.h"
double pt[50][3],h[50];
double v=10;
void listPline();
void iterate(AcDbObjectId id);
int maxi(int,int);
void studyaaddd()
{
listPline();
}
void
listPline()
{
    int rc;
    ads_name en;
    AcGePoint3d pt;
    rc = acedEntSel("\nSelect a polyline: ", en,
        asDblArray(pt));

    if (rc != RTNORM) {
        acutPrintf("\nError during object selection");
        return;
    }

    AcDbObjectId eId;
    acdbGetObjectId(eId, en);

    AcDbObject *pObj;
    acdbOpenObject(pObj, eId, AcDb::kForRead);
    if (pObj->isKindOf(AcDb2dPolyline::desc())) {
        pObj->close();
        iterate(eId);
    } else {
        pObj->close();
        acutPrintf("\nSelected entity is not an AcDb2dPolyline. \nMake sure the setvar PLINETYPE is set to 0 before createing a polyline");
    }
}
void
iterate(AcDbObjectId plineId)
{
    AcDb2dPolyline *pPline;
    acdbOpenObject(pPline, plineId, AcDb::kForRead);

    AcDbObjectIterator *pVertIter= pPline->vertexIterator();
    pPline->close();  

    AcDb2dVertex *pVertex;
    AcGePoint3d location;
    AcDbObjectId vertexObjId;
int i=0;
    for (int vertexNumber = 0;!pVertIter->done();
        vertexNumber++,pVertIter->step())
    {
        vertexObjId = pVertIter->objectId();
        acdbOpenObject(pVertex, vertexObjId,
            AcDb::kForRead);
        location = pVertex->position();
  pt[0]=float(location[X]);
        pt[1]=float(location[Y]);
  pt[2]=float(location[Z]);
        pVertex->close();
      
    acutPrintf("\npt[%d][0]=%.4f,pt[%d][1]=%.4f,pt[%d][2]=%.4f",
    i,location[X],i,location[Y],i,location[Z]);
i++;
    }

    delete pVertIter;
     acutPrintf("\n总共%d个顶点",i);
  int m,n;
  n=i-1;
  double max1,a1,b1,c1,e1,s1;
  b1=sqrt((pt[1][1]-pt[0][1])*(pt[1][1]-pt[0][1])+(pt[1][0]-pt[0][0])*(pt[1][0]-pt[0][0]));
  a1=sqrt((pt[2][1]-pt[0][1])*(pt[2][1]-pt[0][1])+(pt[2][0]-pt[0][0])*(pt[2][0]-pt[0][0]));
  c1=sqrt((pt[2][1]-pt[1][1])*(pt[2][1]-pt[1][1])+(pt[2][0]-pt[1][0])*(pt[2][0]-pt[1][0]));
  e1=(a1+b1+c1)/2;
        s1=sqrt(e1*(e1-a1)*(e1-b1)*(e1-c1));
     max1=(2*s1)/a1;
  
switch(i)
{case 2:acutPrintf("\n不符合条件,无法求距离!");return;
case 3:acutPrintf("\n第2点距离为%f:",max1);
     acutPrintf("\n无最大值!");
}
if(i>3)
{  
acutPrintf("\n该点为pt[%d]且最大值h[%d]=%lf",m,m,h[m]);
for(m=maxi(0,n);p=maxi(0,n);n-p>1;m>1;m=maxi(0,m);p=maxi(p,n))
{k1=maxi(maxi(0,m),m);
u1=maxi(p,maxi(p,n));
for(k2=k1;k3=k1;m-k3>1;k2-maxi(0,m)>1;k2=maxi(maxi(0,m),k2);k3=maxi(k3,m))


}
}
int maxi(int x,int y)
{int z;
double a,b,c,e,s,max=0;
for(int j=x+1;j<y;j++)
{a=sqrt((pt[y][1]-pt[x][1])*(pt[y][1]-pt[x][1])+(pt[y][0]-pt[x][0])*(pt[y][0]-pt[x][0]));
b=sqrt((pt[j][1]-pt[x][1])*(pt[j][1]-pt[x][1])+(pt[j][0]-pt[x][0])*(pt[j][0]-pt[x][0]));
c=sqrt((pt[y][1]-pt[j][1])*(pt[y][1]-pt[j][1])+(pt[y][0]-pt[j][0])*(pt[y][0]-pt[j][0]));
e=(a+b+c)/2;
s=sqrt(e*(e-a)*(e-b)*(e-c));
h[j]=(2*s)/a;
if(h[j]>max)
{max=h[j];
z=j;
}
acutPrintf("\nh[%d]=%lf",j,h[j]);
}
acutPrintf("\n第%d点距离最大为%lf:",z+1,max);
return z;
}
在顶点遍历中可能需要采用递归和循环思路,可是我花了好些时间也不能理顺思路,真是急啊,恳请各位高手指点一下有什么好的思路和方法啊,如何去用递归和循环来实现顶点遍历的问题,在下感激不尽!!!!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-5-11 09:58:27 | 显示全部楼层
只是顶点遍历应该不是很复杂吧?

我做了一半的函数 不知道对你有没有用



  1. /////////////////////////////////////////////////////////////////////////////////
  2. //#  DOC.BEGIN
  3. //#  函数名称: oxaReversePolyline
  4. //#  函数编号: OXA
  5. //#  函数声明:
  6. //#  函数参数: ads_name entname
  7. //#  返回值:   bool
  8. //#  函数分类:
  9. //#  函数功能:多义线点倒序,
  10. //#  注意事项: 没有完成
  11. //#  涉及的全局变量:
  12. //#  调用的OXARX函数:
  13. //#  函数算法:  
  14. //#  ACAD版本:R14  R15  R16
  15. //#  配合函数:
  16. //#  类似函数:
  17. //#  替换函数:
  18. //#  现存缺陷:没有完成 如果存在弧线会失败。
  19. //#  示例程序:
  20. //#  测试要求:
  21. //#  历史记录: 2003年11月24日 , zjw ,完成
  22. //
  23. //#  DOC.END
  24. bool oxaReversePolyline(ads_name entname)
  25. {
  26.        
  27.         char *strGet=new char[32];
  28.         AcDbObjectId   idPline;
  29.         if (acdbGetObjectId(idPline, entname)!=Acad::eOk)
  30.         {
  31.                 return  false;
  32.         }
  33.         AcDbEntity*  pEnt;       
  34.         if(Acad::eOk!=acdbOpenAcDbEntity(pEnt, idPline, AcDb::kForWrite))
  35.         {
  36.                 return  false;
  37.         }
  38.        
  39.         //判断是不是曲线
  40.         AcDbPolyline  *cvPLine=AcDbPolyline::cast(pEnt);
  41.         if (cvPLine==NULL)//acutPrintf("\n 选择的不是Polyline ");
  42.         {
  43.                 pEnt->close();
  44.                 return  false;               
  45.         }
  46.         //
  47.         unsigned int uiNumberTotal=cvPLine->numVerts();
  48.         unsigned int uiNumber=uiNumberTotal/2; // 折半,通过整数相除舍去余数
  49.         uiNumberTotal--;   //修正之,因为index起点是0
  50.        
  51.         AcGePoint2d ptFront, ptBack;
  52.         double      dBulgeFront, dBulgeBack;
  53.         for(unsigned int index=0;index<uiNumber;index++)
  54.         {     
  55.                 cvPLine->getPointAt(index,ptFront);
  56.                 cvPLine->getBulgeAt(index+1,dBulgeFront);
  57.                 cvPLine->getPointAt(uiNumberTotal-index,ptBack);
  58.                 cvPLine->getBulgeAt(uiNumberTotal-index-1,dBulgeBack);
  59.                 acutPrintf("\n---fBulge=%f ,%f ,",dBulgeFront ,dBulgeBack);
  60.                
  61.                 cvPLine->setPointAt(index,ptBack);
  62.                 cvPLine->setBulgeAt(index,-dBulgeBack);
  63.                 cvPLine->setPointAt(uiNumberTotal-index,ptFront);
  64.                 cvPLine->setBulgeAt(uiNumberTotal-index+1,-dBulgeFront);
  65.         }
  66.        
  67.         cvPLine->close();
  68.         pEnt->close();
  69.         return  true;
  70. }
复制代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 19:45 , Processed in 0.323263 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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