private void UpdateAndDrawFlowArrow(RenderTime time, LineProxy proxy, int zoomLevel, MM_DisplayParameter displayOptions, SharpDX.Direct2D1.Brush brush) { //Now, draw the line as appropriate if (proxy.Coordinates == null || proxy.Coordinates.Count == 0) { return; } // reset if bad if (proxy.FlowPositionPercentage > 1) { proxy.FlowPositionPercentage = 1; } if (proxy.FlowPositionPercentage < float.Epsilon) { proxy.FlowPositionPercentage = 0; } // reset if bad if (proxy.FlowVarPositionPercentage > 1) { proxy.FlowVarPositionPercentage = 1; } if (proxy.FlowVarPositionPercentage < float.Epsilon) { proxy.FlowVarPositionPercentage = 0; } var Line = proxy.BaseLine; // don't render dead lines flow arrows if (Line == null || Math.Abs(Line.MVAFlow) < 0.1 || (Line.NearBus != null && Line.NearBus.Dead) || (Line.FarBus != null && Line.FarBus.Dead)) { return; } //Determine how large our arrow should be float baseSize = proxy.BaseLine.KVLevel.MVASize; float threshold = proxy.BaseLine.KVLevel.MVAThreshold / 100.0f; bool flowKvVisible = proxy.BaseLine.KVLevel.ShowMVA; float mvaSize = Line.KVLevel.MVASize; float lineWidth = displayOptions.Width; float flowIncrement = 0; float flowVarIncrement = 0; float flowSize; bool isTie = Line is MM_Tie; if ((!MM_Repository.OverallDisplay.ShowLineFlows || !flowKvVisible) && !(isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible)) { return; } //MM_Repository.OverallDisplay. // absolute vs % limit bool absoluteValueFlowSize = zoomLevel < MM_Repository.OverallDisplay.LineFlows; if (isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible) { // show enhanced size/color for AC Tie lines if TieFlowDirectionVisible == true if (MM_Repository.KVLevels.ContainsKey("Tie")) { mvaSize = MM_Repository.KVLevels["Tie"].MVASize; } else if (MM_Repository.KVLevels.ContainsKey("DCTie")) { mvaSize = MM_Repository.KVLevels["DCTie"].MVASize; } else { mvaSize = 5; } } else if (Line.KVLevel.Name.Contains("Tie")) { isTie = true; } bool moveForward = true; float zoomScale = (float)zoomLevel / MM_Repository.OverallDisplay.LineFlows; bool varForward = true; var varFlowSize = Math.Min(50, lineWidth * baseSize); if (absoluteValueFlowSize) { if (Math.Abs(Line.MVAFlow) < float.Epsilon) { flowSize = flowIncrement = 0; } else { moveForward = Line.MVAFlowDirection == Line.ConnectedStations[1]; varForward = Line.MVARFlowDirection == Line.ConnectedStations[1]; flowSize = (zoomLevel / 20f) * mvaSize * Line.MVAFlow * 0.02f; // + 1.5f * lineWidth; varFlowSize = (zoomLevel / 20f) * mvaSize * Line.MVAFlow * 0.04f; // + 1.5f * lineWidth; } } else { // relative size based on limit if (Line.NormalLimit == 0) { flowSize = flowIncrement = 0; } else { var percentLimit = Line.MVAFlow / Line.NormalLimit; var percentVar = Line.MVARFlow / Line.NormalLimit; if (percentLimit < threshold) { return; } moveForward = Line.MVAFlowDirection == Line.ConnectedStations[1]; varForward = Line.MVARFlowDirection == Line.ConnectedStations[1]; flowSize = 10f * mvaSize * percentLimit * ((float)(MathUtil.Clamp(lineWidth, 1, 3) / 2f)); varFlowSize = 30f * mvaSize * percentVar * ((float)(MathUtil.Clamp(lineWidth, 1, 3) / 2f)); } } flowSize = MathUtil.Clamp(flowSize, 0, 100); varFlowSize = MathUtil.Clamp(varFlowSize, 0, 100); if (float.IsNaN(flowSize) || flowSize < 0) { flowSize = flowIncrement = 0; varFlowSize = flowVarIncrement = 0; } else { flowIncrement = MathUtil.Clamp(0.5f * zoomScale * flowSize, -20f, 20f) * (float)time.ElapsedTime.TotalSeconds; flowVarIncrement = MathUtil.Clamp(0.5f * zoomScale * varFlowSize, -20f, 20f) * (float)time.ElapsedTime.TotalSeconds; } // scale up arrow (but not speed) based on zoom if (flowSize < lineWidth + 0.25f || proxy.Length <= 0 || (MM_Repository.OverallDisplay.BlackstartMode == MM_Display.enumBlackstartMode.HideExternalElements && !Line.IsInternal)) { return; } // Move MVA flow arrow if (moveForward) { proxy.FlowPositionPercentage += flowIncrement / proxy.Length; } else { proxy.FlowPositionPercentage -= flowIncrement / proxy.Length; } if (proxy.FlowPositionPercentage < float.Epsilon) { proxy.FlowPositionPercentage = 1 - proxy.FlowPositionPercentage; } else { proxy.FlowPositionPercentage -= (float)Math.Floor(proxy.FlowPositionPercentage); // just keep the decimal } // Move Var Arrow if (varForward) { proxy.FlowVarPositionPercentage += flowVarIncrement / proxy.Length; } else { proxy.FlowVarPositionPercentage -= flowVarIncrement / proxy.Length; } if (proxy.FlowVarPositionPercentage < float.Epsilon) { proxy.FlowVarPositionPercentage = 1 - proxy.FlowVarPositionPercentage; } else { proxy.FlowVarPositionPercentage -= (float)Math.Floor(proxy.FlowVarPositionPercentage); // just keep the decimal } if (zoomLevel < MM_Repository.OverallDisplay.LineFlows) { proxy.FlowPositionPercentage = 0.5f; proxy.FlowVarPositionPercentage = 0.5f; } SolidColorBrush borderBrush = null; if (isTie && MM_Repository.OverallDisplay.TieFlowDirectionVisible) { bool importing = (Line.Substation1.IsInternal && (Line.MVAFlowDirection == Line.Substation1)) || (Line.Substation2.IsInternal && (Line.MVAFlowDirection == Line.Substation2)); var color = importing ? MM_Repository.OverallDisplay.TieFlowImportColor : MM_Repository.OverallDisplay.TieFlowExportColor; if (proxy.BlackStartDim) { color = MM_Repository.OverallDisplay.BlackstartDim(color); } borderBrush = Surface.Brushes.GetBrush(color); } // add border around flow arrow for tie //proxy.FlowPositionPercentage = 0; float rotAngle = 0; RawVector2 ArrowTip = proxy.GetPosition(proxy.FlowPositionPercentage, out rotAngle); float varrotAngle = 0; RawVector2 varArrowTip = proxy.GetPosition(proxy.FlowVarPositionPercentage, out varrotAngle); //var if (MM_Repository.OverallDisplay.VarFlows) { DrawArrow(null, brush, varArrowTip, varrotAngle, varFlowSize, varForward, 0.1f); } // mva DrawArrow(brush, borderBrush, ArrowTip, rotAngle, flowSize, moveForward, 0.25f); }
public static void DrawGraphicsPath(this RenderTarget graph, GraphicsPath path, SharpDX.Direct2D1.Brush brush, float width = 1, StrokeStyle style = null) { for (int i = 0; i < path.PointCount - 1; i++) { if (style != null) { graph.DrawLine(new Vector2(path.PathPoints[i].X, path.PathPoints[i].Y), new Vector2(path.PathPoints[i + 1].X, path.PathPoints[i + 1].Y), brush, width, style); } else { graph.DrawLine(new Vector2(path.PathPoints[i].X, path.PathPoints[i].Y), new Vector2(path.PathPoints[i + 1].X, path.PathPoints[i + 1].Y), brush, width); } } }