分享

张勇:编程求解幕墙复杂面域几何属性的方法

 联想派 2022-10-12 发布于埃及

作者:张勇   中建八局装饰工程有限公司

【摘要】 本文讲述在AutoCAD二次开发平台基于C#编程求解复杂面域几何属性的方法,从只有一个连通域的面域到多个连通域的面域,由简单到复杂,逐步深入探究几何属性计算机求解的过程。

【关键词】复杂面域 面域几何属性  编程求解

AbstractComplex Region  Geometric Properties of An Area  Programming Solution

Key wordsThis paper describes the method of solving the geometric attributes of complex regions based on C # programming, from regions with only one connected region to regions with multiple connected regions, from simple to complex, and gradually explores the process of computer solving geometric attributes.

在土木行业中,大型复杂结构计算一般采用专业的有限元软件,如YJKPKPMANSYSSAP20003D3S等,但一些简单结构,用静力学手册公式计算即可解决,这些结构的计算适用于开发简单的桌面应用程序,在工程设计应用中可大大提高工作效率。

幕墙的立柱和横梁就是这样的可自编公式计算的简单结构,但其铝合金型材截面通常比较复杂,在得到杆件内力后,计算复杂面域的几何属性是必不可少的,本文试图将这方面的知识作一简单阐述。

AutoCAD二次开发平台,以C#编程语言为背景,分几个模块讲述其中的重要代码和编程思路:

1,AutoCAD中获取曲线。

曲线种类以代码方式表示如下: 

RXClass.GetClass(typeof(Line)).DxfName;     //直线

RXClass.GetClass(typeof(Polyline)).DxfName; //二维多段线

RXClass.GetClass(typeof(Circle)).DxfName;   //

RXClass.GetClass(typeof(Arc)).DxfName;      //圆弧

RXClass.GetClass(typeof(Spline)).DxfName;   //样条曲线

RXClass.GetClass(typeof(Ellipse)).DxfName;  //椭圆及椭圆弧

将上述类型定义为一个过滤器,在选择集中使用这个过滤器得到满足要求的曲线。

TypedValue[] values = {

new TypedValue((int)DxfCode.Operator, '<or'),

new TypedValue((int)DxfCode.Start, dxfnameLine),

new TypedValue((int)DxfCode.Start, dxfnamePolyline),

new TypedValue((int)DxfCode.Start, dxfnameCircle),

new TypedValue((int)DxfCode.Start, dxfnameArc),

new TypedValue((int)DxfCode.Start, dxfnameSpline),

new TypedValue((int)DxfCode.Start, dxfnameEllipse),

new TypedValue((int)DxfCode.Operator, 'or>')

};

var filter = new SelectionFilter(values);

var entSelected = ed.GetSelection(filter);

if (entSelected.Status == PromptStatus.OK)

{

foreach (var id in entSelected.Value.GetObjectIds())

{

Curve c = trans.GetObject(id, OpenMode.ForRead, false) as Curve;

Curves.Add(c);

}

}

2,由曲线生成面域。  

当曲线组成一个连通域时:

编程思路:

1)将每根平面闭合曲线生成面域;

2)将所有面域加入列表;

3)按面域面积大小排序;

4)第一个面域减去其它所有面域,得到一个新的面域即为所求面域。

如下图,面域1面积最大,减去面域2和面域3即得到铝型材的截面面域。

图片

当曲线组成多个连通域时:

编程思路:

1)将每根平面闭合曲线生成面域;

2)将所有面域加入列表;

3)按面域面积大小排序;

4)第一个面域与其它所有面域相减,如果所得结果的面积没有变化,则被减面域与原面域不相交,新建一个面域列表装载这面域如果所得结果的面积小,则被减面域与原面域相交存相减后的新面域。

5)将新建列表中的每个面域执行第4)步操作,得到一个新面域和一个新建面域列表。

6)循环执行第5)步操作直到无新建面域列表为止

7)将每次得到的新面域组成一个集合,即为最终的型材截面。

如下图,面域1面积最大,减去面域2和面域3即得到一个新面域,因为每减一次面积比原来小,所以不会新建面域列表,当减去面域4时,面积没有变化,可知其与被减面域没有相交,故新建一个面域列表,再用面域4去减该列表中的面域,下图面域4中没有子面域,即退出方法,返回两个面域。

图片

核心代码如下:

List<Region> regionList = new List<Region>();//新建面域列表,存储创建的面域

//将可变数组转化为集合类,用于面域的创建

DBObjectCollection curveCollection = new DBObjectCollection();

foreach (Curve curve in curves)//遍历曲线

{

curveCollection.Add(curve);//将曲线添加到集合中

}

try

{

//根据曲线集合,在内存中创建面域对象集合

DBObjectCollection regionObjs = Region.CreateFromCurves(curveCollection);//此方法API自带

//将面域对象集合复制到面域列表

foreach (Region region in regionObjs)

{

regionList.Add(region);

}

//将所得面域按面积大小排序

List<Region> orderRegions = (from r in regionList

orderby r.Area descending

select r).ToList();

return orderRegions;

}

catch //如果面域创建失败,返回空值。

{

regionList.Clear();//清空面域列表

return regionList;//返回空的面域列表

}

for (int i = 0; i < RegionList.Count - 1; i++)

{

RegionList[0].BooleanOperation(BooleanOperationType.BoolSubtract, RegionList[i + 1]);

}

3,由面域计算几何属性。

.NET库中尚未包含相应功能的函数,需要使用P/Invoke技术在.NET程序中调用C++函数,由面域返回几何属性的函数在Acdb**.dll文件(此文件C++编写的里。下面以AutoCAD2020为例,其它版本AutoCAD对应的Acdb**.dll文件如下:默认安装在C:\Program Files\Autodesk\AutoCAD 20**文件夹里。

AutoCAD2010

Acdb18.dll

AutoCAD2011

Acdb18.dll

AutoCAD2012

Acdb18.dll

AutoCAD2013

Acdb19.dll

AutoCAD2014

Acdb19.dll

AutoCAD2015

Acdb20.dll

AutoCAD2016

Acdb20.dll

AutoCAD2017

Acdb21.dll

AutoCAD2018

Acdb22.dll

AutoCAD2019

Acdb23.dll

AutoCAD2020

Acdb23.dll

核心代码如下:

[DllImport('acdb23.dll', CallingConvention = CallingConvention.ThisCall, EntryPoint =

//标识符,不随版本变化'?getAreaProp@AcDbRegion@@UEBA?AW4ErrorStatus@Acad@@AEBVAcGePoint3d@@AEBVAcGeVector3d@@1AEAN2AEAVAcGePoint2d@@QEAN24QEAVAcGeVector2d@@433@Z')] 

private static extern ErrorStatus getAreaProp18(IntPtr region,

ref Point3d origin,       //图形原点

ref Vector3d xAxis,       //X主轴线

ref Vector3d yAxis,       //X主轴线

out double perimeter,     //周长  

out double area,          //面积

out Point2d centroid,     //

double[] momInertia,      //惯性矩

out double prodInertia,   //惯性积

double[] prinMoments,     //惯性矩

Vector2d[] prinAxes,      //主惯性轴 

double[] radiiGyration,   //转半径

out Point2d extentsLow,   //外包框最低点

out Point2d extentsHigh); //外包框最高点

//取面域的

public static Point2d GetCentroid(this Region region)

{

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

CoordinateSystem3d coord = ed.CurrentUserCoordinateSystem.CoordinateSystem3d;

Point3d origin = coord.Origin;

Vector3d xAxis = coord.Xaxis;

Vector3d yAxis = coord.Yaxis;

getAreaProp(region.UnmanagedObject, ref origin, ref xAxis, ref yAxis, out perimeter, out area, out centroid,momInertia, out prodInertia, prinMoments, prinAxes, radiiGyration, out extentsLow, out extentsHigh);      

return centroid;

}

//取面域的惯性矩

public static double[] GetMomInertia(this Region region)

{

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

CoordinateSystem3d coord = ed.CurrentUserCoordinateSystem.CoordinateSystem3d;

Point3d origin = coord.Origin;

Vector3d xAxis = coord.Xaxis;

Vector3d yAxis = coord.Yaxis;

getAreaProp (region.UnmanagedObject, ref origin, ref xAxis, ref yAxis, out perimeter, out area, out centroid,  momInertia, out prodInertia, prinMoments, prinAxes, radiiGyration, out extentsLow, out extentsHigh);

return momInertia;

}

//取面域边界框的下限,其它特性相同

public static Point2d GetExtentsLow(this Region region)

{

Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

CoordinateSystem3d coord =ed.CurrentUserCoordinateSystem.CoordinateSystem3d;

Point3d origin = coord.Origin;

Vector3d xAxis = coord.Xaxis;

Vector3d yAxis = coord.Yaxis;                        

getAreaProp(region.UnmanagedObject, ref origin, ref xAxis, ref yAxis, out perimeter, out area, out centroid, momInertia, out prodInertia, prinMoments, prinAxes, radiiGyration, out extentsLow, out extentsHigh);

}

return extentsLow;

}

4,几何属性求解如下:

1)public double A { get; set; }        //面积

由面域属性直接得出,代码:double A = Region.Area;    

2)public double Ip { get; set; }       //极惯性矩

由公式:Ip = Ix + Iy

3)public double Ix { get; set; }       //X轴惯性矩

可由方法返回图形相对于模型空间X轴的惯性矩,再通过移轴公式移到面域形心处的惯性矩。

由公式:Ix = Ix0 + A * Ycent * Ycent

代码:double Ix = GetMomInertia(Region)[0] - A * Centroid.Y * Centroid.Y;

4)public double Iy { get; set; }       //Y轴惯性矩

Ix,将X轴与Y轴参数对调

5)public double ix { get; set; }       //X轴回转半径

由公式:   得出,代码: double ix = Math.Pow(Ix / A, 0.5)   

6)public double iy { get; set; }       //Y轴回转半径

ix,将X轴与Y轴参数对调

7)public double Wxup { get; set; }     //X轴上部抗弯模量

由公式:   得出,

代码:double hy2 = Math.Abs(GetExtentsHigh(Region).Y - Centroid.Y)

8)public double Wxdown { get; set; }   //X轴下部抗弯模量

WxupY轴上下参数对调

9)public double Wyleft { get; set; }   //Y轴左侧抗弯模量

WxupX轴与Y轴参数对调

10)public double Wyright { get; set; }  //Y轴右侧抗弯模量

WyleftX轴上下参数对调

11)public double Sx { get; set; }       //X轴静矩

将面域沿过形心的X轴切开,得到上下两个面域,分别对这两个面域求面积A1,A2和形心坐标Y11,Y22,由新面域的形心坐标减去原面域的形心坐标Y11,Y22 得到距离 Y1,Y2(按绝对值计)。

由公式:   得出。(注:

代码:double Sx = RgLastX.Area * Math.Abs(Region.GetCentroid().Y - Centroid.Y)

12)public double Sy { get; set; }       //Y轴静矩

SxY轴上下参数对调

5,程序界面效果:

点击右侧的“梁截面”按扭,即隐藏主界面,提示用户选择AutoCAD曲线,获取曲线后,界面恢复显示,列表参数展示如下:

图片

6,总结:

求面域的几何属性这样的功能,市面上有很多软件已经相当完善了,但其代码和编程思路并未公开,网上也很难找到这方面完备的参考资料,有鉴于此,作者在相关书籍的基础上通过编程实践,整理出来一套自已的思路和代码,以供行业同仁参考和切磋。

1.不足之处及有待改进的地方:

A,不能动态调用Acdb**.dll**AutoCAD版本有关),而是要针对每个AutoCAD版本编译不同的程序。虽然作者采用了并行导入的方法,但是代码看起来比较冗繁,不利于维护。

B,对于不符合条件的曲线,比如Z轴坐标不为零、存在小缺口等,如何进行前期预处理,使曲线顺利生成正确的面域。

2.难点:

A,面积矩S,既不能直接得出,也不能由现成参数量推导出来,需要切分原面域,再分别求形心,然后才能根据材料力学公式S = A * y计算。

B,多个连通域面域的识别和分类整理,这里用到的技术是面域相减结果与原面域比较的方法,如果不相交则相减后面积不变,从而进入新建列表,多个列表依次调用同一个方法。

参考文献:

【1】AutoCAD VBA&VB.NET开发基础与实例教程 (C#) 作者:曾洪飞

【2】《建筑结构静力计算实用手册(第四版)》    作者姚谏

【3】《材料力学(第3版)》王晶孙伟王单李栋栋王社民 

【4】C#图解教程(第5版)》作者 [] 丹尼尔·索利斯 / [] 卡尔·施罗坦博尔

新书信息

图书信息:

书名:幕墙设计    实用软件案例解析

作者:章一峰    魏丽丽    谢容成     主编

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多