OCC开发_变高箱梁全桥建模

概述

    上一篇文章《OCC开发_箱梁梁体建模》中详细介绍了箱梁梁体建模的过程。但是,对于实际桥梁,截面可能存在高度、腹板厚度、顶底板厚度变化,全桥的结构中心线存在平曲线和竖曲线。针对实际情况,通过一个截面拉伸来实现全桥建模显然不可能。因此,针对变高箱梁,本文新的思路来实现全桥建模。

思路

上一篇文章通过一个截面拉伸生成几何体的方式行不通,我们可以通过不同面来形成棱柱的方式实现。具体步骤如下:

  1. 生成控制数据(控制点位置、转角、梁高、底板厚);
  2. 生成各个截面(含内外轮廓,且偏移旋转到指定位置);
  3. 各个截面各轮廓生成棱柱;
  4. 布尔运算,外轮廓棱柱扣减各内轮廓棱柱;
  5. 保存.Brep文件;
  6. 查看效果。

实际的桥梁中,墩顶存在隔板,梁端存在托梁、槽口,隔板还存在人洞,本文暂不涉及这些构造。

代码实现

本文以某个具体桥梁为例来实现全桥建模,桥梁参数见效果栏。

#include <vector>
#include <tuple>
#include <gp_Pnt.hxx>
#include <gp_Circ.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepOffsetAPI_ThruSections.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <ShapeAnalysis_Edge.hxx>
#include <ShapeAnalysis_WireOrder.hxx>
#include <AIS_Shape.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#pragma comment(lib, "TKernel.lib")
#pragma comment(lib, "TKMath.lib")
#pragma comment(lib, "TKG2d.lib")
#pragma comment(lib, "TKG3d.lib")
#pragma comment(lib, "TKGeomBase.lib")
#pragma comment(lib, "TKGeomAlgo.lib")
#pragma comment(lib, "TKBRep.lib")
#pragma comment(lib, "TKTopAlgo.lib")
#pragma comment(lib, "TKShHealing.lib")#define pi 3.141592653589793  //π值预定义//通过初始数据生成边
std::vector<TopoDS_Edge> GetEdges(std::vector<std::tuple <double, double, double>> tuples)
{std::vector<TopoDS_Edge> anEdges;for (int i = 0; i < tuples.size(); ++i){int i1 = i;int i2 = (i + 1) % tuples.size();BRepBuilderAPI_MakeEdge tempRdge(gp_Pnt(std::get<0>(tuples[i1]), std::get<1>(tuples[i1]), std::get<2>(tuples[i1])),gp_Pnt(std::get<0>(tuples[i2]), std::get<1>(tuples[i2]), std::get<2>(tuples[i2])));anEdges.push_back(tempRdge.Edge());}return anEdges;
}//通过边生成形状
TopTools_ListOfShape GetShape(std::vector<TopoDS_Edge> edges)
{TopTools_ListOfShape aOrderedEdges;for (int e = 0; e < edges.size(); ++e){const TopoDS_Edge& anEdge = edges[e];aOrderedEdges.Append(anEdge);}return aOrderedEdges;
}//通过边生成BRepBuilderAPI_MakeWire
BRepBuilderAPI_MakeWire GetWire(std::vector<TopoDS_Edge> outerEdges)
{TopTools_ListOfShape aOrderedEdges = GetShape(outerEdges);BRepBuilderAPI_MakeWire aWireMaker;aWireMaker.Add(aOrderedEdges);return aWireMaker;
}//生成截面定位点信息,未偏置和旋转
std::vector<std::vector<std::tuple <double, double, double>>> GetBoundaryPoints(double height, double bottomThick)
{double topWidth = 16.00;double bottomWidth = 11.00;double edgeThick = 0.2;double rootThick = 0.80;double charmerWidth = 0.30;double charmerHeight = 0.30;double deckThick = 0.60;double topThick = 0.30;std::vector<std::tuple <double, double, double>> tuples;tuples.push_back(std::make_tuple(-topWidth / 2, 0, 0.0));tuples.push_back(std::make_tuple(topWidth / 2, 0, 0.0));tuples.push_back(std::make_tuple(topWidth / 2, -edgeThick, 0.0));tuples.push_back(std::make_tuple(bottomWidth / 2, -rootThick, 0.0));tuples.push_back(std::make_tuple(bottomWidth / 2, -height, 0.00));tuples.push_back(std::make_tuple(-bottomWidth / 2, -height, 0.0));tuples.push_back(std::make_tuple(-bottomWidth / 2, -rootThick, 0.0));tuples.push_back(std::make_tuple(-topWidth / 2, -edgeThick, 0.0));std::vector<std::vector<std::tuple <double, double, double>>> outerTuples;outerTuples.push_back(tuples);for (int i = 0; i < 2; ++i){std::vector<std::tuple <double, double, double>> outerTuple;double gridWidth = bottomWidth / 2 - deckThick * 1.5;double midX = (i == 0 ? -1 : 1) * (bottomWidth / 4 - deckThick / 4);outerTuple.push_back(std::make_tuple(midX - gridWidth / 2 + charmerWidth, -topThick, 0.0));outerTuple.push_back(std::make_tuple(midX - gridWidth / 2, -topThick - charmerHeight, 0.0));outerTuple.push_back(std::make_tuple(midX - gridWidth / 2, -height + bottomThick + charmerHeight, 0.0));outerTuple.push_back(std::make_tuple(midX - gridWidth / 2 + charmerWidth, -height + bottomThick, 0.0));outerTuple.push_back(std::make_tuple(midX + gridWidth / 2 - charmerWidth, -height + bottomThick, 0.0));outerTuple.push_back(std::make_tuple(midX + gridWidth / 2, -height + bottomThick + charmerHeight, 0.0));outerTuple.push_back(std::make_tuple(midX + gridWidth / 2, -topThick - charmerHeight, 0.0));outerTuple.push_back(std::make_tuple(midX + gridWidth / 2 - charmerWidth, -topThick, 0.0));outerTuples.push_back(outerTuple);}return outerTuples;
}//点偏移和旋转
std::tuple <double, double, double> Transform(std::tuple <double, double, double> inputPoint, std::tuple <double, double, double> centerPoint, double angle)
{double x1 = std::get<0>(centerPoint)+ std::get<0>(inputPoint) * cos(angle);double y1 = std::get<1>(centerPoint)+ std::get<1>(inputPoint);double z1 = std::get<2>(centerPoint) + std::get<0>(inputPoint) * sin(angle);return std::make_tuple(x1, y1, z1);
}//实际位置截面(经过偏移和旋转)
std::vector<std::vector<std::tuple <double, double, double>>> GetBoundaryPoints(std::tuple <double, double, double> centerPoint, double angle, double height, double bottomThick)
{std::vector<std::vector<std::tuple <double, double, double>>> sectionBoundaries = GetBoundaryPoints(height, bottomThick);std::vector<std::vector<std::tuple <double, double, double>>> transformedBoundaries;for (int i = 0; i < sectionBoundaries.size(); ++i){std::vector<std::tuple <double, double, double>> transformedBoundary;for (int j = 0; j < sectionBoundaries[i].size(); ++j){//transformedBoundary.push_back(sectionBoundaries[i][j]);transformedBoundary.push_back(Transform(sectionBoundaries[i][j], centerPoint, angle));}transformedBoundaries.push_back(transformedBoundary);}return transformedBoundaries;
}//输出梁高列表(也可以用于板厚)
std::vector<double> GetHeightList(std::vector<double> canSegmentLengthList, double colTopBeamHeight, double midBeamHeight)
{double detaHeight = colTopBeamHeight - midBeamHeight;double totalLength = 0;for (int i = 0; i < canSegmentLengthList.size(); ++i){totalLength = totalLength + canSegmentLengthList[i];}double factorA = detaHeight / (totalLength * totalLength);std::vector<double> heightList = { midBeamHeight };double detaLength = 0;for (int i = 0; i < canSegmentLengthList.size(); ++i){detaLength = detaLength + canSegmentLengthList[i];double height = factorA * detaLength * detaLength + midBeamHeight;heightList.insert(heightList.begin(), height);}return heightList;
}//输出里程、梁高、板厚列表
std::vector<std::tuple <double, double, double>> GetStaTupleList(std::vector<double> canSegmentLengthList, double midSta, double equalHeightLength, double colTopBeamHeight, double midBeamHeight, double colTopBottomThick, double midBottomThick)
{std::vector<double> heightList = GetHeightList(canSegmentLengthList, colTopBeamHeight, midBeamHeight);//梁高列表std::vector<double> bottomThickList = GetHeightList(canSegmentLengthList, colTopBottomThick, midBottomThick);//梁高列表std::vector<std::tuple <double, double, double>> staTupleList;staTupleList.push_back(std::make_tuple(midSta - equalHeightLength / 2, colTopBeamHeight, colTopBottomThick));staTupleList.push_back(std::make_tuple(midSta + equalHeightLength / 2, colTopBeamHeight, colTopBottomThick));double staStart = midSta - equalHeightLength / 2;double staEnd = midSta + equalHeightLength / 2;for (int i = 0; i < canSegmentLengthList.size(); ++i){staStart = staStart - canSegmentLengthList[i];staEnd = staEnd + canSegmentLengthList[i];staTupleList.push_back(std::make_tuple(staEnd, heightList[i + 1], bottomThickList[i + 1]));staTupleList.insert(staTupleList.begin(), std::make_tuple(staStart, heightList[i + 1], bottomThickList[i + 1]));}return staTupleList;
}//获取位置、角度、梁高、顶板厚列表
//跨径组合65+110+65
//支点梁高6.5,板厚0.8,跨中梁高2.6,板厚0.32
//支点等高段3,变高段52.5,合拢段3,边跨9
//节段划分12+3*3.5+6*4+3*4.5
//起点里程为0,高程为0,终点高程2.4m
//平面在半径1000的圆曲线上
std::vector<std::tuple <std::tuple <double, double, double>, double, double, double>> GetControlMessageList()
{double edgeSpanLength = 65;//边跨长double midSpanLength = 100;//中跨长double colTopBeamHeight = 6.5;//墩顶梁高double midBeamHeight = 2.6;//跨中梁高double colTopBottomThick = 0.8;//墩顶板厚double midBottomThick = 0.32;//跨中板厚double equalHeightLength = 3;//墩顶等高段长double variableHeightLength = 52.5;//变高段长double closedSegmentLength = 2;//合拢段长double edgeSegmentLength = 9;//边跨现浇段长std::vector<double> canSegmentLengthList = { 4.5,3.5,3.5,3.5,4,4,4,4,4,4,4.5,4.5,4.5 };//T构节段长列表std::vector<std::tuple <double, double, double>> staList;//里程,梁高,底板厚//计算两个T构的里程,梁高,底板厚double midSta = edgeSpanLength; //墩顶中心里程std::vector<std::tuple <double, double, double>> list1 = GetStaTupleList(canSegmentLengthList, midSta, equalHeightLength, colTopBeamHeight, midBeamHeight, colTopBottomThick, midBottomThick);staList.insert(staList.end(), list1.begin(), list1.end());midSta = edgeSpanLength + midSpanLength; //墩顶中心里程std::vector<std::tuple <double, double, double>> list2 = GetStaTupleList(canSegmentLengthList, midSta, equalHeightLength, colTopBeamHeight, midBeamHeight, colTopBottomThick, midBottomThick);staList.insert(staList.end(), list2.begin(), list2.end());//计算两侧边跨段的里程,梁高,底板厚double endSta0 = std::get<0>(staList[staList.size() - 1]);double endSta1 = endSta0 + closedSegmentLength;double endSta2 = endSta0 + (closedSegmentLength+ edgeSegmentLength);double startSta0 = std::get<0>(staList[0]);double startSta1 = startSta0 - closedSegmentLength;double startSta2 = startSta0 - (closedSegmentLength + edgeSegmentLength);staList.insert(staList.end(), std::make_tuple(endSta1, midBeamHeight, midBottomThick));staList.insert(staList.end(), std::make_tuple(endSta2, midBeamHeight, midBottomThick));staList.insert(staList.begin(), std::make_tuple(startSta1, midBeamHeight, midBottomThick));staList.insert(staList.begin(), std::make_tuple(startSta2, midBeamHeight, midBottomThick));//计算坐标和角度std::vector<std::tuple <std::tuple <double, double, double>, double, double, double>> pointTuples;for (int i = 0; i < staList.size(); ++i){std::tuple <double, double, double> tuple = staList[i];double detaSta = std::get<0>(tuple);double detaHeight = detaSta * 0.01;//竖向,Ydouble detaSita = detaSta / 1000;double sita = pi / 2 - detaSita;double detaX = 1000 * cos(sita);//纵向double detaY = 1000 - 1000 * sin(sita);//横向double beamHeight = std::get<1>(tuple);double bottomThick = std::get<2>(tuple);std::tuple <double, double, double> point = std::make_tuple(detaY , detaHeight, detaX);pointTuples.push_back(std::make_tuple(point, detaSita, beamHeight, bottomThick));}return pointTuples;
}//生成全桥
void GenerateBridge()
{//生成控制信息std::vector<std::tuple <std::tuple <double, double, double>, double, double, double>> pointTuples = GetControlMessageList();//生成各个截面std::vector<std::vector<std::vector<std::tuple <double, double, double>>>> sections;//所有截面实际定位信息(偏移旋转后)for (int i = 0; i < pointTuples.size(); ++i){std::tuple <std::tuple <double, double, double>, double, double, double> tuple = pointTuples[i];std::tuple <double, double, double> points = std::get<0>(tuple);sections.push_back(GetBoundaryPoints(std::get<0>(tuple), std::get<1>(tuple), std::get<2>(tuple), std::get<3>(tuple)));}//生成截面各轮廓体std::vector<BRepOffsetAPI_ThruSections> generators;for (int i = 0; i < sections[0].size(); ++i){BRepOffsetAPI_ThruSections generator(Standard_True, Standard_False);generators.push_back(generator);}for (int i = 0; i < sections.size(); ++i){std::vector<std::vector<std::tuple <double, double, double>>> section = sections[i];for (int j = 0; j < section.size(); ++j){std::vector<TopoDS_Edge> innerEdges0 = GetEdges(section[j]);TopoDS_Wire wire = GetWire(innerEdges0);generators[j].AddWire(wire);}}std::vector<TopoDS_Shape> shapes;for (int i = 0; i < sections[0].size(); ++i){generators[i].Build();shapes.push_back(generators[i].Shape());}//外轮廓体扣减内轮廓体TopoDS_Shape S1 = BRepAlgoAPI_Cut(shapes[0], shapes[1]);for (int i = 2; i < sections[0].size(); ++i){S1 = BRepAlgoAPI_Cut(S1, shapes[i]);}//输出BRepTools::Write(S1, "d:/wire.brep");//保存文件
}//主函数
int main(int argc, char* argv[])
{GenerateBridge();return 0;
}

效果

桥梁在半径1000m的圆弧平曲线上,竖曲线为1%的纵坡。全桥跨径组合为65+110+65m,墩顶梁高6.5m,跨中梁高2.8m,顶板厚0.3m,底板厚0.32~0.8m,抛物线次数为2.0次,墩顶水平段3m,变高段52.5m,跨中合拢段和边跨合拢段均为2.0m,边跨现浇段9m,T构节段划分为12+33.5+64+3*4.5m。桥梁立面图纸(已经对称处理)如下:
在这里插入图片描述

全桥三维模型形状如下图(隔板未建模):
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/419072.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法复杂度 —— 数据结构前言、算法效率、时间复杂度、空间复杂度、常见复杂度对比、复杂度算法题(旋转数组)

目录 一、数据结构前言 1、数据结构 2、算法 3、学习方法 二、 算法效率 引入概念&#xff1a;算法复杂度 三、时间复杂度 1、大O的渐进表示法 2、时间复杂度计算示例 四、空间复杂度 计算示例&#xff1a;空间复杂度 五、常见复杂度对比 六、复杂度算法题&…

《JavaEE进阶》----12.<SpringIOCDI【扫描路径+DI详解+经典面试题+总结】>

本篇博客主要讲解 扫描路径 DI详解&#xff1a;三种注入方式及优缺点 经典面试题 总结 五、环境扫描路径 虽然我们没有告诉Spring扫描路径是什么&#xff0c;但是有一些注解已经告诉Spring扫描路径是什么了 如启动类注解SpringBootApplication。 里面有一个注解是componentS…

【学习笔记】3GPP WG SA5 Rel-19标准化工作管理和编排

3GPP WG SA5 Rel-19标准化工作涵盖了管理和编排要求、管理阶段2和管理流程&#xff0c;以及阶段3 OpenAPI和YANG解决方案集&#xff0c;以在多供应商环境中为5G网络提供完整的管理互操作性能力。 SA5以WG SA1通过紧密跟踪其他3GPP工作组的进展&#xff0c;这些工作组产生新的网…

如何使div居中?CSS居中终极指南

前言 长期以来&#xff0c;如何在父元素中居中对齐一个元素&#xff0c;一直是一个让人头疼的问题&#xff0c;随着 CSS 的发展&#xff0c;越来越多的工具可以用来解决这个难题&#xff0c;五花八门的招式一大堆&#xff0c;这篇博客&#xff0c;旨在帮助你理解不同的居中方法…

【机器人工具箱Robotics Toolbox开发笔记(二)】Matlab中机器人工具箱的下载与安装

Matlab机器人工具箱(Robotics Toolbox)可从Peter Corke教授提供的网站上免费下载。网址为:http://www.petercorke.com/Robotics_Toolbox.html。 图1 网站所提供的机器人工具箱版本 在Downloading the Toolbox栏目中单击here按钮进入下载页面,然后在该页面中填写国家、组织…

Qt多语种开发教程

Qt作为跨平台的开发工具&#xff0c;早已应用到各行各业的软件开发中。 今天讲讲&#xff0c;Qt开发的正序怎么做多语言开发。就是说&#xff0c;你设置中文&#xff0c;就中文显示&#xff1b;设置英语就英文显示&#xff0c;设置繁体就繁体显示&#xff0c;设置发育就显示法语…

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务&#xff0c;使用API接口查询京东物流的便捷步骤&#xff0c;首先选择专业的数据平台的快递API接口&#xff1a;物流快递查询API接口-单号查询…

【C语言】详解结构体(下)(位段)

文章目录 前言1. 位段的含义2. 位段的声明3. 位段的内存分配&#xff08;重点&#xff09;3.1 存储方向的问题3.2 剩余空间利用的问题 4. 位段的跨平台问题5. 位段的应用6. 总结 前言 相信大部分的读者在学校或者在自学时结构体的知识时&#xff0c;可能很少会听到甚至就根本没…

win10不用anaconda安装tensorflow-cpu并导入pycharm

记录一下防止忘了 一、前提&#xff1a;已经安装了python3.6.4,想用tensorflow的包 二、在pycharm中File-Settings-Project Interpreter点“”号导入很慢&#xff0c;所以直接在cmd中使用 pip install -i https://mirrors.aliyun.com/pypi/simple tensorflow-cpu下载好&#x…

2024AI绘画工具排行榜:探索最受欢迎的AI绘图软件特点与选择指南

AI绘画工具各有优势&#xff0c;从开放性到对特定语言和文化的支持&#xff0c;以及对图像细节和艺术性的不同关注点&#xff0c;根据具体需求选择合适的工具 MidJourney 图片品质卓越&#xff0c;充满独特创意&#xff0c;初期能够免费获取数十账高质量图片&#xff0c;整个生…

(一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别

🍂1、不说废话,现象展示 🍃图片识别 🍃视频识别 自己训练样本 十分简易快速 opencv级联ha

前端:Vue3学习-2

前端:Vue3学习-2 1. vue3 新特性-defineOptions2. vue3 新特性-defineModel3. vue3 Pinia-状态管理工具4. Pinia 持久化插件 -> pinia-plugin-persistedstate 1. vue3 新特性-defineOptions 如果要定义组件的name或其他自定义的属性&#xff0c;还是得回归原始得方法----再…

页面要突破手机安全区域来全屏显示(沉浸式模式显示),其他页面不需要,如何设置安全区域文字颜色

#效果图 ##思路遇到的问题 在aboutToAppear中使用window模块的 getLastWindow 和 setWindowLayoutFullScreen两个方法来处理全屏显示 设置沉浸式模式的特点&#xff1a; 在任何一个页面中设置过一次之后&#xff0c;其他页面也会跟着全屏显示 这么处理会出现问题&#xff1a…

实验七 期中练习

实验目的及要求 目的&#xff1a;掌握File类的作用和使用方法&#xff0c;掌握运用文件字节输入输出流对文件进行操作&#xff0c;综合运用学过的知识。 要求&#xff1a; &#xff08;1&#xff09;编写FileDemo类测试File类的常用方法 &#xff08;2&#xff09;用FileOu…

2024国赛数学建模-模拟火算法(MATLAB 实现)

模拟退火算法 1.1 算法原理 模拟退火算法的基本思想是从一给定解开始 ,从邻域 中随机产生另一个解 ,接受 Metropolis准则允许目标函数在 有限范围内变坏 ,它由一控制参数 t决定 ,其作用类似于物 理过程中的温度 T,对于控制参数的每一取值 ,算法持续进 行“产生 —判断 —接受…

ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合 1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实…

oracle数据块内部结构详解

文章目录 Oracle数据块详解概述Oracle块具有以下特点&#xff1a;① 最小的I/O单元&#xff1b;② 包含一个或多个OS块&#xff1b;③ 大小由参数DB_BLOCK_SIZE决定&#xff1b;④ 数据库创建时设置&#xff0c;数据库创建后不能更改 Oracle数据块详解 概述 操作系统块是…

音频-语言大模型原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

Flutter中自定义气泡框效果的实现

在用户界面的设计中&#xff0c;气泡框&#xff08;Bubble&#xff09;是一种非常有效的视觉工具&#xff0c;它可以用来突出显示信息或提示用户。气泡框广泛应用于聊天应用、通知提示等场景。在 Flutter 中&#xff0c;虽然有很多现成的气泡框组件&#xff0c;但如果你想要更多…

c# checkbox的text文字放到右边

checkbox的text文字放到右边 实现方法如下图 特此记录 anlog 2024年9月2日