找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 4663|回复: 18

[分享] 学习objectarx做的一个对齐命令

[复制链接]

已领礼包: 195个

财富等级: 日进斗金

发表于 2013-7-27 15:04:24 | 显示全部楼层 |阅读模式

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

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

×
为了解决程序运行时间过长的问题,学了一下objectarx,这个对齐命令是我学习objectarx做的第一个命令,简陋了:
//定义一个4x4矩阵
static void ident_init(ads_matrix id)
{
int i, j;
for(i=0; i<=3; i++)
{
  for (j=0; j<=3; j++)
  {
   id[i][j] = 0.0;
  }
}
for(i=0; i<=3; i++)
{
  id[i][i] = 1.0;
}
}
static void zdqMyGroup_duiqi ()
{
ads_matrix xform,xformmo,xformro; // 转换矩阵
ads_name ssGrp;  // 选择集名称
int rc;    // 返回值
ads_real sf;  // 目标数据扩大倍数

// 构造选集
acedPrompt(ACRX_T("\n选择实体并对齐"));
rc = acedSSGet(NULL, NULL, NULL, NULL, ssGrp);
if(rc != RTNORM)
{
  acutPrintf(ACRX_T("\n选择实体"));
  return;
}

// 选择源点和目标点
ads_point ptTo,ptFrom,ptFrom2,ptTo2;
if (acedGetPoint(NULL, ACRX_T("\n选择源点一:"),ptFrom)!= RTNORM)
{
  return;
}
if (acedGetPoint(ptFrom, ACRX_T("\n选择目标点一:"), ptTo)!= RTNORM)
{
  return;
}
if (acedGetPoint(NULL, ACRX_T("\n选择源点二:"),ptFrom2)!= RTNORM)
{
  return;
}
if (acedGetPoint(ptFrom2, ACRX_T("\n选择目标点二:"), ptTo2)!= RTNORM)
{
  return;
}
// 输入目标数据扩大倍数
sf=sqrt((ptTo[X]-ptTo2[X])*(ptTo[X]-ptTo2[X])+(ptTo[Y]-ptTo2[Y])*(ptTo[Y]-ptTo2[Y]))/
  sqrt((ptFrom[X]-ptFrom2[X])*(ptFrom[X]-ptFrom2[X])+(ptFrom[Y]-ptFrom2[Y])*(ptFrom[Y]-ptFrom2[Y]));
// 构建用于实现移动实体的矩阵
ident_init(xformmo);
xformmo[0][3]=- ptFrom[X];
xformmo[1][3]=- ptFrom[Y];
xformmo[2][3]=- ptFrom[Z];
ident_init(xform);
xform[0][3]=ptTo[X]*sf;
xform[1][3]=ptTo[Y]*sf;
xform[2][3]=ptTo[Z]*sf;
// 构建用于实现旋转实体的矩阵
ident_init(xformro);
double angle;
angle=atan((ptFrom2[Y]-ptFrom[Y])/(ptFrom2[X]-ptFrom[X]))-atan((ptTo2[Y]-ptTo[Y])/(ptTo2[X]-ptTo[X]));
xformro[0][0]=cos(angle);
xformro[0][1]=sin(angle);
xformro[1][0]=-sin(angle);
xformro[1][1]=cos(angle);

//变换选择集
rc = acedXformSS(ssGrp, xformmo);
rc = acedXformSS(ssGrp, xformro);
rc = acedXformSS(ssGrp, xform);
if(rc != RTNORM)
{
  acutPrintf(ACRX_T("\n实体对齐转换失败. "));
}
//释放选集
acedSSFree(ssGrp);
}

评分

参与人数 1D豆 +6 收起 理由
XDSoft + 6 很给力!经验;技术要点;资料分享奖!

查看全部评分

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

使用道具 举报

已领礼包: 1742个

财富等级: 堆金积玉

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

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-27 17:54:08 | 显示全部楼层
支持楼主, 不过,楼主你写的这个应该是ADS, 不是ARX。使用的都是ARX的全局函数(ADS)

ARX应该是用 AcGeMatrix3d构建矩阵,抽空我帮你修改下。你会看到使用ARX很方便,那些数学函数都可以省掉了。

点评

那就多谢啦,这些天我正在纠结AcGeMatrix3d和ads_matrix的异同、相互转换。  详情 回复 发表于 2013-7-27 19:44
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 195个

财富等级: 日进斗金

 楼主| 发表于 2013-7-27 19:44:19 | 显示全部楼层
XDSoft 发表于 2013-7-27 17:54
支持楼主, 不过,楼主你写的这个应该是ADS, 不是ARX。使用的都是ARX的全局函数(ADS)

ARX应该是用 Ac ...

那就多谢啦,这些天我正在纠结AcGeMatrix3d和ads_matrix的异同、相互转换。

点评

取点和选择集还是你那个,核心构造对齐矩阵的代码如下: from1 --- 源点1 from2--- 源点2 to1--- 目标点1 to2--- 目标点2 f1,f2,t1,t2对应的是你取的ads_point点。 得到对齐矩阵后,遍历选择集,然  详情 回复 发表于 2013-7-27 20:18
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-27 20:18:29 | 显示全部楼层
zdqwy19 发表于 2013-7-27 19:44
那就多谢啦,这些天我正在纠结AcGeMatrix3d和ads_matrix的异同、相互转换。

取点和选择集还是你那个,核心构造对齐矩阵的代码如下:
from1 --- 源点1
from2--- 源点2
to1--- 目标点1
to2--- 目标点2


f1,f2,t1,t2对应的是你取的ads_point点。

[pcode=cpp,true]
         AcGePoint3d from1,from2,to1,to2;
        ads_point f1,f2,t1,t2;

        from1=asPnt3d(f1);
        from2=asPnt3d(f2);
        to1=asPnt3d(t1);
        to2=asPnt3d(t2);
        AcGeVector3d s_xAxis,s_yAxis,s_zAxis,d_xAxis,d_yAxis,d_zAxis;
        s_xAxis=(from2-from1).normalize(); //源坐标系 X轴单位向量
        s_yAxis=s_xAxis.perpVector();//源坐标系 Y轴单位向量
        s_zAxis=s_xAxis.crossProduct(s_yAxis);//源坐标系 Z轴单位向量

        d_xAxis=(to2-to1).normalize;//目标坐标系 X轴单位向量
        d_yAxis=d_xAxis.perpVector();//目标坐标系 Y轴单位向量
        d_zAxis=d_xAxis.crossProduct(d_yAxis);//目标坐标系 Z轴单位向量

        AcGeMatrix3d align;
        align.setToAlignCoordSys(from1,s_xAxis,s_yAxis,s_zAxis,to1,d_xAxis,d_yAxis,d_zAxis);//构建从源坐标系到目的坐标系的变换矩阵

[/pcode]

得到对齐矩阵后,遍历选择集,然后对每个实体用 pEnt->transformby(align) 就变换过去了。

点评

老师您好!您看看,我这段代码怎样精简,我的本意求块的插入点由(x,y,z)变为(x+a,y+b,z)的转换矩阵 //构建转换矩阵 AcGePoint3d origin;//块的原基点 struct resbuf rbFrom, rbTo; rbFrom.restype = RT3DPO  详情 回复 发表于 2013-7-27 21:15
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-27 20:29:53 | 显示全部楼层
送你几个函数

  1. //从选择集中的实体加入到AcDbObjectIdArray中

  2. Acad::ErrorStatus XdDbUtils::getIdArrayFromPickSet(ads_name PickSet,AcDbObjectIdArray &ids)
  3. {
  4.         
  5.         long len,i;
  6.         if (ads_sslength(PickSet,&len)!=RTNORM)
  7.                 return  Acad::eNotImplementedYet;
  8.         ads_name mEname;
  9.         AcDbObjectId id;
  10.         if (!(ids.isEmpty())){
  11.                 ids.setPhysicalLength(0);
  12.                 ids.setLogicalLength(0);
  13.         }
  14.         for (i=0;i<len;i++){
  15.                 ads_ssname(PickSet,i,mEname);
  16.                 acdbGetObjectId(id,mEname);
  17.                 if (isValidEnt(id)){
  18.                         ids.append(id);
  19.                 }
  20.         }
  21.         return (!ids.isEmpty())?Acad::eOk:Acad::eNotImplementedYet;
  22. }


  1. Acad::ErrorStatus XdDbUtils::getPickSetFromIdArray(AcDbObjectIdArray *ids,ads_name PickSet)
  2. {
  3.         if (ids->isEmpty())
  4.                 return eNotImplementedYet;
  5.         
  6.         ads_name ent;
  7.         for (int i=0;i<ids->length();i++)
  8.         {
  9.                 acdbGetAdsName(ent,ids->at(i));
  10.                 ads_ssadd(ent,PickSet,PickSet);
  11.         }
  12.         long len;
  13.         ads_sslength(PickSet,&len);
  14.         return (len>0)?Acad::eOk:Acad::eNotImplementedYet;
  15. }
  16. BOOL XdDbUtils::isValidEnt(ads_name ent)
  17. {
  18.         AcDbObjectId id;
  19.         acdbGetObjectId(id,ent);
  20.         AcDbEntity *pEnt;
  21.         Acad::ErrorStatus es;
  22.         es=acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead);
  23.         if (es!=Acad::eOk)
  24.                 return FALSE;
  25.         pEnt->close();
  26.         return TRUE;
  27. }
  28. //
  29. BOOL XdDbUtils::isValidEnt(AcDbObjectId id)
  30. {
  31.         AcDbEntity *pEnt;
  32.         Acad::ErrorStatus es;
  33.         es=acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead);
  34.         if (es!=Acad::eOk)
  35.                 return FALSE;
  36.         pEnt->close();
  37.         return TRUE;
  38. }        


遍历ID数组,你就可以做想做的实体变换了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 195个

财富等级: 日进斗金

 楼主| 发表于 2013-7-27 21:15:15 | 显示全部楼层
本帖最后由 zdqwy19 于 2013-7-28 15:38 编辑
XDSoft 发表于 2013-7-27 20:18
取点和选择集还是你那个,核心构造对齐矩阵的代码如下:
from1 --- 源点1
from2--- 源点2

不去研究了,块转换矩阵

点评

你是想把一个 INSERT 从一个点 移动到另外一个点, 还是想修改块定义,重新定义插入点?  详情 回复 发表于 2013-7-27 21:40
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-27 21:40:05 | 显示全部楼层
zdqwy19 发表于 2013-7-27 21:15
老师您好!您看看,我这段代码怎样精简,我的本意求块的插入点由(x,y,z)变为(x+a,y+b,z)的转换矩阵
// ...

你是想把一个 INSERT 从一个点 移动到另外一个点, 还是想修改块定义,重新定义插入点?

点评

我不是想移动块或修改块定义,但我知道块的转换矩阵和插入点有关,我在工作中需要根据块的插入点和块的原始转换矩阵来转换数据。  详情 回复 发表于 2013-7-27 22:24
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-27 21:50:01 | 显示全部楼层
首先明确几个事情:

1、 忘记C的数组操作(这是ADS), 所有的点都用 AcGePoint3d,所有的位移都用AcGeVector3d,这样你才能利用这些对象提供的方法(AcGe库)
2、 getCoordSystem 是获得一个矩阵的坐标系(得到 原点、X,Y,Z轴向量)
3、 setCoordSystem 是设置一个矩阵的坐标系 (根据 原点、X,Y,Z轴向量)

2和3都没涉及到矩阵变换, 要想矩阵变换, 需要用 AcGeMatrix3d::alignCoordSys (从一个坐标系到另外一个坐标系变换矩阵), 另外就是 AcGeMatrix3d类的 set 类方法构建平移、旋转、镜像、投影、缩放变换矩阵。

如果你熟练使用了AcGeMatrix3d::alignCoordSys ,那么很多事情都容易解决了。 AcGeMatrix3d::alignCoordSys 是其他set类的组合,从一个坐标系到另外一个坐标系的平移,旋转组合矩阵操作。

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

使用道具 举报

已领礼包: 195个

财富等级: 日进斗金

 楼主| 发表于 2013-7-27 22:24:14 | 显示全部楼层
XDSoft 发表于 2013-7-27 21:40
你是想把一个 INSERT 从一个点 移动到另外一个点, 还是想修改块定义,重新定义插入点?

我不是想移动块或修改块定义,但我知道块的转换矩阵和插入点有关,我在工作中需要根据块的插入点和块的原始转换矩阵来转换数据。

点评

那你想做什么? 详细说一下,贴图来论坛。  详情 回复 发表于 2013-7-28 03:13
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-28 03:13:26 | 显示全部楼层
zdqwy19 发表于 2013-7-27 22:24
我不是想移动块或修改块定义,但我知道块的转换矩阵和插入点有关,我在工作中需要根据块的插入点和块的原 ...

那你想做什么? 详细说一下,贴图来论坛。

点评

其实描述挺简单的,已知块的数据,将块的插入点移动(a,b,0)后,利用原数据和移动矢量获得移动后的转换矩阵。  详情 回复 发表于 2013-7-28 07:35
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 195个

财富等级: 日进斗金

 楼主| 发表于 2013-7-28 07:35:13 | 显示全部楼层
XDSoft 发表于 2013-7-28 03:13
那你想做什么? 详细说一下,贴图来论坛。

其实描述挺简单的,已知块的数据,将块的插入点移动(a,b,0)后,利用原数据和移动矢量获得移动后的转换矩阵。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-7-28 10:59:10 | 显示全部楼层
我不是想移动块或修改块定义,但我知道块的转换矩阵和插入点有关,我在工作中需要根据块的插入点和块的原始转换矩阵来转换数据。


你说过既不想移动块,又不想修改块定义的插入点, 那么:

你下面说的:
将块的插入点移动(a,b,0)后


的移动是什么意思?  

可以贴个图上来吗?

点评

[attachimg]4544[/attachimg]  详情 回复 发表于 2013-7-28 12:11
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 195个

财富等级: 日进斗金

 楼主| 发表于 2013-7-28 12:11:16 | 显示全部楼层
本帖最后由 zdqwy19 于 2013-7-28 12:16 编辑
XDSoft 发表于 2013-7-28 10:59
你说过既不想移动块,又不想修改块定义的插入点, 那么:

你下面说的:

假设原块移动到假设块的位置,只想得到假设块的变换矩阵,不对图形做任何更改

无标题.png

点评

AcGePoint3d p1,p2; AcGeVector3d mTVec=p1-p2; AcGeMatrix3d mMatrix; mMatrix.setTransLation(mTVec); 这个是平移变换矩阵 AcDbBlockReference *pBlk; 这个是INSERT实体,你需要打开操作 AcGeMatrix3d  详情 回复 发表于 2013-7-28 20:39
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-12 05:27 , Processed in 0.233221 second(s), 71 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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