动态插入箭头
平常因为工作的关系经常要插入一些箭头,根据鼠标的位置变化方向和变化.之前有人写过这个功能,我就按照样例仿写了一下,可能因为水平的关系算法有些复杂,还希望大家轻拍,麻烦各位大侠帮忙把算法优化一下,刚写完没有完全测试可能有点小问题.(defun c:tt ()
(vl-load-com)
(setq acad (vlax-get-acad-object))
(setq acaddocument (vla-get-activedocument acad))
(setq mspace (vla-get-modelspace acaddocument))
(setq h (getreal "\n请输入偏移距离"))
(setq endata (entsel "\n请选择一条线"))
(setq ename (car endata))
(setq p0 (cadr endata))
(setq obj (vlax-ename->vla-object ename))
(setq l1 (car (vlax-safearray->list (vlax-variant-value (vla-offset obj h))))) ;偏移曲线1
(setq l2 (car (vlax-safearray->list (vlax-variant-value (vla-offset obj (* -1 h)))))) ;偏移曲线2
(setq p1 (vlax-curve-getclosestpointto l1 p0 t)) ;插入点1
(setq p2 (vlax-curve-getclosestpointto l2 p0 t)) ;插入点2
(vla-delete l1) ;删除曲线1
(vla-delete l2) ;删除曲线2
(setq ang1 (angle p2 p1));插入点1 点2角度
(setq ang2 (- ang1 (/ pi 2)));计算直线角度或者曲线的切线角度
(setq obj (vla-insertblock mspace (vlax-3d-point p2) "11005" 1 1 1 ang2)) ;插入块名为11005的图块
(setq loop t)
(while loop
(setq code (grread t 8))
(cond
((= (car code) 5)
(setq ang3 (- (angle p0 (cadr code)) ang2)) ;光标所在点与单选点的角度减去直线的或者曲线切线的角度
(if (< ang3 0)
(setq ang3 (+ ang3 (* 2 pi))))
(cond
((and (> ang3 0 ) (< ang3(/ pi 2)))
(vla-put-Rotation obj ang2)
(vla-put-insertionpoint obj (vlax-3d-point p1))
)
((and (> ang3 (/ pi 2)) (< ang3 pi))
(vla-put-Rotation obj (- ang2 pi))
(vla-put-insertionpoint obj (vlax-3d-point p1))
)
((and (> ang3 pi) (< ang3(* 3 (/ pi 2))))
(vla-put-Rotation obj (- ang2 pi))
(vla-put-insertionpoint obj (vlax-3d-point p2))
)
((and (> ang3 (* 3 (/ pi 2))) (< ang3(* 2 pi)))
(vla-put-Rotation obj ang2)
(vla-put-insertionpoint obj (vlax-3d-point p2))
)
)
)
((= code '(25 37)) (vla-delete obj))
(T (setq loop nil))
)
)
)
根据自己使用改了下,在图形中第一次使用时,输入名字,自动创建一个800*400的箭头块,或者选择已有块 ;; 曲线动态插入箭头
本帖最后由 adolfken 于 2013-4-15 18:39 编辑
在院长和wowan两位大侠的指导下我按照正常切线方向的计算写了代码,非常感谢两位. (defun c:tt ()
(vl-load-com)
(setq acad (vlax-get-acad-object))
(setq acaddocument (vla-get-activedocument acad))
(setq mspace (vla-get-modelspace acaddocument))
(setq h (getreal "\n请输入偏移距离"))
(setq endata (entsel "\n请选择一条线"))
(setq p0 (cadr endata))
(setq l1 (vlax-ename->vla-object (car endata)))
(setq p1 (vlax-curve-getclosestpointto l1 p0 t))
(setq ang1 (angle p1 (mapcar '+ p1 (vlax-curve-getfirstderiv l1 (vlax-curve-getparamatpoint l1 p1)))))
(setq p2 (polar p1 (+ ang1 (/ pi 2)) h))
(setq p3 (polar p1 (- ang1 (/ pi 2)) h))
(setq obj (vla-insertblock mspace (vlax-3d-point p2) "11005" 1 1 1 ang1))
(setq loop t)
(while loop
(setq code (grread t 8))
(cond
((= (car code) 5)
(setq ang2 (- (angle p1 (cadr code)) ang1))
(if (< ang2 0)
(setq ang2 (+ ang2 (* 2 pi))))
(cond
((and (> ang2 0 ) (< ang2 (/ pi 2)))
(vla-put-Rotation obj ang1)
(vla-put-insertionpoint obj (vlax-3d-point p2))
)
((and (> ang2 (/ pi 2) ) (< ang2 pi))
(vla-put-Rotation obj (- ang1 pi))
(vla-put-insertionpoint obj (vlax-3d-point p2))
)
((and (> ang2 pi ) (< ang2(* 3 (/ pi 2))))
(vla-put-Rotation obj (- ang1 pi))
(vla-put-insertionpoint obj (vlax-3d-point p3))
)
((and (> ang2 (* 3 (/ pi 2))) (< ang2(* pi 2)))
(vla-put-Rotation obj ang1)
(vla-put-insertionpoint obj (vlax-3d-point p3))
)
)
)
((= (car code) 25) (setq loop nil) (vla-delete obj))
(T (setq loop nil))
)
)
)
这个好是好 工作关系用不上 感谢热心人 出现错误:
请选择一条线; 错误: Automation 错误。 文件处理器错误
另外最好距离可以点选。 yaya-54 发表于 2013-5-10 11:00 static/image/common/back.gif
出现错误:
请选择一条线; 错误: Automation 错误。 文件处理器错误
另外最好距离可以点选。
同样的错误
同样的建议 看明白了,原来是要先自己画个箭头做个块 错误: Automation 错误。 文件处理器错误 本帖最后由 j15tty 于 2020-1-10 14:44 编辑
C:\Users\Administrator\Desktop\GIF动画录制工具20200110141850.gif public class 坡度标注Jig : DrawJig
{
public Autodesk.AutoCAD.DatabaseServices.Polyline m_pl;
private Point3d m_pt, m_insertPt;
public static DBText m_text = new DBText();
private Curve m_c;
public static double m_bl = 1;
public static double m_jj = 3;
public static double m_h = 3;
private Database m_db;
public 坡度标注Jig(Autodesk.AutoCAD.DatabaseServices.Polyline pl, DBText text, Curve c, Point3d pt, Database db, double bl, double jj, double h)
{
m_pl = pl;
m_pt = pt;
m_text = text;
m_c = c;
m_db = db;
m_bl = bl;
m_jj = jj;
m_h = h;
}
protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
{
Point3d p1 = m_c.GetClosestPointTo(m_insertPt, false);
Vector3d vecCz = m_insertPt - p1;//鼠标点到曲线的垂足点的向量
Vector3d vec = m_insertPt - m_pt;//得到鼠标与曲线上点取点的向量
Vector3d vec1 = m_c.GetFirstDerivative(m_pt);//曲线点切向量
double angFx = vec.GetAngleTo(Vector3d.XAxis, -Vector3d.ZAxis);//鼠标点与曲线上点取点向量与X轴的夹角;
double angQx = vec1.GetAngleTo(Vector3d.XAxis, -Vector3d.ZAxis);
double ang = vec.GetAngleTo(vec1);
Point3d insertPt, pt1, pt2, pt3;
bool flag = IsLeftOfCurve(m_c, m_insertPt);
if (flag == true)
{
insertPt = m_pt.polarPoint(angQx + Math.PI / 2, m_jj);
if (ang < Math.PI / 2)
{
pt1 = insertPt.polarPoint(angQx + Math.PI, m_bl * 5);
pt2 = pt1.polarPoint(angQx, m_bl * 10);
pt3 = pt2.polarPoint(angQx, m_bl * 3.5);
m_text.Position = insertPt.polarPoint(angQx + Math.PI / 2, m_bl * 0.5 + m_text.Height / 2);
m_text.Rotation = angQx;
m_text.Height = m_h;
m_text.HorizontalMode = TextHorizontalMode.TextMid;
m_text.VerticalMode = TextVerticalMode.TextBottom;
m_text.AlignmentPoint = m_text.Position;
m_text.AdjustAlignment(m_db);
}
else
{
pt1 = insertPt.polarPoint(angQx, m_bl * 5);
pt2 = pt1.polarPoint(angQx + Math.PI, m_bl * 10);
pt3 = pt2.polarPoint(angQx + Math.PI, m_bl * 3.5);
m_text.Position = insertPt.polarPoint(angQx + Math.PI / 2, m_bl * 0.5 + m_text.Height / 2);
m_text.Rotation = angQx;
m_text.Height = m_h;
m_text.HorizontalMode = TextHorizontalMode.TextMid;
m_text.VerticalMode = TextVerticalMode.TextBottom;
m_text.AlignmentPoint = m_text.Position;
m_text.AdjustAlignment(m_db);
}
}
else
{
insertPt = m_pt.polarPoint(angQx - Math.PI / 2, m_jj);
if (ang < Math.PI / 2)
{
pt1 = insertPt.polarPoint(angQx + Math.PI, m_bl * 5);
pt2 = pt1.polarPoint(angQx, m_bl * 10);
pt3 = pt2.polarPoint(angQx, m_bl * 3.5);
m_text.Position = insertPt.polarPoint(angQx - Math.PI / 2, m_bl * 0.5 + m_text.Height / 2);
m_text.Rotation = angQx + Math.PI;
m_text.Height = m_h;
m_text.HorizontalMode = TextHorizontalMode.TextMid;
m_text.VerticalMode = TextVerticalMode.TextBottom;
m_text.AlignmentPoint = m_text.Position;
m_text.AdjustAlignment(m_db);
}
else
{
pt1 = insertPt.polarPoint(angQx, m_bl * 5);
pt2 = pt1.polarPoint(angQx + Math.PI, m_bl * 10);
pt3 = pt2.polarPoint(angQx + Math.PI, m_bl * 3.5);
m_text.Position = insertPt.polarPoint(angQx - Math.PI / 2, m_bl * 0.5 + m_text.Height / 2);
m_text.Rotation = angQx + Math.PI;
m_text.Height = m_h;
m_text.HorizontalMode = TextHorizontalMode.TextMid;
m_text.VerticalMode = TextVerticalMode.TextBottom;
m_text.AlignmentPoint = m_text.Position;
m_text.AdjustAlignment(m_db);
}
}
m_pl.Normal = Vector3d.ZAxis;
m_pl.Elevation = 0.0;
m_pl.SetPointAt(0, new Point2d(pt1.X, pt1.Y));
m_pl.SetPointAt(1, new Point2d(pt2.X, pt2.Y));
m_pl.SetPointAt(2, new Point2d(pt3.X, pt3.Y));
m_pl.SetStartWidthAt(0, 0);
m_pl.SetEndWidthAt(0, 0);
m_pl.SetStartWidthAt(1, m_bl);
m_pl.SetEndWidthAt(1, 0);
m_pl.SetStartWidthAt(2, 0);
m_pl.SetEndWidthAt(2, 0);
draw.Geometry.Draw(m_pl);
draw.Geometry.Draw(m_text);
return true;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
Matrix3d mat = ed.CurrentUserCoordinateSystem;
JigPromptPointOptions optInsertPt = new JigPromptPointOptions("\n请选择方向或[比例增(A)/比例减(S)/间距增(D)/间距减(F)/坡度设置(Q)]");
optInsertPt.UserInputControls = (UserInputControls.Accept3dCoordinates |
UserInputControls.NullResponseAccepted |
UserInputControls.NoNegativeResponseAccepted |
UserInputControls.GovernedByOrthoMode);
optInsertPt.Keywords.Add("A");
optInsertPt.Keywords.Add("S");
optInsertPt.Keywords.Add("D");
optInsertPt.Keywords.Add("F");
optInsertPt.Keywords.Add("Q");
optInsertPt.AppendKeywordsToMessage = false;
//m_pt = m_pt.TransformBy(mat);
PromptPointResult resJigInsertPt = prompts.AcquirePoint(optInsertPt);
if (resJigInsertPt.Status == PromptStatus.Cancel)
return SamplerStatus.Cancel;
if (resJigInsertPt.Status == PromptStatus.Keyword)
{
switch (resJigInsertPt.StringResult)
{
case "A":
{
m_bl = m_bl * 2;
m_h = m_h * 2;
break;
}
case "S":
{
m_bl = m_bl * 0.5;
m_h = m_h * 0.5;
break;
}
case "D":
{
m_jj = m_jj * 1.1;
break;
}
case "F":
{
m_jj = m_jj * 0.9;
break;
}
case "Q":
{
PromptStringOptions opt = new PromptStringOptions("\n请输入坡度");
PromptResult res = ed.GetString(opt);
if (res.Status != PromptStatus.OK)
break;
else
{
try
{
double value = Convert.ToDouble(res.StringResult);
if (value >= 10)
{
if (MyEntity.IsInteger(res.StringResult))
{
m_text.TextString = (value / 10).ToString("0") + "%";
}
else
{
m_text.TextString = (value / 10).ToString("0.####") + "%";
}
}
else
m_text.TextString = res.StringResult + "‰";
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.Message);
m_text.TextString = "3" + "‰";
}
}
break;
}
}
}
if (m_insertPt != resJigInsertPt.Value)
{
m_insertPt = resJigInsertPt.Value;
return SamplerStatus.OK;
}
else
{
return SamplerStatus.NoChange;
}
}
页:
[1]