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;
     }
 }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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;
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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;
 }
Exemple #14
0
        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);
        }
Exemple #15
0
        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;
 }
Exemple #17
0
        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);
         }
     }
 }
Exemple #19
0
 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;
     }
 }
Exemple #21
0
        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;
            }
        }
Exemple #25
0
 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;
            }
        }
Exemple #28
0
        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;
            }
        }