This commit is contained in:
张壹 2025-07-02 09:37:49 +08:00
parent f2d36a1f85
commit c84c2f0fbb
7 changed files with 67 additions and 18 deletions

View File

@ -92,10 +92,10 @@ Controls refinement along lines or around polygons. Each shape is defined by a s
4. Topography Control Format 4. Topography Control Format
Controls refinement based on elevation data. The refinement is based on elevation variation within triangles: Controls refinement based on elevation data. The refinement is based on elevation variation within triangles:
# First line: <maximum-STD> <maximal-depth> <minimal-resolution> <physical-group> # First line: STD|MAX <maximal-depth> <minimal-resolution> <physical-group> [<maximum-STD>]
# Following lines: <longitude> <latitude> <elevation(meters)> # Following lines: <longitude> <latitude> <elevation(meters)>
# maximum-STD: Maximum allowed standard deviation of elevation within a triangle # maximum-STD: Maximum allowed standard deviation of elevation within a triangle
200.0 10 -1 5 STD 10 -1 5 200.0
-179.95 89.95 -4203.20 -179.95 89.95 -4203.20
-179.85 89.95 -4203.07 -179.85 89.95 -4203.07
-179.75 89.95 -4203.47 -179.75 89.95 -4203.47
@ -168,7 +168,8 @@ int main(int argc, char* argv[]){
case '?': //处理未定义或错误参数 case '?': //处理未定义或错误参数
if (optopt == 'd' || optopt == 'r' || optopt == 'o' || optopt == 'm' || optopt == 'n' if (optopt == 'd' || optopt == 'r' || optopt == 'o' || optopt == 'm' || optopt == 'n'
|| optopt == 'v' || optopt == 't' || optopt == 'p' || optopt == 'l' || optopt == 'v' || optopt == 't' || optopt == 'p' || optopt == 'l'
|| optopt == 'g' || optopt == 'c' || optopt == 's' || optopt == 'k'){ || optopt == 'g' || optopt == 'c' || optopt == 's' || optopt == 'k'
|| optopt == 'z'){
fprintf (stderr, "Option -%c requires an argument.\n", optopt); fprintf (stderr, "Option -%c requires an argument.\n", optopt);
return 0; return 0;
} }

View File

@ -156,7 +156,7 @@ int LocalIndex(int id, Triangle t)
return -1; return -1;
} }
double data_std(const vector<double> &data) double TopoSTD(const vector<double> &data)
{ {
if (data.size() == 0) return 0.0; if (data.size() == 0) return 0.0;
@ -171,3 +171,14 @@ double data_std(const vector<double> &data)
return sqrt(sq_sum / data.size()); return sqrt(sq_sum / data.size());
} }
double TopoMax(const vector<double> &data)
{
double max = data[0];
for (size_t i = 0; i < data.size(); i++)
{
if (data[i] > max) max = data[i];
}
return max;
}

View File

@ -59,9 +59,16 @@ struct ControlPoint{
}; };
typedef vector<ControlPoint> ControlPointArray; typedef vector<ControlPoint> ControlPointArray;
enum topo_cnst_e
{
STD,
MAX,
};
struct ControlTopo{ struct ControlTopo{
int id = -1, max_depth = -1, physic_group = 0; int id = -1, max_depth = -1, physic_group = 0;
double minimal_resolution = DBL_MAX; double minimal_resolution = DBL_MAX;
topo_cnst_e cnst_type;
VertexArray vert; // verts for topo VertexArray vert; // verts for topo
vector<double> topo; vector<double> topo;
}; };
@ -96,5 +103,6 @@ Vertex RotateVertex(Vertex,Vertex,Vertex);
Cpoint LineCrossPlane(Cpoint,Cpoint,Cpoint); Cpoint LineCrossPlane(Cpoint,Cpoint,Cpoint);
string GetStringIndex(Vertex); string GetStringIndex(Vertex);
int LocalIndex(int,Triangle); int LocalIndex(int,Triangle);
double data_std(const vector<double> &data); double TopoSTD(const vector<double> &data);
double TopoMax(const vector<double> &data);
#endif #endif

View File

@ -34,8 +34,8 @@ public:
int InTriangleLine(QuadTreeNode*);//判断插入线是否穿过节点三角形 使用的是球面下的方法 直接矢量计算 注意因为球面上的特殊关系 两个点之间的夹角不能大于等于180度 因为球面上总是沿着最短路径走 而且通常我们指的也是最短路径 int InTriangleLine(QuadTreeNode*);//判断插入线是否穿过节点三角形 使用的是球面下的方法 直接矢量计算 注意因为球面上的特殊关系 两个点之间的夹角不能大于等于180度 因为球面上总是沿着最短路径走 而且通常我们指的也是最短路径
int InTrianglePolygon(QuadTreeNode*);//判断多边形与三角形的关系 int InTrianglePolygon(QuadTreeNode*);//判断多边形与三角形的关系
int InTriangleCircle(QuadTreeNode*);//判断圆与三角形的关系 int InTriangleCircle(QuadTreeNode*);//判断圆与三角形的关系
int InTriangleTopo(QuadTreeNode*, const ControlTopo& in_topo, double diff_threshold);//判断地形与三角形的关系 int InTriangleTopo(QuadTreeNode*, const ControlTopo& in_topo, double diff_threshold); //判断地形与三角形的关系
int InTriangleTopoSet(QuadTreeNode*, const ControlTopo& in_topo, ControlTopo& out_topo); int InTriangleTopoSet(QuadTreeNode*, const ControlTopo& in_topo, ControlTopo& out_topo); // 整理节点三角形内的地形点数组
int OutPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界 int OutPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界
int InPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界 挖洞 int InPolyOutline(QuadTreeNode*);//判断多边形与三角形的关系 用于切割模型边界 挖洞
int OutputMshFile(char*,double,double); int OutputMshFile(char*,double,double);
@ -79,6 +79,6 @@ private:
ControlLineArray array_outline_polygon_; ControlLineArray array_outline_polygon_;
ControlLineArray array_hole_polygon_; ControlLineArray array_hole_polygon_;
// threshold for topography constraint // threshold for topography constraint
double topo_max_diff_; double topo_thres_;
}; };
#endif #endif

View File

@ -24,7 +24,7 @@ void SttGenerator::CreateBranch(int upper_id,int order_id,int depth,int t_ids0,i
|| InTrianglePolygon(current_node) || InTrianglePolygon(current_node)
|| InTriangleLine(current_node) || InTriangleLine(current_node)
|| InTrianglePoint(current_node) || InTrianglePoint(current_node)
|| InTriangleTopo(current_node, out_topo, topo_max_diff_)) || InTriangleTopo(current_node, out_topo, topo_thres_))
&& depth < max_depth_) //最大深度限制 所有节点不能超过的深度 && depth < max_depth_) //最大深度限制 所有节点不能超过的深度
{ {
ivd_ = map_id_vertex_.find(t_ids0);//利用map_ID映射找到四叉树节点的前三个点这三个节点是上一层四叉树产生的必然存在 ivd_ = map_id_vertex_.find(t_ids0);//利用map_ID映射找到四叉树节点的前三个点这三个节点是上一层四叉树产生的必然存在

View File

@ -4,7 +4,7 @@ int SttGenerator::GetControlTopography(char* filename)
{ {
double one_topo; double one_topo;
stringstream temp_ss; stringstream temp_ss;
string temp_str; string temp_str, cnst_str;
Vertex temp_vert; Vertex temp_vert;
ifstream infile; ifstream infile;
@ -16,7 +16,20 @@ int SttGenerator::GetControlTopography(char* filename)
if (*(temp_str.begin()) == '#' || temp_str == "") continue; if (*(temp_str.begin()) == '#' || temp_str == "") continue;
else{ else{
temp_ss = Str2Ss(temp_str); temp_ss = Str2Ss(temp_str);
temp_ss >> topo_max_diff_ >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group;
temp_ss >> cnst_str;
if (cnst_str == "STD")
{
control_topo_.cnst_type = STD;
temp_ss >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group >> topo_thres_;
}
else if (cnst_str == "MAX")
{
control_topo_.cnst_type = MAX;
temp_ss >> control_topo_.max_depth >> control_topo_.minimal_resolution >> control_topo_.physic_group;
}
else throw std::runtime_error("[stt::get_control_topography] Invalid topography constrain type.");
if (control_topo_.max_depth <= 0) control_topo_.max_depth = 1e+3; //这里直接给一个很大的深度值 节点深度一定小于这个值 if (control_topo_.max_depth <= 0) control_topo_.max_depth = 1e+3; //这里直接给一个很大的深度值 节点深度一定小于这个值
if (control_topo_.minimal_resolution <= 0) control_topo_.minimal_resolution = -1.0; //这里直接给成-1 if (control_topo_.minimal_resolution <= 0) control_topo_.minimal_resolution = -1.0; //这里直接给成-1
break; break;

View File

@ -24,14 +24,30 @@ int SttGenerator::InTriangleTopo(QuadTreeNode* node, const ControlTopo& in_topo,
} }
node_resolution = node_resolution*60/Pi; node_resolution = node_resolution*60/Pi;
if (in_topo.max_depth >= node_depth && if (control_topo_.cnst_type == STD)
node_resolution >= in_topo.minimal_resolution &&
data_std(in_topo.topo) >= diff_threshold)
{ {
// 将控制点的组别赋值给当前节点 if (in_topo.max_depth >= node_depth &&
node->tri.physic_group = in_topo.physic_group; node_resolution >= in_topo.minimal_resolution &&
return 1; TopoSTD(in_topo.topo) >= diff_threshold)
{
// 将控制点的组别赋值给当前节点
node->tri.physic_group = in_topo.physic_group;
return 1;
}
else return 0;
} }
else return 0; else if (control_topo_.cnst_type == MAX)
{
if (in_topo.max_depth >= node_depth &&
node_resolution >= in_topo.minimal_resolution &&
TopoMax(in_topo.topo) >= node_depth)
{
// 将控制点的组别赋值给当前节点
node->tri.physic_group = in_topo.physic_group;
return 1;
}
else return 0;
}
else throw std::runtime_error("[stt::in_triangle_topo] Invalid topography constrain type.");
} }
} }