本帖最后由 edata 于 2015-8-21 13:16 编辑
终于把这个算法弄出来了,昨天因为高于90的角度计算不正确,所有一直没感确定这个算法的正确,经过多次测试,发现大于90小于270°的角度值用tan算出来需要减掉180°,最终完善了这个转换算法。
椭圆41 42 组码值要转换才能实现所见即所得。
组码10是中心点 11 是长半轴的值和方向,40是长短轴比例,41是起始角度参数(不一定等于起始角度)
42是结束角度参数。
组码11的值x值为长半轴值,x,y值构成一个点,和中心点组码10构成角度,等于椭圆的旋转角度。
以上是我对椭圆的研究所得,个人意见,仅供参考。
对于坐标点,可以参考LEE_mac的函数,通过起始角参数,比例,中心点,不管是否平行x轴,直接获得。
当然,平行X轴,有个公式直接可以用。
(list (* (cos ang) a) (* (sin ang) b))
ang是组码41或42的值 a是长半轴 b是短半轴的值(短半轴=组码11的X值*组码40值)
得到的点是相对于中心点(0 0)的坐标,可以通过计算得到起点或终点坐标,如果不平行于X轴,还得将结果按组码11与10的角度旋转。
下面是角度转参数算法例子
 - ;;tan函数
- (defun tan (ang)
- (/ (sin ang) (cos ang))
- )
- ;;角度转弧度
- (defun ang->rad(ang)
- (* pi (/ ang 180.0))
- )
- ;;当角度值大于90-270时,需要减掉180
- ;(angtos (- (atan (/ (tan (ang->b 271)) 0.6)) pi))
- ;tan(StartAngle) = ratio * tan(StratParam)
- ;(atan (* 0.6 (tan (/ pi 6.0))))
- ;;椭圆真实角度转参数
- ;;(椭圆起始角在组码中是起始参数)
- ;;(sk_el_ang->Par 真实弧度 长短轴比例值-组码40值)
- ;;所谓真实角度指的是起点或终点与长轴方向的夹角
- (defun sk_el_ang->Par(ang ratio)
- (if(and (> ang (* pi 0.5))(<= ang (* pi 1.5)))
- (- (atan (/ (tan ang) ratio)) pi)
- (atan (/ (tan ang) ratio))
- )
- )
- (defun c:tt()
- (entmake (list '(0 . "ELLIPSE")
- '(100 . "AcDbEntity")
- '(100 . "AcDbEllipse")
- (cons 10 (getpoint "point:"))
- (cons 11 (list 500 500 0))
- (cons 40 0.6)
- (cons 41 (sk_el_ang->Par(ang->rad 30) 0.6))
- (cons 42 (sk_el_ang->Par(ang->rad 150) 0.6))
- )
- )
- )
|