明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: hrer

如何自动生成不规则多边形的质心

  [复制链接]
发表于 2012-3-4 22:25 | 显示全部楼层
太复杂了啊
发表于 2012-5-17 23:43 | 显示全部楼层
多谢langjs 的程序,今天用到了,很好!有时间自己好好学习一下
发表于 2012-5-18 09:32 | 显示全部楼层
谢谢各位的代码!
发表于 2013-1-28 14:57 | 显示全部楼层
langjs 发表于 2012-2-14 20:56
来个多个闭合区域一起框选的。

;;; 框选多个闭合图形画质心点 by:langjs

正好在找这个资源,非常感谢
发表于 2014-5-12 13:00 | 显示全部楼层
本帖最后由 ynhh 于 2014-5-12 13:04 编辑
langjs 发表于 2012-2-14 20:56
来个多个闭合区域一起框选的。

;;; 框选多个闭合图形画质心点 by:langjs

大师您好
你这能自动生成质心
我是想能不能把两个不同型号的槽钢背对背中间有10mm空隙
想取得这两槽钢组成的一个整体截面中空组合截面惯性矩?



以下这个只能是分开得到答案,能不能改为整体的啊?
谢谢您.

(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 list->string (lst)
(strcat "(" (apply 'strcat (mapcar '(lambda (x) (strcat (rtos x) " ")) lst)) ")")
)
;;;写数据函数
(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 (list->string str2))
(setq str2 (rtos str2))
)
(setq str (strcat str1 ": " str2))
(write-line str file) ;写入region参数表
)
)
Number
)
;;;以下测试程序
(defun C:A (/ i j ss ss1 err objlst REGs W&P OLDCMD file)
(vl-load-com)
(setq *Obj (vlax-get-acad-object)
*Doc (vla-get-activeDocument *Obj)
*MSp (vla-get-Modelspace *Doc)
)
(princ);我试只能对一个或多个单独的封闭线计算,对中空组合截面惯性矩好象不能同步计算?????
(princ "n单位和精度由ACAD确定,可自己控制,选择封闭线段物体,或者region物体,
n在提示数据输出方式时,按下P或W键,P代表屏幕输出,W则在D:盘创建数据。
n请尊重原创者,勿用于商业目的!! Highflybird 2007.1.23 KunMing")
(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")
(setq objlst (S2A ss)) ;选择集列表
(setq file (open "D:截面几何参数.txt""w"));打开文件
(if (setq ss1 (ssget "P" '((0 . "REGION"))));选择集中已有的region
(setq i (if (= W&P "P") ;计算并求出region数目
(GetNum (S2L ss1) 0)
(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)
(Wrdata REGs i)
)
j (mapcar 'vla-delete REGs) ;删除刚建立的截面
)
)
(close file) ;关闭文件
(if (/= 0 i)
(progn
(princ "nn已经列出")
(princ i)
(princ "个截面几何参数表.")
)
(alert "没有选中有效的截面!")
)
(command ".UCS" "P")
(setvar "CMDECHO" OLDCMD)
)
(alert "你没有选中物体! ")
)
(princ)
)

本帖子中包含更多资源

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

x
发表于 2014-5-12 13:59 | 显示全部楼层
本帖最后由 xyp1964 于 2014-5-12 14:32 编辑
  1. ;; 闭合曲线质心
  2. (defun Centroid (s1 / s2 pt)
  3.   (command "copy" s1 "" '(0 0) '(0 0))
  4.   (command "region" (entlast) "")
  5.   (setq s2 (entlast)
  6.         pt (vlax-get (vlax-ename->vla-object s2) 'Centroid)
  7.   )
  8.   (entdel s2)
  9.   pt
  10. )
发表于 2014-5-12 14:12 | 显示全部楼层
ynhh 发表于 2014-5-12 13:00
大师您好
你这能自动生成质心
我是想能不能把两个不同型号的槽钢背对背中间有10mm空隙

将两个型钢组合成一个面域,再利用函数vla-get-MomentOfInertia求惯性矩
工具箱函数:(xyp-get-RegionValue ename 6)
发表于 2014-5-12 15:31 | 显示全部楼层
xyp1964 发表于 2014-5-12 14:12
将两个型钢组合成一个面域,再利用函数vla-get-MomentOfInertia求惯性矩
工具箱函数:(xyp-get-RegionVa ...

大师好:
生成的面域是两个分开的
而不是一整个面域啊?
好象可用并集合并成一个面域再求
不如用LISP如何合并后再求?
感谢你的指点

点评

多少个型钢组合都可以  发表于 2014-5-12 16:21
发表于 2014-5-12 16:34 | 显示全部楼层
好东西啊,赞一个
发表于 2015-7-25 09:55 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-26 17:41 , Processed in 0.233386 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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