|
Calculate and create Elliptical Arcs using LISP and ADS ObjectARX使用 LISP 和 ADS ObjectARX 计算和创建椭圆弧
问题
在开椭圆(椭圆弧)的 DXF 参考列表中,组代码 41 被描述为"开始参数"。但是,很难确定它与弧的已知值的关联。此值是如何得出的?什么是参数化角度,如何从真实起始角度计算它?
溶液
椭圆弧是遵循椭圆偏心率的弧的特殊版本。生成此类弧的一种方法是找到起点的参数法线。为此,必须指定一个与绘制的弧的实际起始角度不同的起始角度。组代码 41 包含以弧度表示的参数化角度。
参数化角度由两个同心圆生成,其中心是椭圆的中心,其半径分别是长轴和小轴。椭圆的每个点都位于这两个圆之间或之上,并且每个椭圆点都可以通过与它们的唯一关系来定义。要发现此关系,请绘制一条垂直于长轴的线,从椭圆上的某个点到与长轴所描述的圆最近的交点。然后对短轴执行相同的操作,从椭
圆点开始,垂直于短轴绘制,直到直线与短轴描述的圆相交。与圆相交的两个点与椭圆的中心共线。包含这三个点的线与长轴之间的角度是组代码 41 指定的参数化角度。
要根据真实起始角度计算参数化角度,必须首先在椭圆上找到起点。这需要同时解直线和椭圆的方程。在此示例中,我们假设椭圆的长轴位于 x 轴上,原点位于椭圆的中心。找到此点后,可以使用其 y 值和短轴求解半径为短轴值且中心为椭圆中心的圆的方程。这将在圆上提供 x,y 点,该点指示从椭圆中心开始的参数化角度。
下面是一个 AutoLisp 示例,演示如何使用三角函数来确定参数角度:
[code](defun c:e_arc( / a b slope ang q1 q2 q3 q4 qmode x y a2)
;;assuming 0,0 is at the center of the ellipse, major axis in x direction
(setq ang (getangle '(0.0 0.0) "Choose start angle: "))
(setq a 1
b 0.5
slope (/ (sin ang) (cos ang))
q1 (/ pi 2.0)
q2 pi
q3 (/ (* 3 pi) 2.0)
q4 (* 2.0 pi)
qmode 'q1
);setq
(entmake
(setq ent '((0 . "ELLIPSE")
(100 . "AcDbEntity")
(100 . "AcDbEllipse")
(10 0.0 0.0 0.0)
(11 1.0 0.0 0.0)
(40 . 0.5)
(62 . 1)
)
);setq
);entmake
;;line equation is y = mx + 0, where m is the slope and 0 is the y-intercept
;;ellipse equation is x^2/a^2 + y^2/b^2 = 1
;;solve line and ellipse equations simultaneously to find x and y values
(setq y (/ (* a b slope) (sqrt (+ (* (* slope slope) (* a a)) (* b b)))))
;;minor axis circle equation is x^2 + y^2 = b^2
;;solve circle equation where y = value calculated above
(setq x (sqrt (- (* b b) (* y y))))
;;calculate start angle trigonometrically
(setq cos_a2 (/ x b)
sin_a2 (/ y b)
);setq
(if (/= cos_a2 0)
(setq a2 (atan (/ sin_a2 cos_a2)))
(setq a2 q1
qmode 'q1
)
);if
;;make a2 insensitive to quadrant
(cond
((and (> ang q1) (< ang q2))
(setq a2 (- pi (abs a2))
qmode 'q2
);setq
);statement 1
((and (> ang q2) (< ang q3))
(setq a2 (+ (abs a2) pi)
qmode 'q3
);setq
);statement 2
((and (> ang q3) (< ang q4))
(setq a2 (abs (- (* 2 pi) (abs a2)))
qmode 'q4
);setq
);statement 3
;;special cases: angle = 0, 90, 180, 270 or 360 deg
((or (= ang 0) (= ang q1))
(setq qmode 'q1)
);statement 4
((= ang q2)
(setq a2 pi
qmode 'q1
)
);statement 5
((= ang q3)
(setq a2 (- (/ pi 2.0) pi)
qmode 'q1
)
);statement 6
(t nil);default statement
);cond
(command "zoom" "c" "0,0" 3)
(setq ent (append ent (list (cons 41 a2) (cons 42 (+ a2 (/ pi 2.0))))))
(setq ent (subst '(62 . 5) (assoc 62 ent) ent))
(entmake ent)
(setq a2
(cond
((= qmode 'q1) a2)
((= qmode 'q2) a2)
((= qmode 'q3) (- a2 q4))
((= qmode 'q4) (- a2 q4))
(t nil)
);cond
);setq
(princ "\nParametric angle in radians: ")
(princ a2)
(princ "\nParametric angle in degrees: ")
(princ (/ (* 180 a2) pi))
(princ)
);e_arc[/code] |
|