截面的几何参数

(alert "\n本程序命令为TEST,具体用法如下:
        \n单位和精度由ACAD确定,可自己控制,选择封闭线段物体,或者region物体,
	\n在提示数据输出方式时,按下P或W键,P代表屏幕输出,W则在C:盘创建数据。
	\n请尊重原创者,勿用于商业目的!!    Highflybird   2007.1.23  KunMing")
(defun mas (obj / Area Area1 Area2 Perimeter Centroid Centroid1 Centroid2 MomentOfInertia
	          MomentOfInertia1 PrincipalDirections PrincipalMoments minpt maxpt Sx Sy
	          ProductOfInertia ProductOfInertia1 RadiiOfGyration Wx1 Wx2 Wy1 Wy2 obj1
	          obj2 recPt1 recPt2 reg1 reg2 CenX CenY)
  (if (= "AcDbRegion" (vla-get-objectname obj))                        ;如果是截面则计算
    (progn
      (setq Area (vla-get-area obj)                                    ;面积
            Perimeter (vla-get-Perimeter obj)                          ;周长
            Centroid (V2L (vla-get-Centroid obj))                      ;质心
	    MomentOfInertia (V2L (vla-get-MomentOfInertia obj))        ;惯性矩
            PrincipalDirections (V2L (vla-get-PrincipalDirections obj));主矩方向
	    PrincipalMoments (V2L (vla-get-PrincipalMoments obj))      ;主力矩与质心的X-Y方向
	    ProductOfInertia (vla-get-ProductOfInertia obj)            ;惯性积
      )                                                                ;setq
      (vla-move obj (vlax-3d-point Centroid) (vlax-3d-point '(0 0)))   ;移动质心到原点
      (setq MomentOfInertia1 (V2L (vla-get-MomentOfInertia obj))       ;质心的惯性矩
	    ProductOfInertia1 (vla-get-ProductOfInertia obj)           ;质心的惯性积
	    RadiiOfGyration (V2L (vla-get-RadiiOfGyration obj))        ;回旋半径
      )                                                                ;setq
      (vla-getboundingbox obj 'minpt 'maxpt)                           ;边界框
      (setq minpt (vlax-safearray->list minpt)                         ;左下角点
            maxpt (vlax-safearray->list maxpt)                         ;右上角点
            Wx1 (/ (car MomentOfInertia1) (cadr minpt))                ;抵抗矩
	    Wx2 (/ (car MomentOfInertia1) (cadr maxpt))
	    Wy1 (/ (cadr MomentOfInertia1) (car minpt))
	    Wy2 (/ (cadr MomentOfInertia1) (car maxpt))
      )                                                                ;setq
      (vla-move obj (vlax-3d-point '(0 0)) (vlax-3d-point Centroid))   ;移回原来位置
      (setq obj1 (vla-copy obj)                                        ;拷贝物体以用来算X面积矩
            obj2 (vla-copy obj)                                        ;拷贝物体以用来算Y面积矩
            CenX (car Centroid)
	    CenY (cadr Centroid)
            recPt1 (list (+ CenX (car minpt) -1) CenY                  ;建立两个矩形面域的点表
	                 (+ CenX (car maxpt) +1) CenY
		         (+ CenX (car maxpt) +1) (+ CenY (cadr minpt) -1)
		         (+ CenX (car minpt) -1) (+ CenY (cadr minpt) -1))
	    recPt2 (list (+ CenX (car minpt) -1) (+ CenY (cadr minpt) -1)
		         (+ CenX (car minpt) -1) (+ CenY (cadr maxpt) +1)
		         CenX (+ CenY (cadr maxpt) +1)
		         CenX (+ CenY (cadr minpt) -1))
            reg1 (draw-rectange recPt1)                                ;创建面域1
	    reg2 (draw-rectange recPt2)                                ;创建面域2
      )
      (vla-boolean obj1 acSubtraction reg1)                            ;求obj1与面域1之差
      (vla-boolean obj2 acSubtraction reg2)                            ;求obj2与面域2之差
      (setq Area1 (vla-get-area obj1)                                  ;求obj1的面积
	    Area2 (vla-get-area obj2)                                  ;求obj2的面积
	    Centroid1 (V2L (vla-get-Centroid obj1))                    ;求obj1的质心
	    Centroid2 (V2L (vla-get-Centroid obj2))                    ;求obj2的质心
            Sx (* Area1 (- (cadr Centroid1) (cadr Centroid)))          ;绕X轴面积矩(静矩)
	    Sy (* Area2 (- (car  Centroid2) (car  Centroid)))          ;绕Y轴面积矩(静矩)
      )
      (vla-delete obj1)                                                ;删除面域1
      (vla-delete obj2)                                                ;删除面域2
      (list (cons "面积        " Area)                                 ;返回各种参数值
	    (cons "周长        " Perimeter)
	    (cons "质心        " Centroid)
	    (cons "X 轴主惯性矩" (car PrincipalMoments))
	    (cons "X 轴惯性矩  " (car MomentOfInertia1))
	    (cons "Y 轴主惯性矩" (cadr PrincipalMoments))
	    (cons "Y 轴惯性矩  " (cadr MomentOfInertia1))
	    (cons "XY惯性积    " ProductOfInertia1)
	    (cons "X 轴上抗弯距" Wx2)
	    (cons "X 轴下抗弯距" Wx1)
	    (cons "Y 轴左抗弯距" Wy1)
	    (cons "Y 轴右抗弯距" Wy2)
	    (cons "X 轴面积矩  " Sx )
	    (cons "Y 轴面积矩  " Sy )
	    (cons "回旋半径ix  " (car RadiiOfGyration))
	    (cons "回旋半径iy  " (cadr RadiiOfGyration))
	    (cons "主矩方向1   " (list (car PrincipalDirections) (caddr PrincipalDirections)))
	    (cons "主矩方向2   " (list (cadr PrincipalDirections) (cadddr PrincipalDirections)))
	    (cons "距左边距离  " (abs (car minpt)))
	    (cons "距右边距离  " (abs (car maxpt)))
	    (cons "距上边距离  " (abs (cadr maxpt)))
	    (cons "距下边距离  " (abs (cadr minpt)))
      )
    )
  )
)
;;;用ActiveX的方式画矩形面域
(defun draw-rectange (recpts / pts rec reg)
  (setq pts (vlax-make-safearray vlax-vbdouble '(0 . 7)))
  (vlax-safearray-fill pts recpts)
  (setq rec (vla-addlightweightPolyline *MSP pts));创建矩形
  (vla-put-closed rec 1)		          ;封闭矩形
  (setq reg (vla-addregion *MSP (O2L rec)))       ;对矩形求面域
  (vla-delete rec)			          ;删除矩形的轻多段线
  (car (V2L reg))                                 ;取得矩形面域物体
)
;;;ActiveX的变量转化为lisp列表
(defun V2L (x)
  (vlax-safearray->list (vlax-variant-value x))
)
;;;把选择集的物体转化为安全数组
(defun S2A (ss / i l objs curves)
  (setq i -1 l (sslength ss) objs nil)
  (repeat l
    (setq objs (cons (vlax-ename->vla-object (ssname ss (setq i (1+ i)))) objs))
  )
  (setq curves (vlax-make-safearray vlax-vbobject (eval '(cons 0 (1- l)))))
  (vlax-safearray-fill curves objs)
)
;;;把选择集的物体转化为Lisp表
(defun S2L (ss / i l objs)
  (setq i -1 l (sslength ss) objs nil)
  (repeat l
    (setq objs (cons (vlax-ename->vla-object (ssname ss (setq i (1+ i)))) objs))
  )
)
;;;物体组成lisp列表
(defun O2L (obj / curves)
  (setq curves (vlax-make-safearray vlax-vbobject '(0 . 0)))
  (vlax-safearray-fill curves (list obj))
)
;;;打印截面表并计数
(defun GetNum (regobjs Num / Number reglst)
  (setq Number Num)                               ;计数归零
  (foreach obj regobjs
    (setq reglst (mas obj))                       ;对其分别求值
    (princ obj)				          ;打印region名
    (princ "\n下面为该物体的参数的列表: ")
    (foreach n reglst (princ "\n") (princ n))     ;打印region参数表
    (setq Number (1+ Number))                     ;计数累加
  )
)
;;;表转化成字符串
(defun L2S (lst / s)
  (setq	s
	 (apply
	   'strcat
	   (mapcar '(lambda(x)(strcat (rtos x) " ")) lst)
	 )
  )
  (setq s (substr s 1 (1- (strlen s))))
  (strcat "(" s ")")
)
;;;写数据函数
(defun WrData (regobjs Num / Number reglst string str1 str2 str)
  (setq Number Num)                               ;计数归零
  (foreach obj regobjs
    (setq reglst (mas obj))                       ;对其分别求值
    (setq Number (1+ Number))                     ;计数累加
    (write-line "***********************************" file)
    (setq string (strcat "截面" (itoa Number) "的参数表:"))
    (write-line string file)                      ;写入region名
    (foreach n reglst
      (setq str1 (car n))                         ;参数名称
      (if (listp (setq str2 (cdr n)))             ;参数值
	(setq str2 (L2S str2))
	(setq str2 (rtos str2))
      )
      (setq str (strcat str1 ": " str2))
      (write-line str file)                       ;写入region参数表
    )
  )
  Number
)
;;;以下测试程序
(defun C:test (/ *APP *DOC *MSP i j ss ss1 err objlst REGs W&P OLDCMD OldUcs file)
  (vl-load-com)
  (setq	*APP (vlax-get-acad-object)
	*DOC (vla-get-activeDocument *APP)
	*MSP (vla-get-Modelspace *DOC)
  )
  (princ)
  (if (setq ss (ssget))                           ;建立选择集
    (progn
      (initget 1 "W P")                           ;选择写入文件或屏幕打印
      (setq W&P (getkword "\n确定输出数据方式:\n写入文件[W]或屏幕打印[P])?"))
      (princ "\n")
      (setq OLDCMD (getvar "CMDECHO"))
      (setvar "CMDECHO" 0)
      ;;(command ".UCS" "W")
      (uu 1)
      (setq objlst (S2A ss))                      ;选择集列表
      (if (setq ss1 (ssget "P" '((0 . "REGION"))));选择集中已有的region
	(setq i (if (= W&P "P")                   ;计算并求出region数目
		  (GetNum (S2L ss1) 0)
		  (progn
		    (setq file (open "C:\\截面几何参数.TXT""W"));打开文件
                    (Wrdata (S2L ss1) 0)
		  )
		)
	)
	(setq i 0)
      )
      (defun addreg ()
	(setq REGs (vla-addregion *MSP objlst))
      )
      (setq err (vl-catch-all-apply 'addreg))     ;建立区域并出错检测
      (if (vl-catch-all-error-p err)              ;如果没有新建任何region
        (setq j 0)                                ;则计数为0
	(setq REGs (V2L REGs)                     ;否则转化成region集合
              i (if (= W&P "P")                   ;计算并求出region数目
		  (GetNum REGs i)
		  (progn
		    (setq file (open "C:\\截面几何参数.TXT""A"));打开文件
		    (Wrdata REGs i)
		  )
		)
	      j (mapcar 'vla-delete REGs)         ;删除刚建立的截面
	)
      )
      (close file)                                ;关闭文件
      (if (/= 0 i)
	(progn
          (princ "\n\n已经列出")
          (princ i)
          (princ "个截面几何参数表.")
	)
	(alert "没有选中有效的截面!")
      )
      ;;(command ".UCS" "P")
      (uu 0)
      (setvar "CMDECHO" OLDCMD)
    )
    (alert "你没有选中物体! ")
  )
  (gc)
  (princ)
)
(defun uu (T&F / WCSOrg WCSXDr WCSYDr WCSObj OldOrg OldXDr OldYDr *UTI *UCS)
  (setq *UTI (vla-get-Utility *DOC)                             ;取得Utility集
	*UCS (vla-get-UserCoordinateSystems *DOC)               ;取得UCS集
  )
  (setq WCSOrg (vlax-3d-point '(0 0 0)))                        ;WCS原点
  (setq WCSXDr (vlax-3d-point '(1 0 0)))
  (setq WCSYDr (vlax-3d-point '(0 1 0)))
  (setq WCSObj (vla-add *UCS WCSOrg  WCSXDr WCSYDr "WCS"))
  (if (= T&F 1)
    (progn
      (if (= (getvar "UCSNAME") "")                             ;当前UCS名,如果未命名,则
        (progn
          (setq OldOrg (vla-GetVariable *DOC "UCSORG")          ;取当前UCS原点
  	        OldXDr (vla-getVariable *DOC "UCSXDIR")         ;取当前X方向
	        OldYDr (vla-getVariable *DOC "UCSYDIR")         ;取当前Y方向
	        OldUcs (vla-add *UCS WCSOrg OldXDr OldYDr "OLD");建立当前UCS,但原点在'(0,0,0)处
          )
          (vla-put-origin OldUcs OldOrg)                        ;改变原点为当前UCS原点
        )
        (setq OldUcs (vla-get-ActiveUcs *DOC))                  ;如果已经命名,则取得UCS物体
      )
      (vla-put-ActiveUcs *DOC WCSobj)
    )
    (vla-put-ActiveUcs *DOC OldUcs)
  )
  OldUcs
)

时间是一台不停地卷走你脚下地毯的机器

人们总喜欢回头看看,甚至是排泄物!这也许是人类的习性。
我每次回头看过去时,总是茫然,茫然得想哭,却哭不出来。

时间是一台不停地卷走你脚下地毯的机器,把你所走过的每一寸土地全部沦陷,把你所得到的全都沉入那深深的海洋里,让你永远也找不到,拾不起,收不回,任它在海底化为尘泥或者沙石,幸运的话可以变成珍珠。
把我的感想慢慢记录下来吧,让时光这个恶魔吞噬吧,希望在以后的某一天,或许能找到它吐出来的残渣。

我和我爱的几何,不得不说的故事

有幸能看到Joseflin出了这么多题目锻炼大家的思维,以及他的雄心壮志,心中亦有所感。虽不才,然亦想谈谈我对几何与CAD的认识。

在我读高中时,那是偶然发现一个几何命题:从某一点引出三条射线,与从另一点引出的三条射线,他们的相交成如下图1,

jh1-1

在这个田字状中,其对角连线与其相应边上的另四个点所构成的两条连线,三条线要么相交于一点,要么平行。我当时很高兴,但那时竟然没有办法证明。当上大学之后,学了画法几何及其透视与阴影之后,我对这个命题的证明思路一下子开朗了:把这个田字状的用透视观点去看它,他们相交于与一点,那就是他们的灭点。于是本命题的证明就转化为证明一个矩形上的那几个点的连线是相交于一点或平行的。这就容易多了。我自认为发现了一个定理,等到我参加工作后,我用CAD验证了这个命题。然而后来一个偶然的机会让我接触到了高等几何,阅读了朱德祥老先生的《高等几何》后,我知道我自己说的命题就是巴卜斯/巴斯卡定理的变换型。那9个点,12条线都是有代号的。至此,心里有一点点失望,然而更多的是喜悦。因为我知道那时我已经不自觉地运用了射影中的某些性质,如对偶性,结合性等。
从这一点可以看出,一个简单的几何形状中,往往蕴含了很多的奥秘和定理。

同样是在高中时,老师告诉我们了蝴蝶定理,还让我们证明,但只是局限于圆上的蝴蝶定理,也没让我们对这个定理深入想下去。到了大学,我又开始空想了,我想把这个定理推广到二次曲线上,发现它是成立的,甚至是变态的二次曲线,如下图2:

jh1-2

过AB的中点作两条线段分别交曲线(或直线)于M,N和P,Q,连接MQ交AB于C,连接NP交AB于D,则必有OC=OD。后来我想了一个巧妙的办法证明了它:那就是参数方程法。证明比较短。我想把这个定理再推广到三次及其以上的曲线,发现它不成立了,它就是二次曲线的固有性质。在工作中我用数学软件MATLAB,MAPLE分别证明了它,也就是在代数上亦是成立的。到书店翻阅一下,发现我的想法又跟别人想到一块了,不过人家是数学家,证明的工具竟然还是高等几何的方法,很简短的几行。
我想,这就是几何:一定的形,包含着一定的理,同时也包含着一定的数。

那时我还在农村时,有一个问题,如何确定一点使得到另三点的距离和为最小,(在实际生活中可能遇上)。当时我父亲跟我说,这个题跟物理与关联。在某一年的春节,我想着这个问题,模模糊糊中,我好像得到解,醒来后,我画了一个图,三角形内一点与三顶点连线所形成的夹角都是120 º。这就是解(当然,如果三角形中的某一个角大于120º,那么这个角的顶点就是解),那时我没有掌握多少理论知识,使出浑身的解术,左画又画,竟然无从得手。后来慢慢就淡忘了。然而,该忘记的总是忘不了,有时心里毫无去处时,或许会飘来一下它的影子。多少年之后,我断断续续知道我得到的是正解,有几何证法的,有矢量证明法的等等,再后来我上了网,知道这个点叫费马点。(他是业余数学之王)。在这些年中,我想了更多,我开始想把它推广到凸多边形,例如五边形,然而,并不是所有的五边形都存在那么一点,使得这点与各顶点形成的夹角都是360º/5=72º,那么这一点究竟在哪里呢?后来我又反过来想,如果有那么一个五边形,存在那么一点,使得使得这点与各顶点形成的夹角都是360º/5=72º,那么这点与各顶点距离和一定就是最小么?现在我终于得到了证明:
首先看定理一:一个凸N多边形,如果其内角都相等的话,则从多边形内任一点到各边的距离和(记为内垂距和)都相等,且等于这个多边形边长平均值构成的正N多边形的内垂距和。(见下图3)
jh1-3
我以五边形为例,对五边形进行如下变换,其中AB1为边长的平均值,品红色为变换后的部分,青色为原有图形,黄色粗线段等于蓝色粗线段。很明显可看出变换之后,其中一条边长已变成了平均值,但周长和内垂距还是跟变换前相等。因此最多经过N-2次变换后就成为一个正多边形了。正多边形的证明是很容易的。定理得证。
定理二:如果一个凸N多边形,内有一点满足这点与各顶点形成的夹角都是360º/N,那么这点与各顶点距离和为最小值。
见下图4,
jh1-4
我以五边形为例:红色粗线条的是凸五边形A1A2A3A4A5,O点是与各顶点形成的夹角都为72º,构造一个内角都为108º的五边形B1B2B3B4B5,对于A1A2A3A4A5内的另一点O1,则有O1A1+ O1A2+ O1A3+ O1A4+ O1A5> O1H1+ O1H2+ O1H3+ O1H4+ O1H5,依据定理一有:O1H1+ O1H2+ O1H3+ O1H4+ O1H5=OA1+ OA2+ OA3+ OA4+ OA5,因而证明了O点就是极小值点。N多边形类似证明。注意了,我这里讨论的都是奇数边多边形,偶数的其实要更简单,而且条件没有这么严格。(只要满足相对顶点连线相交于一点就是了)
关于这个的严格证明我不在此赘述了。我还发现,对于不能满足条件的多边形,这个极小值点与顶点形成的夹角与角的平均值偏差总是最小。说到这里,我竟然要把此定理称呼为曾子定理了,如果大家在其他地方见过此定理,请告知我名字,但我决非抄袭。
(网站只能上传5张图片,想多发图片表达我想法也无奈)

正是因为如此,我工作后仍然扔不下几何,有时间就瞎弄两下,再在CAD上验证验证,怡然自得。几何与建筑,几何与代数,几何与艺术,几何与设计,这之中血肉相连。秩序和节奏,比例与构图,排列和组合,韵律与均衡,突变和协调,变换之中的永恒;分形,傅立叶级数,微积分,迭代,射影与仿射,…,既是形,又是数, 恍如一扇门里还一扇扇门,无穷无尽。有我真希望大学能开一门设计数学的科目。

再次申明,由于我对于数学的认识仅限于皮毛,帖子中纰漏之处,骂我无知则可,人身攻击则免。

说了这么多,写了这么多,画了这么多,或问曰:何用之有? 吾茫然,环顾四周,愿有人能应者。足矣!