明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

帖子
查看: 778|回复: 6

ARX 曲线文字

[复制链接]
发表于 2025-2-22 15:53:20 | 显示全部楼层 |阅读模式
官方有个例子,但版本是 2008 的、而且涉及太多。

看了 Lee Mac 的代码觉得容易理解。翻译成 ARX 的。


  1.         Acad::ErrorStatus es = Acad::eOk;
  2.         // 用户选择单行文字
  3.         ads_name nameText;
  4.         ads_point pt;
  5.         if (RTNORM != acedEntSel(_T("\n选择一个单行文字沿曲线排列:"), nameText, pt))
  6.             return;
  7.         AcDbObjectId TextID;
  8.         es = acdbGetObjectId(TextID, nameText);
  9.         if (es != Acad::eOk)
  10.             return;
  11.         AcDbEntity* pEntText = NULL;
  12.         es = acdbOpenObject(pEntText, TextID, AcDb::kForWrite);
  13.         if (es != Acad::eOk)
  14.             return;
  15.         AcDbText* pText = AcDbText::cast(pEntText);
  16.         if (pText == NULL)
  17.         {
  18.             pEntText->close();
  19.             return;
  20.         }
  21.         ACHAR* pTextStr = pText->textString();
  22.         CString strText = pTextStr;
  23.         delete[] pTextStr;
  24.         pText->close();
  25.         pEntText->close();
  26.         // 用户选择曲线
  27.         ads_name nameCurve;
  28.         if (RTNORM != acedEntSel(_T("\n选择一条曲线:"), nameCurve, pt))
  29.             return;
  30.         AcDbObjectId CurveID;
  31.         es = acdbGetObjectId(CurveID, nameCurve);
  32.         if (es != Acad::eOk)
  33.         {
  34.             acutPrintf(_T("\n获取曲线 ID 失败!"));
  35.             return;
  36.         }
  37.         AcDbEntity* pEntCurve = NULL;
  38.         es = acdbOpenObject(pEntCurve, CurveID, AcDb::kForRead);
  39.         if (es != Acad::eOk)
  40.         {
  41.             acutPrintf(_T("\n打开曲线失败!"));
  42.             return;
  43.         }
  44.         AcDbCurve* pCurve = AcDbCurve::cast(pEntCurve);
  45.         if (pCurve == NULL)
  46.         {
  47.             pEntCurve->close();
  48.             return;
  49.         }
  50.         pCurve->close();
  51.         pEntCurve->close();

  52.         int nCount = 0;

  53.         AcGePoint3dArray mousePoints;  // 鼠标移动-点集

  54.         AcGePoint3d grrPt;
  55.         int track = 1, type;
  56.         struct resbuf result;
  57.         while (track > 0)
  58.         {
  59.             acedGrRead(track, &type, &result);   // 追踪光标移动
  60.             grrPt[X] = result.resval.rpoint[X];  // 获得用户输入点的位置
  61.             grrPt[Y] = result.resval.rpoint[Y];
  62.             int nResult = result.resval.rint;

  63.             // 点从用户坐标系坐标转换到世界坐标系
  64.             AcGePoint3d wGrrPt = UcsToWcsPoint(grrPt);

  65.             if (type == 5)  // 鼠标移动
  66.             {
  67.                 //mousePoints.append(wGrrPt);

  68.                 AcGePoint3d ptOnCurve;
  69.                 // 获取最接近曲线上的点
  70.                 pCurve->getClosestPointTo(wGrrPt, ptOnCurve, Adesk::kFalse);
  71.                 // 获取角度(弧度值)
  72.                 double dAngle = acutAngle(asDblArray(ptOnCurve), asDblArray(wGrrPt));
  73.                 // 获取曲线起点和点之间曲线段的长度
  74.                 double dLength;
  75.                 pCurve->getDistAtPoint(ptOnCurve, dLength);
  76.                 // 获取点处曲线的参数
  77.                 double dParam;
  78.                 pCurve->getParamAtPoint(ptOnCurve, dParam);
  79.                 // 获取 dParam 曲线的一阶导数
  80.                 AcGeVector3d firstDeriv;
  81.                 pCurve->getFirstDeriv(dParam, firstDeriv);
  82.                 // 计算两向量的夹角
  83.                 AcGePoint3d vecPt(0.0, 0.0, 0.0);
  84.                 AcGePoint3d vecDerivPt(firstDeriv.x, firstDeriv.y, firstDeriv.z);
  85.                 double dDer = acutAngle(asDblArray(vecPt), asDblArray(vecDerivPt));

  86.                 if ((PI * 0.5 < dDer) && (dDer <= (3.0 * PI * 0.5)))
  87.                 {
  88.                     std::string str(CW2A(strText.GetString()));
  89.                     std::reverse(str.begin(), str.end());
  90.                     strText = str.c_str();
  91.                 }
  92.                 int textLen = strText.GetLength();
  93.                 if (textLen > 1)
  94.                 {
  95.                     dDer = GetCorrectionAngle(dDer); // 校正角度
  96.                 }
  97.                 dDer = GetCorrectionAngle(dDer); // 校正角度
  98.                 double dDif = dAngle - dDer;
  99.                 // 当前注释比例的值
  100.                 double dTextSize;
  101.                 GetVar(_T("textsize"), dTextSize);
  102.                 // 文字长度
  103.                 int nTextLen = strText.GetLength();
  104.                 double ln = 0 - (1 + nTextLen * 0.5);
  105.                 // 获取位于 dLength 指定位置的点
  106.                 AcGePoint3d pt;
  107.                 pCurve->getPointAtDist(dLength + (ln + 1) * dSpacin * dTextSize, pt);
  108.                 ln++;

  109.                 SetTextRotation(CurveID, TextID, dDif, dLength, pt);
  110.             }

  111.             if (type == 2)
  112.             {
  113.                 if (nResult == 46)
  114.                 {
  115.                     dSpacin += 0.1;
  116.                     //acedAlert(_T("按下>键"));
  117.                 }
  118.                 if (nResult == 44)
  119.                 {
  120.                     dSpacin -= 0.1;
  121.                     //acedAlert(_T("按下<键"));
  122.                 }
  123.                 if (nResult == 61)
  124.                 {
  125.                     dOffset += 0.1;
  126.                     //acedAlert(_T("按下+键"));
  127.                 }
  128.                 if (nResult == 45)
  129.                 {
  130.                     dOffset -= 0.1;
  131.                     //acedAlert(_T("按下-键"));
  132.                 }
  133.                 if (nResult == 32)
  134.                 {
  135.                     track = 0;
  136.                     //acedAlert(_T("按下-空格键"));
  137.                 }
  138.                 //CString sKey;
  139.                 //sKey.Format(_T("%d"), nResult);
  140.                 //acedAlert(sKey);
  141.             }

  142.             if (type == 3)  // 用户按下了鼠标左键
  143.             {
  144.                 track = 0;
  145.             }
  146.         }
复制代码

  1.     static void SetTextRotation(AcDbObjectId CurveID, AcDbObjectId TextID, double dDif, double dLength, const AcGePoint3d& pt)
  2.     {
  3.         Acad::ErrorStatus es = Acad::eOk;

  4.         AcDbEntity* pEntCurve = NULL;
  5.         es = acdbOpenObject(pEntCurve, CurveID, AcDb::kForRead);
  6.         if (es != Acad::eOk)
  7.             return;
  8.         AcDbCurve* pCurve = AcDbCurve::cast(pEntCurve);
  9.         if (pCurve == NULL)
  10.             return;

  11.         // 当前注释比例的值
  12.         double dTextSize;
  13.         GetVar(_T("textsize"), dTextSize);
  14.         // 获取点处曲线的参数
  15.         double dParam;
  16.         pCurve->getParamAtPoint(pt, dParam);
  17.         // 获取 dParam 曲线的一阶导数
  18.         AcGeVector3d firstDeriv;
  19.         pCurve->getFirstDeriv(dParam, firstDeriv);
  20.         // 计算夹角
  21.         AcGePoint3d vecPt(0.0, 0.0, 0.0);
  22.         AcGePoint3d vecDerivPt(firstDeriv.x, firstDeriv.y, firstDeriv.z);
  23.         double dDer = acutAngle(asDblArray(vecPt), asDblArray(vecDerivPt));
  24.         double dCorrect = GetCorrectionAngle(dDer); // 校正角度
  25.         double dDist = dDif + dDer;
  26.         AcDbEntity* pEntText = NULL;
  27.         es = acdbOpenObject(pEntText, TextID, AcDb::kForWrite);
  28.         if (es != Acad::eOk) return;
  29.         if (pEntText->isKindOf(AcDbText::desc()))
  30.         {
  31.             AcDbText* pText = AcDbText::cast(pEntText);

  32.             pText->setHorizontalMode(TextHorzMode::kTextMid);
  33.             pText->setVerticalMode(TextVertMode::kTextVertMid);
  34.             AcGePoint3d AlignmentPt = PolarPoint(pt, dDist, dTextSize * dOffset);
  35.             pText->setAlignmentPoint(AlignmentPt);
  36.             pText->setRotation(dDer + dCorrect);
  37.             pText->close();
  38.         }
  39.         pEntText->close();
  40.         pCurve->close();
  41.         pEntCurve->close();
  42.     }
复制代码



本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2025-2-22 16:01:31 | 显示全部楼层
太长了不看,嘻嘻
回复 支持 反对

使用道具 举报

发表于 2025-2-22 16:14:16 | 显示全部楼层
大侠改成lisp版?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-2-22 16:26:49 来自手机 | 显示全部楼层
你有种再说一遍 发表于 2025-2-22 16:01
太长了不看,嘻嘻

还好啦,官方的例子,看到我两眼泪汪汪
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-2-22 16:32:05 来自手机 | 显示全部楼层
gzxl 发表于 2025-2-22 16:26
还好啦,官方的例子,看到我两眼泪汪汪

lisp源码就是看Lee的,还改什么?
回复 支持 反对

使用道具 举报

发表于 2025-2-22 17:22:42 | 显示全部楼层
gzxl 发表于 2025-2-22 16:26
还好啦,官方的例子,看到我两眼泪汪汪

核心就是切线是一阶导数,也就是顺着它放文字就好了.
https://www.cnblogs.com/JJBox/p/14300098.html#_label6
回复 支持 反对

使用道具 举报

发表于 2025-2-24 09:22:40 | 显示全部楼层
虽然看不懂
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-2 12:58 , Processed in 0.158494 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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