146 lines
5.4 KiB
C#
146 lines
5.4 KiB
C#
///
|
|
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace SchematicDrawing
|
|
{
|
|
public class Pipe
|
|
{
|
|
public IDrawingItem StartItem;
|
|
public int StartNodeId;
|
|
public IDrawingItem EndItem;
|
|
public int EndNodeId;
|
|
public Sz Sz;
|
|
|
|
public bool CoordinatesAreValid;
|
|
public int x1, y1, x2, y2;
|
|
public bool HasIntersection;
|
|
public float P;
|
|
|
|
|
|
public Pipe(IDrawingItem startItem, int startNodeId, IDrawingItem endItem, int endNodeId, Sz sz)
|
|
{
|
|
StartItem = startItem;
|
|
StartNodeId = startNodeId;
|
|
EndItem = endItem;
|
|
EndNodeId = endNodeId;
|
|
Sz = sz;
|
|
CoordinatesAreValid = false;
|
|
HasIntersection = false;
|
|
}
|
|
|
|
public Pipe(string pipeStr, Sz sz, Dictionary<string, IDrawingItem> name2Item)
|
|
{
|
|
String2Items(pipeStr, name2Item, out StartItem, out StartNodeId, out EndItem, out EndNodeId);
|
|
Sz = sz;
|
|
CoordinatesAreValid = false;
|
|
HasIntersection = false;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return (StartItem != null && EndItem != null) ? string.Format("{0}~{1}~{2}~{3}", StartItem.Name, StartNodeId, EndItem.Name, EndNodeId) : string.Empty;
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Calculates coordinates of the start- and the end-point
|
|
/// </summary>
|
|
/// <param name="x1">Start point X</param>
|
|
/// <param name="y1">Start point Y</param>
|
|
/// <param name="x2">End point X</param>
|
|
/// <param name="y2">End point Y</param>
|
|
/// <returns>true when calculation successful</returns>
|
|
public bool GetCoordinates()
|
|
{
|
|
DrawingShape startDShape = DrawingShape.GetDrawingShape(StartItem);
|
|
DrawingShape endDShape = DrawingShape.GetDrawingShape(EndItem);
|
|
|
|
if (StartItem != null && EndItem != null && startDShape != null && endDShape != null)
|
|
{
|
|
Node startNode = startDShape.GetRotatedFlippedNode(StartItem, StartNodeId);
|
|
Node endNode = endDShape.GetRotatedFlippedNode(EndItem, EndNodeId);
|
|
|
|
x1 = StartItem.X + startNode.X * Const.GridSize;
|
|
y1 = StartItem.Y + startNode.Y * Const.GridSize;
|
|
x2 = EndItem.X + endNode.X * Const.GridSize;
|
|
y2 = EndItem.Y + endNode.Y * Const.GridSize;
|
|
CoordinatesAreValid = true;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts pipe string to start and end items
|
|
/// </summary>
|
|
/// <param name="pipeStr">Edge string</param>
|
|
/// <param name="name2Item">Dictionary of items</param>
|
|
/// <param name="startItem">Start item</param>
|
|
/// <param name="endItem">End item</param>
|
|
/// <returns>true when conversion successful</returns>
|
|
public static bool String2Items(string pipeStr, Dictionary<string, IDrawingItem> name2Item, out IDrawingItem startItem, out int startNid, out IDrawingItem endItem, out int endNid)
|
|
{
|
|
string[] fields = pipeStr.Split(new char[] { '~' });
|
|
|
|
IDrawingItem start, end;
|
|
DrawingShape dshapeFrom, dshapeTo;
|
|
if (fields.Length == 4 && name2Item.TryGetValue(fields[0], out start)
|
|
&& (null != (dshapeFrom = DrawingShape.Shapes[DrawingShape.DrShIx(start.Shape, start.Sz)]))
|
|
&& int.TryParse(fields[1], out startNid) && (startNid >= 0) && (startNid < dshapeFrom.Nodes.Length)
|
|
&& name2Item.TryGetValue(fields[2], out end)
|
|
&& (null != (dshapeTo = DrawingShape.Shapes[DrawingShape.DrShIx(end.Shape, end.Sz)]))
|
|
&& int.TryParse(fields[3], out endNid) && (endNid >= 0) && (endNid < dshapeTo.Nodes.Length))
|
|
{
|
|
startItem = start;
|
|
endItem = end;
|
|
return true;
|
|
}
|
|
|
|
startItem = null;
|
|
endItem = null;
|
|
startNid = 0;
|
|
endNid = 0;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true when two pipes have an intersection
|
|
/// </summary>
|
|
/// <param name="pipe2">Second pipe</param>
|
|
/// <returns>true when ipes intersect</returns>
|
|
public bool CalculateIntersectionWith(Pipe pipe2)
|
|
{
|
|
if (!this.CoordinatesAreValid) GetCoordinates();
|
|
if (!pipe2.CoordinatesAreValid) pipe2.GetCoordinates();
|
|
|
|
int D = (x2 - x1) * (pipe2.y2 - pipe2.y1) - (y2 - y1) * (pipe2.x2 - pipe2.x1);
|
|
float Dp = Convert.ToSingle((pipe2.x1 - x1) * (pipe2.y2 - pipe2.y1) - (pipe2.y1 - y1) * (pipe2.x2 - pipe2.x1));
|
|
float Dq = Convert.ToSingle((x2 - x1) * (pipe2.y1 - y1) - (y2 - y1) * (pipe2.x1 - x1));
|
|
|
|
if (D == 0)
|
|
{
|
|
return false; /// Parallel pipes -> no intersection
|
|
}
|
|
|
|
float Df = Convert.ToSingle(D);
|
|
float p = Dp / Df;
|
|
float q = -Dq / Df;
|
|
if (p > 0.01 && p < 0.99 && q > 0.01 && q < 0.99)
|
|
{
|
|
this.HasIntersection = true;
|
|
this.P = p;
|
|
return true; /// Pipes intersect, pipes touching by their ends are not considered
|
|
}
|
|
|
|
return false; /// Pipes do not intersect
|
|
}
|
|
}
|
|
}
|