CommonShapeBase

张开发
2026/4/10 5:23:54 15 分钟阅读

分享文章

CommonShapeBase
CommonShapeBase 详解 - 通用形状辅助类这是形状系统中的通用辅助基类为所有形状提供了常用的绘图辅助方法如绘制十字标记、绘制圆点等避免每个形状都重复实现这些功能。 文件头部和命名空间namespaceH.LabelImg.ShapeBox.Shapes.Base;// 命名空间存放形状的基类️ CommonShapeBase 抽象类// 抽象基类为形状提供通用的绘图辅助方法// 继承自 ShapeBase形状基类publicabstractclassCommonShapeBase:ShapeBase{// 绘制十字标记// 参数说明// view - 视图对象提供缩放等信息// drawingContext - WPF绘图上下文// point - 十字标记的中心点// pen - 画笔定义颜色、粗细等// angle - 旋转角度默认0度publicvoidDrawCross(IViewview,DrawingContextdrawingContext,Pointpoint,Penpen,doubleangle0){// 调用 DrawingContextExtension 中的扩展方法// 绘制一个十字形状// - 水平线从 point - (宽度/2) 到 point (宽度/2)// - 垂直线从 point - (高度/2) 到 point (高度/2)// - 宽度和高度 pen.Thickness * 4.0drawingContext.DrawCross(point,pen.Brush,pen.Thickness,pen.Thickness*4.0,// 水平线长度pen.Thickness*4.0,// 垂直线长度angle);}// 绘制圆点// 参数说明// view - 视图对象// drawingContext - WPF绘图上下文// point - 圆点的中心点// fill - 填充颜色// radius - 圆点半径默认1像素publicvoidDrawPoint(IViewview,DrawingContextdrawingContext,Pointpoint,Brushfill,doubleradius1){// 绘制一个实心圆// DrawEllipse(填充, 边框, 中心点, X半径, Y半径)// 这里边框为 null只绘制填充drawingContext.DrawEllipse(fill,null,point,radius,radius);}} 设计目的为什么需要 CommonShapeBase在形状绘制中经常需要绘制一些辅助图形场景1绘制中心标记 场景2绘制控制点 ┌─────┐ ┌─────┐ │ ✝ │ ← 十字标记 │ ● │ ← 圆点 └─────┘ └─────┘ 表示中心点 表示可拖拽的控制点如果没有 CommonShapeBase每个形状都要重复实现这些方法// ❌ 没有基类每个形状都要重复写publicclassRectangleShape:ShapeBase{privatevoidDrawCross(DrawingContextdc,Pointpoint,Penpen){// 重复的十字绘制代码doublelenpen.Thickness*4;dc.DrawLine(pen,newPoint(point.X-len,point.Y),newPoint(point.Xlen,point.Y));dc.DrawLine(pen,newPoint(point.X,point.Y-len),newPoint(point.X,point.Ylen));}}publicclassCircleShape:ShapeBase{privatevoidDrawCross(DrawingContextdc,Pointpoint,Penpen){// 完全相同的代码又写一遍doublelenpen.Thickness*4;dc.DrawLine(pen,newPoint(point.X-len,point.Y),newPoint(point.Xlen,point.Y));dc.DrawLine(pen,newPoint(point.X,point.Y-len),newPoint(point.X,point.Ylen));}}// ✅ 有基类代码复用publicclassRectangleShape:CommonShapeBase{publicvoidDrawCenterMark(DrawingContextdc,Pointcenter,Penpen){this.DrawCross(null,dc,center,pen);// 直接调用基类方法}} 方法详解1. DrawCross - 绘制十字标记publicvoidDrawCross(IViewview,DrawingContextdrawingContext,Pointpoint,Penpen,doubleangle0)视觉效果无旋转angle0 旋转45度angle45 │ │ ────┼──── ● │ │ 实际使用示例publicclassRectangleShape:CommonShapeBase{publicoverridevoidDrawing(IViewview,DrawingContextdc,Penpen,Brushfill){// 绘制矩形dc.DrawRectangle(fill,pen,Bounds);// 在矩形中心绘制十字标记PointcenternewPoint(Bounds.LeftBounds.Width/2,Bounds.TopBounds.Height/2);this.DrawCross(view,dc,center,pen);}}参数计算// 十字线长度 pen.Thickness * 4.0// 例如pen.Thickness 2// 十字线长度 8 像素//// 8像素// ←───────→// │// ────┼──── ← 8像素// │2. DrawPoint - 绘制圆点publicvoidDrawPoint(IViewview,DrawingContextdrawingContext,Pointpoint,Brushfill,doubleradius1)视觉效果半径1 半径3 半径5 ● ● ● (小点) (中点) (大点)实际使用示例publicclassPolygonShape:CommonShapeBase{publicoverridevoidDrawing(IViewview,DrawingContextdc,Penpen,Brushfill){// 绘制多边形// ... 多边形绘制代码// 在每个顶点绘制圆点便于识别顶点位置foreach(varpointinVertices){this.DrawPoint(view,dc,point,Brushes.Red,3);}}} 实际应用示例示例1带中心标记的矩形publicclassCenterMarkedRectangle:CommonShapeBase{publicRectBounds{get;set;}publicoverridevoidDrawing(IViewview,DrawingContextdc,Penpen,Brushfill){// 1. 绘制矩形dc.DrawRectangle(fill,pen,Bounds);// 2. 绘制中心十字PointcenternewPoint(Bounds.XBounds.Width/2,Bounds.YBounds.Height/2);this.DrawCross(view,dc,center,pen);// 3. 绘制四个角的圆点this.DrawPoint(view,dc,newPoint(Bounds.Left,Bounds.Top),Brushes.Blue,3);this.DrawPoint(view,dc,newPoint(Bounds.Right,Bounds.Top),Brushes.Blue,3);this.DrawPoint(view,dc,newPoint(Bounds.Left,Bounds.Bottom),Brushes.Blue,3);this.DrawPoint(view,dc,newPoint(Bounds.Right,Bounds.Bottom),Brushes.Blue,3);}}效果图●───────────────● │ │ │ ✝ │ ← 中心十字 │ │ ●───────────────●示例2可旋转的十字标记publicclassRotatableShape:CommonShapeBase{publicPointCenter{get;set;}publicdoubleRotationAngle{get;set;}publicoverridevoidDrawing(IViewview,DrawingContextdc,Penpen,Brushfill){// 绘制旋转的十字标记this.DrawCross(view,dc,Center,pen,RotationAngle);}}示例3顶点带圆点的多边形publicclassVertexMarkedPolygon:CommonShapeBase{publicListPointVertices{get;set;}publicoverridevoidDrawing(IViewview,DrawingContextdc,Penpen,Brushfill){// 绘制多边形vargeometrynewStreamGeometry();using(varctxgeometry.Open()){ctx.BeginFigure(Vertices[0],true,true);ctx.PolyLineTo(Vertices.Skip(1).ToList(),true,true);}dc.DrawGeometry(fill,pen,geometry);// 在每个顶点绘制圆点便于编辑foreach(varpointinVertices){this.DrawPoint(view,dc,point,Brushes.Orange,4);}// 绘制中心点PointcenterGetPolygonCenter();this.DrawCross(view,dc,center,pen);}privatePointGetPolygonCenter(){doublesumXVertices.Sum(pp.X);doublesumYVertices.Sum(pp.Y);returnnewPoint(sumX/Vertices.Count,sumY/Vertices.Count);}} 继承关系中的位置IShape接口 ↓ ShapeBase抽象类← 基础形状功能 ↓ CommonShapeBase抽象类← 当前类添加通用绘图方法 ↓ MouseOverShapeBase抽象类← 添加悬停功能 ↓ SelectableShapeBase抽象类← 添加选中功能 ↓ HandleShapeBase抽象类← 添加控制点功能 ↓ PreviewShapeBase抽象类← 添加预览功能 ↓ 具体形状 扩展建议可以添加更多通用方法publicabstractclassCommonShapeBase:ShapeBase{// 现有方法...// 绘制虚线边框publicvoidDrawDashedRect(DrawingContextdc,Rectrect,Penpen){vardashedPennewPen(pen.Brush,pen.Thickness){DashStyleDashStyles.Dash};dc.DrawRectangle(null,dashedPen,rect);}// 绘制带阴影的形状publicvoidDrawWithShadow(DrawingContextdc,Rectrect,Penpen,Brushfill){// 先绘制阴影varshadowRectnewRect(rect.X5,rect.Y5,rect.Width,rect.Height);dc.DrawRectangle(Brushes.Gray,null,shadowRect);// 再绘制实际形状dc.DrawRectangle(fill,pen,rect);}// 绘制边框高亮publicvoidDrawHighlightBorder(DrawingContextdc,Rectrect,Penpen){varhighlightPennewPen(Brushes.Yellow,pen.Thickness2);dc.DrawRectangle(null,highlightPen,rect);}// 绘制信息标签publicvoidDrawLabel(DrawingContextdc,Pointposition,stringtext,BrushtextBrush){varformattedTextnewFormattedText(text,System.Globalization.CultureInfo.CurrentCulture,FlowDirection.LeftToRight,newTypeface(Microsoft YaHei),12,textBrush,1.2);dc.DrawText(formattedText,position);}}设计模式分析1. 模板方法模式基类提供辅助方法子类在绘制时调用这些方法。2. 代码复用通过继承所有子类自动获得这些通用绘图能力。3. 单一职责原则ShapeBase负责基础的样式管理和绘制框架CommonShapeBase负责提供通用的绘图辅助方法具体形状负责实现特定的形状绘制逻辑总结组件类型职责CommonShapeBase抽象类提供通用的绘图辅助方法提供的方法方法用途典型应用场景DrawCross()绘制十字标记中心点标记、旋转中心DrawPoint()绘制圆点顶点标记、控制点、吸附点核心价值代码复用避免每个形状重复实现相同的绘图逻辑统一风格确保所有形状的辅助标记样式一致简化开发添加新形状时直接使用这些方法即可易于维护修改辅助标记样式只需改一处这个基类虽然简单但为所有形状提供了实用的绘图工具大大简化了具体形状的实现

更多文章