private void CreateOrEditNode(IssoPoint2D pt1) { // РЕДАКТИРОВАНИЕ УЗЛА // Сначала найдём ближайший к pt1 компонент и точку на нём - // Если pt1 далека от какого-либо компонента, не делаем ничего // Если эта точка далека от существующего узла компонента, то // Создаём новый узел, разделяя компонент на две части IssoPoint2D pt2; ComponentBasic comp = modelVM.GetComponent(pt1, out pt2); // Если эта точка близка к началу или концу линейного компонента - выбираем начало или конец // Если нет - разбиваем компонент на две части if (comp?.CompType == ComponentTypes.ctLinear) { modelVM.SplitLinearAt((ComponentLinear)comp, pt2); EditedComp = new ComponentNode(pt2); RModel.CompsList.Add(EditedComp); OnComponentSelected?.Invoke(EditedComp, null); } if (comp?.CompType == ComponentTypes.ctNode) { EditedComp = comp; OnComponentSelected?.Invoke(EditedComp, null); } }
private void ChangeLastPoint(IssoPoint2D pt1) { if (EditedComp?.CompType == ComponentTypes.ctLinear) { ((ComponentLinear)EditedComp).End = pt1; } }
public static bool Contains(ComponentLoad load, IssoPoint2D pt, ModelViewSurface surface) { switch (load.CompType) { case ComponentTypes.ctDistributedLoad: { float ArrawHeight = surface.ViewHeight / 30; SKPath b = new SKPath(); b.MoveTo(load.AppNodes[0].Location.X, load.AppNodes[0].Location.Y); b.LineTo(load.AppNodes[0].Location.X, load.AppNodes[0].Location.Y + ArrawHeight); b.LineTo(load.AppNodes[1].Location.X, load.AppNodes[1].Location.Y + ArrawHeight); b.LineTo(load.AppNodes[1].Location.X, load.AppNodes[1].Location.Y); b.Close(); return(b.Contains(pt.X, pt.Y)); } case ComponentTypes.ctForce: { float ArrawHeight = surface.ViewHeight / 15; SKPath b = new SKPath(); b.MoveTo(load.AppNodes[0].Location.X - ArrawHeight / 6, load.AppNodes[0].Location.Y); b.LineTo(load.AppNodes[0].Location.X - ArrawHeight / 6, load.AppNodes[0].Location.Y - ArrawHeight); b.LineTo(load.AppNodes[0].Location.X + ArrawHeight / 6, load.AppNodes[0].Location.Y - ArrawHeight); b.LineTo(load.AppNodes[0].Location.X + ArrawHeight / 6, load.AppNodes[0].Location.Y); b.Close(); SKMatrix rotate = SKMatrix.MakeRotationDegrees(load.Direction + 90, load.AppNodes[0].Location.X, load.AppNodes[0].Location.Y);; b.Transform(rotate); return(b.Contains(pt.X, pt.Y)); } default: return(false); } }
internal void DrawMirrorAxis(List <IssoPoint2D> mirrorAxis, SKCanvas canvas) { SKPaint dashPaint = new SKPaint() { Style = SKPaintStyle.Stroke, Color = Color.AliceBlue.ToSKColor(), PathEffect = SKPathEffect.CreateDash(new Single[2] { surface.ViewHeight / 100, surface.ViewHeight / 100 }, surface.ViewHeight / 80), IsAntialias = true, StrokeWidth = 1 }; SKPoint pt1 = IssoConvert.IssoPoint2DToSkPoint(mirrorAxis[0], surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt2 = IssoConvert.IssoPoint2DToSkPoint(mirrorAxis[1], surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawLine(pt1.X, pt1.Y, pt2.X, pt2.Y, dashPaint); // Рисуем то, как будет выглядеть отражение dashPaint.PathEffect = null; foreach (ComponentLinear c in SelectedBeams) { IssoPoint2D p1 = IssoDist.MirrorPoint(c.Start, mirrorAxis[0], mirrorAxis[1]); IssoPoint2D p2 = IssoDist.MirrorPoint(c.End, mirrorAxis[0], mirrorAxis[1]); pt1 = IssoConvert.IssoPoint2DToSkPoint(p1, surface.ScaleFactor, surface.Origin, surface.ViewHeight); pt2 = IssoConvert.IssoPoint2DToSkPoint(p2, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawLine(pt1.X, pt1.Y, pt2.X, pt2.Y, dashPaint); } }
private void ApplySnap(ComponentLinear linear, IssoPoint2D pt1) { ComponentNode node = modelVM.GetNodeAtPoint(pt1); if (node != null) { linear.End = node.Location; } else { // Используем выравнивание. Если угол близок к 0, 90, 180, 270 и т.п. - выравниваем. float a = IssoBind.OrthoAngle(linear.AngleD); if ((a == 0) || (a == 180)) { linear.EndNode.MoveTo(new IssoPoint2D() { X = pt1.X, Y = linear.Start.Y }); } if ((a == 90) || (a == 270) || (a == -90)) { linear.EndNode.MoveTo(new IssoPoint2D() { Y = pt1.Y, X = linear.Start.X }); } } }
private ComponentNode GetLoadStartNode(IssoPoint2D pt1, ComponentTypes loadType) { // Если пользователь указал узел, то создаём силу, приложенную в этом узле ComponentNode node = modelVM.GetNodeAtPoint(pt1); if ((node == null) || (!modelVM.CloseEnough(pt1, node.Location))) { ComponentBasic lin = modelVM.GetComponent(pt1, out IssoPoint2D pt2); // Если же он указал линейный компонент, то создаём узел в ближайшей точке к указанной // точке компонента, а уже в нём - силу if (lin?.CompType == ComponentTypes.ctLinear) { if (loadType == ComponentTypes.ctForce) { if (lin?.CompType == ComponentTypes.ctLinear) { modelVM.SplitLinearAt((ComponentLinear)lin, pt1); } node = modelVM.GetNodeAtPoint(pt1); } else { node = new ComponentNode(pt2); } } else { node = null; } } return(node); }
private void SelectByFrame(IssoPoint2D pt1, bool over) { if (!SelectionStarted) { SelectionStarted = true; SelectionRect.Left = pt1.X; SelectionRect.Top = pt1.Y; SelectionRect.Right = SelectionRect.Left; SelectionRect.Bottom = SelectionRect.Top; } else { SelectionRect.Right = pt1.X; SelectionRect.Bottom = pt1.Y; } if (over) { if (modelVM.SelectElementsByRect(SelectionRect) > 0) { OnComponentSelected?.Invoke(modelVM.FirstSelectedBeam, null); } SelectionStarted = false; EditorAction = EditorActions.None; CancelAction(); Invalidate(); } ; }
private void CreateNewLinear(IssoPoint2D pt1) { // НОВЫЙ ЛИНЕЙНЫЙ КОМПОНЕНТ // Компонент идёт в паре с двумя узлами. // Первый узел - в точке, указанной пользователем (pt1) // Если в этой точке уже есть другой узел, то берём его как начало элемента // Если тут нет узла - создаём его, и берём как стартовый // Если пользователь указал точку, лежащую на линейном компоненте - создаём в этом месте // узел, разделяя компонент на две части, и берём его как стартовый ComponentNode node = modelVM.GetNodeAtPoint(pt1); if (node == null) { IssoPoint2D pt2; ComponentBasic b = modelVM.GetComponent(pt1, out pt2); if (b?.CompType == ComponentTypes.ctLinear) { modelVM.SplitLinearAt((ComponentLinear)b, pt2); node = modelVM.GetNodeAtPoint(pt2); } node = new ComponentNode(pt1); } pt1.X += 0.1f; EditedComp = new ComponentLinear(node, new ComponentNode(pt1), RModel); EditorAction = EditorActions.NewLinearLastPoint; }
internal void DrawSelectionRect(SKRect selectionRect, SKCanvas canvas) { SKPaint dashPaint = new SKPaint() { Style = SKPaintStyle.Stroke, Color = Color.AliceBlue.ToSKColor(), PathEffect = SKPathEffect.CreateDash(new Single[2] { surface.ViewHeight / 100, surface.ViewHeight / 100 }, surface.ViewHeight / 80), IsAntialias = true, StrokeWidth = 1 }; IssoPoint2D topLeft = new IssoPoint2D() { X = selectionRect.Left, Y = selectionRect.Top }; IssoPoint2D bottomRight = new IssoPoint2D() { X = selectionRect.Right, Y = selectionRect.Bottom }; SKPoint pt1 = IssoConvert.IssoPoint2DToSkPoint(topLeft, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt2 = IssoConvert.IssoPoint2DToSkPoint(bottomRight, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawRect(pt1.X, pt1.Y, pt2.X - pt1.X, pt2.Y - pt1.Y, dashPaint); }
public static bool Contains(ComponentLinear linear, IssoPoint2D pt, ModelViewSurface surface) { SKPath pin = new SKPath(); // Определим начало координат - это всегда точка, расположенная левее IssoPoint2D ptstart, ptend; if (linear.Start.X < linear.End.X) { ptstart = linear.Start; ptend = linear.End; } else { ptstart = linear.End; ptend = linear.Start; } double ang = Math.Asin((ptend.Y - ptstart.Y) / linear.Length); float dy = 7 / surface.scaleFactor; pin.MoveTo(ptstart.X, ptstart.Y - dy); pin.LineTo(ptstart.X, ptstart.Y + dy); pin.LineTo(ptstart.X + linear.Length, ptstart.Y + dy); pin.LineTo(ptstart.X + linear.Length, ptstart.Y - dy); pin.Close(); pin.Transform(SKMatrix.MakeRotation((float)ang, ptstart.X, ptstart.Y)); return(pin.Contains(pt.X, pt.Y)); }
internal static SKPoint IssoPoint2DToSkPoint(IssoPoint2D point, float scaleFactor, IssoPoint2D origin, float yTrans) { return(new SKPoint() { X = (point.X - origin.X) * scaleFactor, Y = (point.Y - origin.Y) * (-scaleFactor) + yTrans }); }
private static bool ContainsH(IssoBinding binding, IssoPoint2D pt, ModelViewSurface surface) { float leftX = Math.Min(binding.Source.Location.X, binding.Target.Location.X); float rightX = Math.Max(binding.Source.Location.X, binding.Target.Location.X); // Прямоугольник вогруг одной из размерных линий SKRect r = new SKRect() { Left = binding.Source.Location.X - 5, Right = binding.Source.Location.X + 5, Top = Math.Min(binding.Source.Location.Y, binding.LinePlace.Y), Bottom = Math.Max(binding.Source.Location.Y, binding.LinePlace.Y) }; if (r.Contains(pt.X, pt.Y)) { return(true); } // Прямоугольник вокруг горизонтальной линии r.Top = binding.LinePlace.Y - 5; r.Bottom = binding.LinePlace.Y + 5; r.Left = leftX - 5; r.Right = rightX + 5; if (r.Contains(pt.X, pt.Y)) { return(true); } // Прямоугольник вогруг второй размерной линии r.Left = binding.Target.Location.X - 5; r.Right = binding.Target.Location.X + 5; r.Top = Math.Min(binding.Target.Location.Y, binding.LinePlace.Y); r.Bottom = Math.Max(binding.Target.Location.Y, binding.LinePlace.Y); if (r.Contains(pt.X, pt.Y)) { return(true); } // Прямоугольник вогруг текста размера float middle = (leftX + rightX) / 2; string dim = binding.Value.ToString("G0"); float tsize = dim.Length * 16; r.Left = middle - tsize / 2 - 5; r.Right = middle + tsize / 2 + 5; r.Top = binding.LinePlace.Y; r.Bottom = binding.LinePlace.Y + 20; if (r.Contains(pt.X, pt.Y)) { return(true); } return(false); }
private void ChangeDimPlace(IssoPoint2D pt1) { // Завершение ввода нового линейного компонента if (EditedComp?.CompType != ComponentTypes.ctBinding) { return; } ((IssoBinding)EditedComp).LinePlace = pt1; }
private static SKMatrix TRMatrix(ComponentLoad load, float scaleFactor, IssoPoint2D origin, float ViewHeight, out SKMatrix rmatrix) { SKPoint point = IssoConvert.IssoPoint2DToSkPoint(load.AppNodes[0].Location, scaleFactor, origin, ViewHeight); SKMatrix matrix = new SKMatrix(); matrix.SetScaleTranslate(1, 1, point.X, point.Y); rmatrix = SKMatrix.MakeRotationDegrees(load.Direction + 90, point.X, point.Y); return(matrix); }
private List <ComponentLinear> ArrayElements() { // Сначала проверим, есть ли возможность хоть что-то нарисовать // Условия: количество элементов больше 1 и шаг больше 0 List <ComponentLinear> newElements = new List <ComponentLinear>(); int hc = 1, vc = 1; float hs = 0, vs = 0; if (arrayHorizontalCount > 0) { hc = arrayHorizontalCount; } if (arrayVerticalCount > 0) { vc = arrayVerticalCount; } if (arrayHorizontalStep != 0) { hs = arrayHorizontalStep; } if (arrayVerticalStep != 0) { vs = arrayVerticalStep; } for (int h = 0; h < hc; h++) { for (int v = 0; v < vc; v++) { // Элемент с индексом 0, 0 пропускаем - поскольку он уже создан if (h + v == 0) { continue; } foreach (ComponentLinear c in SelectedBeams) { IssoPoint2D point1 = c.Start; point1.X += h * hs; point1.Y += v * vs; IssoPoint2D point2 = c.End; point2.X += h * hs; point2.Y += v * vs; ComponentNode nd1 = new ComponentNode(point1); ComponentNode nd2 = new ComponentNode(point2); newElements.Add(new ComponentLinear(nd1, nd2, model)); } } } return(newElements); }
private void DimensionLinePlace(IssoPoint2D pt1) { // Завершение ввода нового линейного компонента if (EditedComp?.CompType != ComponentTypes.ctBinding) { return; } ((IssoBinding)EditedComp).LinePlace = pt1; RModel.EnableChangeTracking(); RModel.CompsList.Add(EditedComp); RModel.DisableChangeTracking(); EditorAction = EditorActions.None; }
internal void SplitLinearAt(ComponentLinear l, IssoPoint2D pt2) { if (CloseEnough(pt2, l.Start) || CloseEnough(pt2, l.End)) { return; } ComponentLinear lin = l.SplitAt(pt2); model.EnableChangeTracking(); model.CompsList.Add(lin.StartNode); model.CompsList.Add(lin); model.DisableChangeTracking(); }
private void ChangeDstLoadEnd(IssoPoint2D pt1) { if (EditedComp?.CompType == ComponentTypes.ctDistributedLoad) { // Определяем, какому линейному компоненту принадлежит начальный узел нагрузки ComponentLoad load = (ComponentLoad)EditedComp; ComponentLinear lin = (ComponentLinear)modelVM.GetComponent(pt1, out IssoPoint2D pt2, ComponentTypes.ctLinear); if (lin != null) { load.SetLastNodeAt(pt2); } } }
public float NodeDist(IssoPoint2D pt, ComponentNode node) { // Если точка pt лежит внутри области узла, возвращаем ноль - иначе // возвразаем расстояние от pt до Node.Location if (ComponentNodeVM.Contains(node, pt, surface)) { return(0f); } else { return(IssoDist.PointDst(pt, node.Location)); } }
private void CopyElements(IssoPoint2D pt1, bool copyBasePointDefined) { // Если базовая точка не задана, то первым делом её задаём if (!copyBasePointDefined) { CopyBasePoint = pt1; CopyBasePointDefined = true; } else { modelVM.CreateCopy(CopyBasePoint, pt1); //CopyBasePointDefined = false; } }
private ComponentNode MirrorNode(IssoPoint2D point, List <ComponentBasic> newElements) { IssoPoint2D pt = IssoDist.MirrorPoint(point, surface.MirrorAxis[0], surface.MirrorAxis[1]); IssoPoint2D ptout; ComponentNode nd = (ComponentNode)GetComponent(pt, out ptout, ComponentTypes.ctNode); if (nd == null) { nd = new ComponentNode(pt); newElements.Add(nd); } return(nd); }
private void FinishNewLinear(IssoPoint2D pt1, SKMouseButton MouseButton) { // Завершение ввода нового линейного компонента if (EditedComp?.CompType != ComponentTypes.ctLinear) { return; } ((ComponentLinear)EditedComp).End = pt1; ApplySnap((ComponentLinear)EditedComp, pt1); AddNewLinear(); // Тут же начинаем новый элемент CreateNewLinear(((ComponentLinear)EditedComp).End); }
public static bool Contains(ComponentNode node, IssoPoint2D pt, ModelViewSurface surface) { SKPath pin; // Проверяем, находится ли указанная точка внутри области отображения узла //if ((node.Type == NodeType.Rigid) || (node.Type == NodeType.Hinge)) pin = Rigid(); // else pin = SupportBounds(); SKMatrix rotate; SKPoint skp = IssoConvert.IssoPoint2DToSkPoint(pt, surface.ScaleFactor, surface.Origin, surface.ViewHeight); pin.Transform(TRMatrix(node, surface, out rotate)); pin.Transform(rotate); return(pin.Contains(skp.X, skp.Y)); }
private void DimensionLastNode(IssoPoint2D pt1) { // Завершение ввода нового линейного компонента if (EditedComp?.CompType != ComponentTypes.ctBinding) { return; } ComponentNode node = modelVM.GetNodeAtPoint(pt1); if (node != null) { ((IssoBinding)EditedComp).Target = node; EditorAction = EditorActions.NewDimensionLinePlace; } }
internal ComponentLinear GetLinear(IssoPoint2D p1, IssoPoint2D p2) { // Возвращаем линейный компонент, которому принадлежат обе точки p1 и p2 for (int i = 0; i < model.CompsList.Count; i++) { if (model.CompsList[i].CompType == ComponentTypes.ctLinear) { ComponentLinear lin = (ComponentLinear)model.CompsList[i]; if (IssoDist.PointsOnLine(new IssoPoint2D[] { p1, p2 }, new IssoPoint2D[] { lin.Start, lin.End })) { return(lin); } } } return(null); }
public static bool Contains(IssoBinding binding, IssoPoint2D pt, ModelViewSurface surface) { if (binding.Target == null) { return(false); } switch (binding.Type) { case IssoBindingType.Horizontal: return(ContainsH(binding, pt, surface)); case IssoBindingType.Vertical: return(ContainsV(binding, pt, surface)); default: return(false); } }
private void CreateForce(IssoPoint2D pt1) { ComponentNode node = GetLoadStartNode(pt1, ComponentTypes.ctForce); if (node != null) { ComponentLoad load = new ComponentLoad(ComponentTypes.ctForce, -100, node); RModel.EnableChangeTracking(); RModel.CompsList.Add(load); RModel.DisableChangeTracking(); EditedComp = load; } else { EditedComp = null; } }
public IssoPoint2D Snap(IssoPoint2D pt) { IssoPoint2D res = new IssoPoint2D(); res.X = ScaledStep * (float)Math.Truncate(pt.X / ScaledStep); res.Y = ScaledStep * (float)Math.Truncate(pt.Y / ScaledStep); if ((pt.X - res.X) > (ScaledStep / 2)) { res.X += ScaledStep; } if ((pt.Y - res.Y) > (ScaledStep / 2)) { res.Y += ScaledStep; } return(res); }
private void CreateDistLoad(IssoPoint2D pt1) { //ComponentNode node = GetLoadStartNode(pt1, ComponentTypes.ctDistributedLoad); IssoPoint2D pt2; ComponentBasic c = modelVM.GetComponent(pt1, out pt2, ComponentTypes.ctLinear); if (c != null) { ComponentLoad load = new ComponentLoad(ComponentTypes.ctDistributedLoad, -10, (ComponentLinear)c); RModel.CompsList.Add(load); EditedComp = load; EditorAction = EditorActions.None; Invalidate(); } else { EditedComp = null; } }
private void DimensionFirstNode(IssoPoint2D pt1) { // Первый узел - начало линейного размера ComponentNode node = modelVM.GetNodeAtPoint(pt1); if (node != null) { IssoBindingType t = IssoBindingType.Horizontal; switch (EditorAction) { case EditorActions.NewDimensionFirstNode: t = IssoBindingType.Horizontal; break; case EditorActions.NewDimensionVFirstNode: t = IssoBindingType.Vertical; break; } IssoBinding bin = new IssoBinding(t, node, null, 0); EditedComp = bin; EditorAction = EditorActions.NewDimensionLastNode; } }