diff --git a/Cad/FeatureDrivenDrawer.cs b/Cad/FeatureDrivenDrawer.cs index 1d46ab7..6c6de43 100644 --- a/Cad/FeatureDrivenDrawer.cs +++ b/Cad/FeatureDrivenDrawer.cs @@ -2992,8 +2992,8 @@ namespace CadParamPluging.Cad : 0; // 1. 绘制完整锻件外轮廓(方体有圆头 - 白色,大圆弧) - // 修正:取消外框处的圆角(改为直角),不再缩进弦线 - DrawBlockRoundHeadOutline(ctx, ox, oy, visualTotalW, H, arcHeight, 0); + // 修正:圆弧弦线需向内缩进 innerFilletR,以与锻件圆角起点对齐 + DrawBlockRoundHeadOutline(ctx, ox, oy, visualTotalW, H, arcHeight, innerFilletR); // 2. 绘制分段式内框(左、中、右三段)以支持中间剖面区域的独立圆角 // 中间区域(剖面)作为主体,如果设置了圆角,四个角都应为圆角 @@ -3010,14 +3010,14 @@ namespace CadParamPluging.Cad DrawBoxSectionContourWithFillet(ctx, xSectionLeft, xSectionRight, oy, H, innerFilletR); // 绘制左侧框线(连接左端圆弧和中间剖面框) - // 左端: xInnerLeft (需处理左上下角的圆角 - 修正为不使用圆角,改为直角 0) + // 左端: xInnerLeft (需处理左上下角的圆角 - 修正为使用内框圆角 innerFilletR,与方体参数一致) // 右端: xSectionLeft (连接到中间框的直边) - DrawBoxSideFrame(ctx, xInnerLeft, xSectionLeft, oy, H, 0, isLeft: true); + DrawBoxSideFrame(ctx, xInnerLeft, xSectionLeft, oy, H, innerFilletR, isLeft: true); // 绘制右侧框线 // 左端: xSectionRight (连接到中间框的直边) - // 右端: xInnerRight (需处理右上下角的圆角 - 修正为不使用圆角,改为直角 0) - DrawBoxSideFrame(ctx, xSectionRight, xInnerRight, oy, H, 0, isLeft: false); + // 右端: xInnerRight (需处理右上下角的圆角 - 修正为使用内框圆角 innerFilletR,与方体参数一致) + DrawBoxSideFrame(ctx, xSectionRight, xInnerRight, oy, H, innerFilletR, isLeft: false); // 3. 剖面填充 - 只在中间区域 // 如果有圆角,填充范围也应考虑圆角(不过Hatch边界通常可以自动处理) @@ -3089,8 +3089,8 @@ namespace CadParamPluging.Cad // 标注从圆弧最外侧开始(避免与圆弧轮廓线重叠) double xOuterRight = ox + visualTotalW; - // 修正:标注界线起点应从圆弧顶端开始,往内缩进一个圆弧高度 arcHeight (不再包含 innerFilletR),定位在弦线上 - double xDimOrigin = xOuterRight - arcHeight; + // 修正:标注界线起点应从圆弧顶端开始,往内缩进一个圆弧高度 arcHeight + innerFilletR,定位在弦线上 + double xDimOrigin = xOuterRight - (arcHeight + innerFilletR); AddLinearDim( ctx, @@ -3221,53 +3221,56 @@ namespace CadParamPluging.Cad /// /// 绘制方体有圆头的完整外轮廓 - /// 结构:左侧大圆弧 (高=H/5) + 顶直线 + 右侧大圆弧 + 底直线 - /// 依据用户需求:圆弧高度(黄色)是总高度(粉色)的1/5 - /// offset: 弦线向内偏移量(通常用于与内框圆角对齐) + /// 结构:4顶点多段线 (底边直 -> 左侧整体大圆弧 -> 顶边直 -> 右侧整体大圆弧) + /// 修复: + /// 1. 起点回归到水平线端点 (xLayoutLeft + r),解决"起点往下"问题 + /// 2. 凸度动态计算,使得圆弧顶点顶到最外侧 (ox),解决"穿模"问题 /// - private static void DrawBlockRoundHeadOutline(DrawingContext ctx, double ox, double oy, double totalWidth, double height, double arcHeight, double chordOffset = 0) + private static void DrawBlockRoundHeadOutline(DrawingContext ctx, double ox, double oy, double totalWidth, double height, double arcHeight, double innerFilletR) { try { - // 计算 Bulge - // Bulge = Sagitta / HalfChord - // Sagitta = arcHeight (H/5) - // HalfChord = height / 2 - // Bulge = (H/5) / (H/2) = 2/5 = 0.4 - // 修正:0.4 (CCW) 导致圆弧向内凹(可能与Polyline默认法向或绘制方向有关),改为 -0.4 以向外凸 - double bulge = -0.4; + // 1. 基础参数 + double H = height; + double r = innerFilletR; + + // 弦线X坐标 (内框水平直边结束的位置) + // 原有的布局边界 (用于内孔定位) 是 ox + arcHeight + // 现在的起点要再往里缩 r + double xCurrentLeft = ox + arcHeight + r; + double xCurrentRight = ox + totalWidth - arcHeight - r; - // 弦线位置(修正:增加 offset 以与内框圆角起点对齐) - double xChordLeft = ox + arcHeight + chordOffset; - double xChordRight = ox + totalWidth - arcHeight - chordOffset; + // 2. 凸度计算 + // 我们希望圆弧从 xCurrentLeft 开始,顶点到达 ox + // 拱高 Sagitta = xCurrentLeft - ox = (ox + arcHeight + r) - ox = arcHeight + r + double sagitta = arcHeight + r; + double halfChord = H / 2.0; + + // 向外凸 (For CW path: Left side Up -> Negative, Right side Down -> Negative) + double bulge = 0; + if (halfChord > 1e-3) + { + bulge = -(sagitta / halfChord); + } var poly = new Polyline(); - + // 顺时针绘制 (CW) - // 1. 左下角 (Start of Left Arc) - // 注意:为了让左侧圆弧向外(向左),在CW路径中(向上走),Bulge应为正(Left side of vector) - // wait, CW path on left side goes UP. - // Vector results: Up. - // Bulge > 0 means CCW from vector. CCW from Up is Left. - // So Bulge = 0.4 creates arc to Left. Correct. - poly.AddVertexAt(0, new Point2d(xChordLeft, oy), bulge, 0, 0); + + // Vertex 0: 底边右侧起点 + poly.AddVertexAt(0, new Point2d(xCurrentRight, oy), 0, 0, 0); - // 2. 左上角 (End of Left Arc, Start of Top Line) - poly.AddVertexAt(1, new Point2d(xChordLeft, oy + height), 0, 0, 0); + // Vertex 1: 底边左侧终点 (左侧大圆弧起点) + // 设置凸度,下一段(到Vertex 2)是圆弧 + poly.AddVertexAt(1, new Point2d(xCurrentLeft, oy), bulge, 0, 0); - // 3. 右上角 (End of Top Line, Start of Right Arc) - // CW path goes Right? No, Top Line goes Right. - // Right side path goes Down. - // Vector: Down. - // We want Arc to Right. - // CCW from Down is Right. - // So Bulge = 0.4. - poly.AddVertexAt(2, new Point2d(xChordRight, oy + height), bulge, 0, 0); + // Vertex 2: 顶边左侧起点 (左侧大圆弧终点) + poly.AddVertexAt(2, new Point2d(xCurrentLeft, oy + H), 0, 0, 0); - // 4. 右下角 (End of Right Arc, Start of Bottom Line) - poly.AddVertexAt(3, new Point2d(xChordRight, oy), 0, 0, 0); + // Vertex 3: 顶边右侧终点 (右侧大圆弧起点) + poly.AddVertexAt(3, new Point2d(xCurrentRight, oy + H), bulge, 0, 0); - // Close back to 0 + // Close back to Vertex 0 (Right Side Arc ends at Vertex 0) poly.Closed = true; ctx.Style?.Apply(poly, DrawingStyleManager.Role.OutlineBold);