diff --git a/SourceCode/Code2026/CoreLibrary/AecDbCamera.cpp b/SourceCode/Code2026/CoreLibrary/AecDbCamera.cpp index 6210726..aeb0ab9 100644 --- a/SourceCode/Code2026/CoreLibrary/AecDbCamera.cpp +++ b/SourceCode/Code2026/CoreLibrary/AecDbCamera.cpp @@ -534,6 +534,26 @@ namespace //#endif } + // 弧长/半径 的比值小于此值即视为"退化圆弧"(圆心角极小)。 + const double kMinArcLengthRadiusRatio = 1e-6; + + // 判断 HLR 结果实体是否为"退化圆弧":实体是 AcDbArc,且 弧长/半径 的比值极小。 + // 这类圆弧的圆心角极小,HLR 计算时圆心角会溢出,使结果由"很小一段"变成 + // "反向的大圆弧",需要从结果中删除。 + bool isDegenerateArc(AcDbEntity *pEnt) + { + AcDbArc *pArc(AcDbArc::cast(pEnt)); + if (pArc == NULL) + return false; + + double dRadius(pArc->radius()); + if (COMPARE_DOUBLE::equal_zero(dRadius, 1e-9)) + return true; // 半径≈0,本身即退化 + + double dRatio(pArc->length() / dRadius); + return dRatio < kMinArcLengthRadiusRatio; + } + bool zeroLength(AcDbCurve *pCrv, const double &tol) { double dPEnd(.0), dDist(.0); @@ -1966,6 +1986,36 @@ void AecDbXCamera::hlrCalc(AcDbObjectIdArray &arIds HlrCalc(arIds, arAdditional_all, pVp.get(), control, result1, result2); + // 删除 HLR 计算中"退化"的圆弧(弧长/半径 比值极小)。 + // 这类圆弧圆心角极小,计算时会溢出,由"很小一段"变成"反向的大圆弧"。 + { + IDMapEntities::iterator it(result1.begin()); + for (; it != result1.end(); ++it) + { + for (int i(it->second.length() - 1); i >= 0; --i) + { + if (isDegenerateArc(it->second[i])) + { + delete it->second[i]; + it->second.removeAt(i); + } + } + } + + EntMapEntities::iterator it2(result2.begin()); + for (; it2 != result2.end(); ++it2) + { + for (int i(it2->second.length() - 1); i >= 0; --i) + { + if (isDegenerateArc(it2->second[i])) + { + delete it2->second[i]; + it2->second.removeAt(i); + } + } + } + } + if (result1.empty() && result2.empty()) { // 如果实体的PreprocessForHlr函数内,设置了 HLR_CALC,从而影响实体的 Draw3d 函数的返回