From fab5d6e30b9a42a1f94524fca74ef227d2c963e4 Mon Sep 17 00:00:00 2001 From: cloudflight <cloudflight@126.com> Date: 星期六, 20 七月 2024 11:12:32 +0800 Subject: [PATCH] 1 --- Hydraulic/Hydro.MapUI/Map/MapViewer.Draw.cs | 366 +++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 288 insertions(+), 78 deletions(-) diff --git a/Hydraulic/Hydro.MapUI/Map/MapViewer.Draw.cs b/Hydraulic/Hydro.MapUI/Map/MapViewer.Draw.cs index ce8dc52..c5840c8 100644 --- a/Hydraulic/Hydro.MapUI/Map/MapViewer.Draw.cs +++ b/Hydraulic/Hydro.MapUI/Map/MapViewer.Draw.cs @@ -1,4 +1,6 @@ -锘縰sing Hydro.MapView; +锘縰sing DevExpress.XtraPrinting.Native; +using Hydro.MapView; +using Hydro.MapView.Base; using Hydro.MapView.Common; using System; using System.Collections.Generic; @@ -18,15 +20,119 @@ public delegate void DrawDelegate(Graphics bufferG, Template template); public delegate void MouseDelegate(MouseEventArgs e); - + partial class MapViewer { - void Draw(Graphics bufferG, Template template) + void DrawBackGroud(Graphics bufferG,Template template) { if (template == null) return; var _Nodes = template.network.Nodes.ViewNodes; var _Links = template.network.Links.ViewLinks; + var Cpoints = getCurclePoints(64).ToList(); + + var r = 1.73f / zoom; + var rt = r; + + float minElve = float.MinValue; + float maxElve = float.MaxValue; + + r = r * Link_multiply; + List<PointF> diametersZoom = new List<PointF>() { new PointF(0, 0.08f), new PointF(150, 0.03f), new PointF(300, 0.001f), new PointF(800, 0.0001f) }; + + Pen penN = new Pen(Color.FromArgb(0, 0, 255), 1 * r); + + + //鑳屾櫙鍥剧粯鍒� + if (this.mapOption.isShowPic && template != null && File.Exists(template.BackGroundImg_FullPath)) + + + { + //var gs = bufferG.Save(); + // 搴旂敤鐭╅樀鍙樻崲浠ユ姷娑堜箣鍓嶇殑缈昏浆鏁堟灉 + //bufferG.ScaleTransform(1 / Zoom.X, 1 / Zoom.Y); + List<PointF> p = new List<PointF>(); + + if (!this.mapOption.isAutoBackgroundImage) + { + var Cps = new List<PointF> + { + template.BackGroundPoint1, + new PointF(template.BackGroundPoint2.X,template.BackGroundPoint1.Y), + new PointF(template.BackGroundPoint1.X,template.BackGroundPoint2.Y), + //template.BackGroundPoint2, + + + }; + Cps.ForEach(cp => p.Add(WorldPointToMapPoint(cp, template.BackGroundElev, template.OffSet))); + } + else + { + + // 鎭㈠涔嬪墠淇濆瓨鐨勭粯鍥剧姸鎬� + + //var Cps = new List<PointF> + //{ + // template.BackGroundPoint1, + // new PointF(template.BackGroundPoint2.X,template.BackGroundPoint1.Y), + // new PointF(template.BackGroundPoint1.X,template.BackGroundPoint2.Y), + // //template.BackGroundPoint2, + + + //}; + var p1 = new PointF(template.BackGroundImgX, template.BackGroundImgY); + var p2 = new PointF(template.BackGroundImgX + template.BackGroundImgWidth, template.BackGroundImgY + template.BackGroundImgHeight); + + var f = template.BackGroundImgRotaAngle / 180 * Math.PI; + var djx = Math.Sqrt((Math.Pow(template.BackGroundImgWidth, 2) + Math.Pow(template.BackGroundImgHeight, 2))); + var p3 = new PointF(p1.X + (float)(Math.Cos(f) * template.BackGroundImgWidth), p1.Y + (float)(Math.Sin(f) * template.BackGroundImgWidth)); + var p4 = new PointF(p1.X - (float)(Math.Sin(f) * template.BackGroundImgHeight), p1.Y + (float)(Math.Cos(f) * template.BackGroundImgHeight)); + p3.Y = p4.Y; + //p4.Y = -p4.Y; + var Cps = new List<PointF> + { + //template.BackGroundPoint1, + //new PointF(template.BackGroundImgX,template.BackGroundImgY), + p4, + p3,p1 + //template.BackGroundPoint2, + + + }; + template.BackGroundPoint1 = p4; + template.BackGroundPoint2 = new PointF(p3.X, p1.Y); + + + + //List<PointF> p = new List<PointF>(); + Cps.ForEach(cp => p.Add(WorldPointToMapPoint(cp, template.BackGroundElev, template.OffSet))); + } + + //bufferG.DrawImage(System.Drawing.Image.FromFile(@"C:\Users\cloud\Pictures\GenshinImpactCloudGame\QQ鎴浘20230919105637.png"), p[0]); + try + { + var img = System.Drawing.Image.FromFile(template.BackGroundImg_FullPath); + if (img != null) + { + bufferG.FillPolygon(penN.Brush, p.ToArray()); + bufferG.DrawImage(img, p.ToArray()); + } + } + catch + { + + } + + //bufferG.Restore(gs); + } + } + + void Draw(Graphics bufferG, Template template) + { + if (template == null) return; + var _Nodes = template.network.Nodes.ViewNodes; + var _Links = template.network.Links.ViewLinks; + var _Areas = template.network.Areas; var Cpoints = getCurclePoints(64).ToList(); var r = 1.73f / zoom; @@ -56,50 +162,52 @@ Pen penClosed = new Pen(Color.OrangeRed, 2 * r); Pen penHovered = new Pen(Color.DeepSkyBlue, 5 * r); - //鑳屾櫙鍥剧粯鍒� - if (this.mapOption.isShowPic && template != null && File.Exists(template.BackGroundImg_FullPath)) + - + //缁樺埗闈� + using (Pen pen0 = new Pen(Color.FromArgb(0, 0, 255), 2 * r)) { - //var gs = bufferG.Save(); - // 搴旂敤鐭╅樀鍙樻崲浠ユ姷娑堜箣鍓嶇殑缈昏浆鏁堟灉 - //bufferG.ScaleTransform(1 / Zoom.X, 1 / Zoom.Y); - - - - // 鎭㈠涔嬪墠淇濆瓨鐨勭粯鍥剧姸鎬� - - var Cps = new List<PointF> + foreach (var area in _Areas) { - template.BackGroundPoint1, - new PointF(template.BackGroundPoint2.X,template.BackGroundPoint1.Y), - new PointF(template.BackGroundPoint1.X,template.BackGroundPoint2.Y), - //template.BackGroundPoint2, - - - }; + if (!area.Visible) continue; + if (!IsFaceVisibleToCamera(area, GetCameraPosition())) continue; + if (area.Elev < minElve || area.Elev >= maxElve) continue; - - List<PointF> p = new List<PointF>(); - Cps.ForEach(cp => p.Add(WorldPointToMapPoint(cp, template.BackGroundElev, template.OffSet))); - - //bufferG.DrawImage(System.Drawing.Image.FromFile(@"C:\Users\cloud\Pictures\GenshinImpactCloudGame\QQ鎴浘20230919105637.png"), p[0]); - try - { - var img = System.Drawing.Image.FromFile(template.BackGroundImg_FullPath); - if (img != null) + var p = new List<PointF>(); + foreach (var node in area.InnerNodes) { - bufferG.FillPolygon(penN.Brush, p.ToArray()); - bufferG.DrawImage(img, p.ToArray()); + p.Add(CubeWorldPointToMapPoint(node, template.OffSet)); } - } - catch - { + if (p.Count < 3) continue; + pen0.Color = penClosed.Color = area.color; + Pen pen = pen0; + if (area.Hovered) pen = penHovered; + bufferG.FillPolygon(pen.Brush, p.ToArray()); + bufferG.DrawPolygon(pen, p.ToArray()); + //鏄剧ずarea鐨勫悕绉� + var c = new PointF(p.Average(p0 => p0.X), p.Average(p0 => p0.Y)); + var brush=new SolidBrush(Color.White); + - } - //bufferG.Restore(gs); + + var gs = bufferG.Save(); + // 搴旂敤鐭╅樀鍙樻崲浠ユ姷娑堜箣鍓嶇殑缈昏浆鏁堟灉 + bufferG.ScaleTransform(1 / Zoom.X, 1 / Zoom.Y); + + Font font = new Font(FontFamily.GenericSansSerif, 10*10*zoom); + + SizeF textSize = bufferG.MeasureString(area.Name, font); + var center = new PointF(c.X * Zoom.X, c.Y * Zoom.Y); + float textLeft = center.X - textSize.Width / 2; + float textTop = center.Y - textSize.Height / 2; + PointF pd = new PointF(textLeft, textTop); + + bufferG.DrawString(area.Name, font, brush, pd); + // 鎭㈠涔嬪墠淇濆瓨鐨勭粯鍥剧姸鎬� + bufferG.Restore(gs); + } } @@ -117,9 +225,9 @@ var p1 = WorldPointToMapPoint(link.StartNode, template.OffSet); var p2 = WorldPointToMapPoint(link.EndNode, template.OffSet); if (!isVisible(p1) && !isVisible(p2)) continue; - if (_LinkColour != null) + if (LinkColour != null) { - pen0.Color = penClosed.Color = GraphHelper.getLinkColor(_LinkColour, link); + pen0.Color = penClosed.Color = GraphHelper.getLinkColor(LinkColour, link); } Pen pen = pen0; @@ -287,8 +395,14 @@ { if (link.StartNode == null || link.EndNode == null) continue; + try + { + bufferG.DrawLines(link.Selected ? penChoosed : pen, new PointF[] { p1, p2 }); + } + catch (Exception ex) + { - bufferG.DrawLines(link.Selected ? penChoosed : pen, new PointF[] { p1, p2 }); + } if (_Template.mapOption._ShowFlowDirection) { var c = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2); @@ -363,9 +477,9 @@ dict_point.Add(ps_20); //var x = junction.Position.X * zoom + PanningOffset.X - radius / 2.0f; //var y = junction.Position.Y * zoom + PanningOffset.Y - radius / 2.0f; - if (_NodeColour != null) + if (NodeColour != null) { - pen.Color = penChoosed.Color = GraphHelper.getNodeColor(_NodeColour, node); + pen.Color = penChoosed.Color = GraphHelper.getNodeColor(NodeColour, node); brush = pen.Brush; brushChoosed = penChoosed.Brush; @@ -509,9 +623,9 @@ dict_point.Add(ps_20); //var x = junction.Position.X * zoom + PanningOffset.X - radius / 2.0f; //var y = junction.Position.Y * zoom + PanningOffset.Y - radius / 2.0f; - if (_NodeColour != null) + if (NodeColour != null) { - pen.Color = GraphHelper.getNodeColor(_NodeColour, node); + pen.Color = GraphHelper.getNodeColor(NodeColour, node); brush = pen.Brush; brushChoosed = penChoosed.Brush; @@ -575,7 +689,7 @@ } if (_isPainting) { - if (_mouseState ==MapViewEnum.MouseState.鏂板绔嬬) + if (_mouseState == MapViewEnum.MouseState.鏂板绔嬬) { var wPos = GetZZWorldPoint(_select_junction1.Position3D, _MousePosition, new Vector3(0, 0, 1)); using (var pen = new Pen(Color.Black, 1 * r)) @@ -594,14 +708,14 @@ { var wPos = GetZZWorldPoint(_select_junction1.Position3D, _MousePosition, new Vector3(1, 1, 0)); //getPointAndHeight(e, _select_junction1, out p, out z); - var mapPos= WorldPointToMapPoint(wPos); + var mapPos = WorldPointToMapPoint(wPos); bufferG.DrawLine(pen, WorldPointToMapPoint(_select_junction1), mapPos); } else { bufferG.DrawLine(pen, WorldPointToMapPoint(_select_junction1), _MousePosition); } - + } } } @@ -680,6 +794,12 @@ return new PointF(worldX, worldY); } + /// <summary> + /// 涓栫晫鎶曞奖鍧愭爣杞崲涓哄睆骞曞潗鏍� + /// </summary> + /// <param name="mapPos"></param> + /// <param name="z"></param> + /// <returns></returns> private PointF MapToScreen(PointF mapPos, float z = 0) { @@ -696,17 +816,18 @@ // 鏍规嵁鏃嬭浆瑙掑害璁$畻鏃嬭浆鍚庣殑鍧愭爣 - private PointF Get骞抽潰鏃嬭浆Point(PointF p) + private PointF Get骞抽潰鏃嬭浆Point(PointF p, PointF MapC) { - PointF center = MapCenter; + + PointF center = MapC ; double radian = Rotation * Math.PI / 180; // 瑙掑害杞姬搴� float x = (float)(Math.Cos(radian) * (p.X - center.X) - Math.Sin(radian) * (p.Y - center.Y) + center.X); float y = (float)(Math.Sin(radian) * (p.X - center.X) + Math.Cos(radian) * (p.Y - center.Y) + center.Y); return new PointF(x, y); } - private PointF Get骞抽潰杩樺師Point(PointF p) + private PointF Get骞抽潰杩樺師Point(PointF p, PointF MapC) { - PointF center = MapCenter; + PointF center = MapC; double radian = -Rotation * Math.PI / 180; // 瑙掑害杞姬搴� float x = (float)(Math.Cos(radian) * (p.X - center.X) - Math.Sin(radian) * (p.Y - center.Y) + center.X); float y = (float)(Math.Sin(radian) * (p.X - center.X) + Math.Cos(radian) * (p.Y - center.Y) + center.Y); @@ -715,9 +836,9 @@ - private PointF Get淇瑙掓棆杞琍oint(PointF p, float z) + private PointF Get淇瑙掓棆杞琍oint(PointF p, float z, PointF MapC) { - PointF center = MapCenter; + PointF center = MapC; double radian_fushi = 淇寮у害; float sin = (float)Math.Sin(radian_fushi); float cos = (float)Math.Cos(radian_fushi); @@ -725,9 +846,9 @@ float y = (float)(sin * (p.Y - center.Y) + center.Y) + cos * z; return new PointF(x, y); } - private PointF Get淇瑙掕繕鍘烶oint(PointF p, float z) + private PointF Get淇瑙掕繕鍘烶oint(PointF p, float z, PointF MapC) { - PointF center = MapCenter; + PointF center = MapC; double radian_fushi = 淇寮у害; float sin = (float)Math.Sin(radian_fushi); float cos = (float)Math.Cos(radian_fushi); @@ -746,7 +867,7 @@ return new PointF(x, y); } /// <summary> - /// 鑾峰彇鍦板浘鎶曞奖鍧愭爣 + /// 鑾峰彇涓栫晫鎶曞奖鍧愭爣 /// </summary> /// <param name="point"></param> /// <param name="z"></param> @@ -756,9 +877,9 @@ if (offset == null) offset = new PointF3D(0, 0, 0); point = new PointF(point.X + offset.X, point.Y + offset.Y); - var pointR = Get骞抽潰鏃嬭浆Point(point); + var pointR = Get骞抽潰鏃嬭浆Point(point, MapCenter); - var pointT = Get淇瑙掓棆杞琍oint(pointR, z + offset.Z); + var pointT = Get淇瑙掓棆杞琍oint(pointR, z + offset.Z, MapCenter); //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y)); return pointT; @@ -774,7 +895,19 @@ if (junction == null) return new PointF(0, 0); p = WorldPointToMapPoint(junction.Position, junction.Elev, offset); return p; - + } + private PointF CubeWorldPointToMapPoint(NodeViewModel junction, PointF3D offset = null) + { + PointF p; + if (junction == null) return new PointF(0, 0); + var point = junction.Position; + var z = junction.Elev; + if (offset == null) offset = new PointF3D(0, 0, 0); + point = new PointF(point.X + offset.X, point.Y + offset.Y); + var pointR = Get骞抽潰鏃嬭浆Point(point, new PointF(0, 0)); + var pointT = Get淇瑙掓棆杞琍oint(pointR, z + offset.Z, new PointF(0, 0)); + //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y)); + return pointT; } private List<PointF> WorldPointToMapPoint(LinkViewModel pipe, PointF3D offset = null) { @@ -799,13 +932,13 @@ private PointF3D GetZZWorldPoint(PointF3D position3D, PointF mousePosition, Vector3 vector3) { //鍋氫竴鏉¢�氳繃position3D鐨勫钩琛屼簬vector3鐨勭洿绾匡紝 - if (vector3==new Vector3(0,0,1)) + if (vector3 == new Vector3(0, 0, 1)) { return GetLGWorldPoint(position3D, mousePosition); } else { - var p2=MapPointToWorldPoint(mousePosition, position3D.Z); + var p2 = MapPointToWorldPoint(mousePosition, position3D.Z); var vector = new Vector2(p2.X - position3D.X, p2.Y - position3D.Y); //鍒ゆ柇浜岀淮鍚戦噺vector鍦ㄧ鍑犺薄闄愶紝璺濈鍝釜杞存渶杩� var x = vector.X; @@ -825,7 +958,7 @@ return new PointF3D(position3D.X - Math.Abs(x), position3D.Y, position3D.Z); } } - else + else { if (y > 0) { @@ -855,14 +988,14 @@ float sin = (float)Math.Sin(radian_fushi); float cos = (float)Math.Cos(radian_fushi); var p1 = WorldPointToMapPoint(position3D); - var dy=p2.Y - p1.Y; - float dz= dy/cos; - return new PointF3D(position3D.X, position3D.Y, position3D.Z+ dz); + var dy = p2.Y - p1.Y; + float dz = dy / cos; + return new PointF3D(position3D.X, position3D.Y, position3D.Z + dz); } - + private PointF MapPointToWorldPoint(PointF3D point) - { + { return MapPointToWorldPoint(new PointF(point.X, point.Y), point.Z); } /// <summary> @@ -871,10 +1004,10 @@ /// <param name="point"></param> /// <param name="z"></param> /// <returns></returns> - private PointF MapPointToWorldPoint(PointF point, float z = 0) + public PointF MapPointToWorldPoint(PointF point, float z = 0) { - var pointT = Get淇瑙掕繕鍘烶oint(point, z); - pointT = Get骞抽潰杩樺師Point(pointT); + var pointT = Get淇瑙掕繕鍘烶oint(point, z,MapCenter); + pointT = Get骞抽潰杩樺師Point(pointT, MapCenter); //var n=new PointF((float)pointR.X - Z(z).X, (float)(pointR.Y - Z(z).Y)); return pointT; @@ -891,7 +1024,84 @@ #endregion + #region 璁$畻涓夌淮鐩告満 + public PointF3D GetCameraPosition( float distance=1) + { + // 灏嗚搴﹁浆鎹负寮у害 + float rotationRadians = (float)Rotation * (float)Math.PI / 180; + float rotationFRadians = (float)RotationF * (float)Math.PI / 180; + // 璁$畻鐩告満鐨勭悆鍧愭爣绯讳綅缃� + float x = distance * (float)Math.Sin(rotationFRadians) * (float)Math.Cos(rotationRadians); + float y = distance * (float)Math.Sin(rotationFRadians) * (float)Math.Sin(rotationRadians); + float z = distance * (float)Math.Cos(rotationFRadians); + + return new PointF3D(x, y, z); + } + public bool IsFaceVisibleToCamera(AreaViewModel area, PointF3D cameraPosition) + { + + //姝i潰鏄�2锛屽彸闈㈡槸1锛屽乏闈㈡槸3锛岃儗闈㈡槸4 + //Rotation涓�0鏃讹紝鍙樉绀烘闈紝Rotation涓�90鏃讹紝鍙樉绀哄彸闈紝Rotation涓�180鏃讹紝鍙樉绀鸿儗闈紝Rotation涓�270鏃讹紝鍙樉绀哄乏闈� + int delta = 5; + bool flag = false; + switch (area.Name) + { + case "宸�": + //Rotation涓�0~180鏃舵樉绀� + if (RotationF<=90-delta && Rotation >= 0 + delta && Rotation <= 180 - delta) + flag = true; + break; + case "鍓�": + //Rotation涓�0~180鏃舵樉绀� + if (RotationF <= 90 - delta && Rotation >= -90 + delta && Rotation <= 90 - delta) + flag = true; + break; + case "鍙�": + //Rotation涓�0~180鏃舵樉绀� + if (RotationF <= 90 - delta && Rotation >= -180 + delta && Rotation <= 0 - delta) + flag = true; + break; + case "鍚�": + //Rotation涓�0~180鏃舵樉绀� + if (RotationF <= 90 - delta && ((Rotation >= 90 + delta && Rotation<=180)||( Rotation>=-180 && Rotation <= -90 - delta))) + flag = true; + break; + case "涓�": + if (RotationF >= 0 + delta) + flag = true; + break; + case "涓�": + if (RotationF <= 0 - delta) + flag = true; + break; + } + return flag; + + var faceVertices = area.InnerNodes; + if (faceVertices.Count < 3) return false; + PointF3D faceVertexA = faceVertices[0].Position3D; + PointF3D faceVertexB = faceVertices[1].Position3D; + PointF3D faceVertexC = faceVertices[2].Position3D; + + // 璁$畻娉曞悜閲� + PointF3D AB = faceVertexB - faceVertexA; + PointF3D AC = faceVertexC - faceVertexA; + PointF3D normal = AB ^ AC; + + // 璁$畻浠庣浉鏈轰綅缃埌闈㈢殑鍚戦噺 + PointF3D PD = faceVertexA - cameraPosition; + + // 璁$畻鐐圭Н + float dotProduct = normal * PD; + + // 鍒ゆ柇闈㈡槸鍚︽湞鍚戠浉鏈� + bool isFacingCamera = dotProduct > 0; + return isFacingCamera; + } + + + #endregion #region 鍒ゆ柇鍙鎬� private float Get_dist(PointF A, PointF B) @@ -902,26 +1112,26 @@ return dist; } //鍒ゆ柇A璺濈绾挎B鍜孋鐨勮窛绂伙紝濡傛灉瓒呭嚭浜嗙嚎娈电殑鑼冨洿锛屽垯杩斿洖鍒版渶杩戠殑绔偣鐨勮窛绂伙紱璺濈绾挎涓績鐐硅秺杩滐紝杩斿洖鐨勮窛绂昏秺澶э紱 - private float Get_dist(PointF A, PointF B,PointF C,float MaxOff) + private float Get_dist(PointF A, PointF B, PointF C, float MaxOff) { //PointF A, PointF B,PointF C锛屾眰鐐笰鍒癇銆丆鏋勬垚绾挎鐨勪腑蹇冪偣鐨勮窛绂� - float dist_off = GetDistanceFromPointAToMidpointOfLineSegmentBC(A,B,C); + float dist_off = GetDistanceFromPointAToMidpointOfLineSegmentBC(A, B, C); //浣跨敤dist_off 璺� 绾挎A銆丅鐨勯暱搴︽瘮杈冿紝濡傛灉澶т簬1/2锛屽垯杩斿洖MaxOff锛屽惁鍒欐寜鐓ф瘮渚嬭繑鍥� float dist_len = Get_dist(B, C); if (dist_len < 5) dist_len = 5; - float dist_add = (dist_off / dist_len>0.5?MaxOff:dist_off/dist_len*2*MaxOff); + float dist_add = (dist_off / dist_len > 0.5 ? MaxOff : dist_off / dist_len * 2 * MaxOff); float dx = C.X - B.X; float dy = C.Y - B.Y; float dist = (float)Math.Sqrt(dx * dx + dy * dy); - if (dist == 0) return Get_dist(A, B)+ dist_add; + if (dist == 0) return Get_dist(A, B) + dist_add; float t = ((A.X - B.X) * dx + (A.Y - B.Y) * dy) / (dist * dist); - if (t < 0) return Get_dist(A, B)+ dist_add; - if (t > 1) return Get_dist(A, C)+ dist_add; + if (t < 0) return Get_dist(A, B) + dist_add; + if (t > 1) return Get_dist(A, C) + dist_add; float x = B.X + t * dx; float y = B.Y + t * dy; - return Get_dist(A, new PointF(x, y))+ dist_add; + return Get_dist(A, new PointF(x, y)) + dist_add; } private float GetDistanceFromPointAToMidpointOfLineSegmentBC(PointF A, PointF B, PointF C) -- Gitblit v1.9.3