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); } }
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)); }
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 static void DrawRollerSupport(ComponentNode c, ModelViewSurface surface, SKCanvas canvas, bool isInt) { SKPath roller = DefaultRoller(); SKMatrix rotate; roller.Transform(TRMatrix(c, surface, out rotate)); roller.Transform(rotate); canvas.DrawPath(roller, GetPaint(c)); }
private static void DrawPinSupport(ComponentNode c, ModelViewSurface surface, SKCanvas canvas, bool isInt) { SKPath pin = DefaultPin(); SKMatrix rotate; pin.Transform(TRMatrix(c, surface, out rotate)); pin.Transform(rotate); canvas.DrawPath(pin, GetPaint(c)); }
public static void Draw(ComponentLoad load, ModelViewSurface surface, SKCanvas canvas) { switch (load.Type) { case ComponentTypes.ctDistributedLoad: DrawDistributed(load, surface, canvas); break; case ComponentTypes.ctForce: DrawConcentrated(load, surface, canvas); break; case ComponentTypes.ctMoment: DrawMoment(load, surface, canvas); break; } }
public static void DrawNode(ComponentNode node, ModelViewSurface surface, SKCanvas canvas) { SKPath p1 = Rigid(); SKPath p = new SKPath(); /* switch (node.Type) * { * case NodeType.Hinge: p = Hinge(); break; * case NodeType.Rigid: p = Rigid(); break; * case NodeType.Pin2d: DrawPinSupport(node, surface, canvas, false); return; * case NodeType.Roller2d: DrawRollerSupport(node, surface, canvas, false); return; * default: p = Point(); break; * } */ if (node.DisallowedDisplacements.Contains(NodeDisplacement.X)) { AddX(p); } if (node.DisallowedDisplacements.Contains(NodeDisplacement.Y)) { AddY(p); } if (node.DisallowedDisplacements.Contains(NodeDisplacement.Rotation)) { AddR(p); } float scale = surface.ViewHeight / 80; SKPoint location = IssoConvert.IssoPoint2DToSkPoint(node.Location, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKMatrix matrix = new SKMatrix(); matrix.SetScaleTranslate(scale, scale, location.X, location.Y); p.Transform(matrix); p1.Transform(matrix); SKPaint paint = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = Color.Aquamarine.ToSKColor(), IsAntialias = true, StrokeWidth = 1 }; // Если компонент выбран, рисуем его пожирнее if (node.CompState == ComponentState.csEdited) { paint.StrokeWidth += 1; } canvas.DrawPath(p1, paint); paint.Style = SKPaintStyle.Stroke; canvas.DrawPath(p, paint); }
private static void DrawDistributed(ComponentLoad load, ModelViewSurface surface, SKCanvas canvas) { SKPaint paint = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = Color.Red.ToSKColor(), IsAntialias = true, StrokeWidth = 1 }; SKPath dc = GetEquallyDistributed(load, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawPath(dc, paint); }
private static SKMatrix TRMatrix(ComponentNode c, ModelViewSurface surface, out SKMatrix rmatrix) { float scale = surface.ViewHeight / 80; SKPoint location = IssoConvert.IssoPoint2DToSkPoint(c.Location, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKMatrix matrix = new SKMatrix(); matrix.SetScaleTranslate(scale, scale, location.X, location.Y); //rmatrix = SKMatrix.MakeRotationDegrees(c.Angle - 90, location.X, location.Y); rmatrix = SKMatrix.MakeRotationDegrees(0, location.X, location.Y); return(matrix); }
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)); }
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 static void DrawConcentrated(ComponentLoad load, ModelViewSurface surface, SKCanvas canvas) { SKPaint paint = new SKPaint { Style = SKPaintStyle.StrokeAndFill, Color = Color.PaleVioletRed.ToSKColor(), IsAntialias = true, StrokeWidth = 1 }; SKPath dc = GetConcentrated(load, surface.ViewHeight); dc.Transform(SKMatrix.MakeRotationDegrees(-load.Direction)); SKPoint pt = IssoConvert.IssoPoint2DToSkPoint(load.AppNodes[0].Location, surface.ScaleFactor, surface.Origin, surface.ViewHeight); dc.Transform(SKMatrix.MakeTranslation(pt.X, pt.Y)); canvas.DrawPath(dc, paint); }
public static void Draw(ComponentLinear linear, ModelViewSurface surface, SKCanvas canvas) { SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.WhiteSmoke.ToSKColor(), IsAntialias = true, StrokeWidth = 2 }; if (linear.CompState == ComponentState.csSelected) { paint.StrokeWidth += 3; paint.Color = Color.CornflowerBlue.ToSKColor(); } SKPoint pt1 = IssoConvert.IssoPoint2DToSkPoint(linear.Start, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt2 = IssoConvert.IssoPoint2DToSkPoint(linear.End, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawLine(pt1, pt2, paint); SKPaint fillPaint = new SKPaint() { Style = SKPaintStyle.Fill, Color = Color.Black.ToSKColor(), IsAntialias = true }; float hr = surface.ViewHeight / 110; double a = Math.Atan2(pt2.Y - pt1.Y, pt2.X - pt1.X); if (linear.HingeStart) { canvas.DrawCircle(pt1.X + hr * (float)Math.Cos(a), pt1.Y + hr * (float)Math.Sin(a), hr, fillPaint); canvas.DrawCircle(pt1.X + hr * (float)Math.Cos(a), pt1.Y + hr * (float)Math.Sin(a), hr, paint); } if (linear.HingeEnd) { canvas.DrawCircle(pt2.X + hr * (float)Math.Cos(a + Math.PI), pt2.Y + hr * (float)Math.Sin(a + Math.PI), hr, fillPaint); canvas.DrawCircle(pt2.X + hr * (float)Math.Cos(a + Math.PI), pt2.Y + hr * (float)Math.Sin(a + Math.PI), hr, paint); } }
public void DrawSnapLines(ModelViewSurface surface, SKCanvas canvas) { SKPaint dashPaint = new SKPaint() { Style = SKPaintStyle.Stroke, Color = Color.GreenYellow.ToSKColor(), PathEffect = SKPathEffect.CreateDash(new Single[2] { surface.ViewHeight / 100, surface.ViewHeight / 100 }, surface.ViewHeight / 80), IsAntialias = true, StrokeWidth = 1 }; if (SnapPoint.X != float.MinValue) { SKPoint pt = IssoConvert.IssoPoint2DToSkPoint(SnapPoint, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawLine(pt.X, 0, pt.X, surface.ViewHeight, dashPaint); } if (SnapPoint.Y != float.MinValue) { SKPoint pt = IssoConvert.IssoPoint2DToSkPoint(SnapPoint, surface.ScaleFactor, surface.Origin, surface.ViewHeight); canvas.DrawLine(0, pt.Y, surface.ViewWidth, pt.Y, dashPaint); } }
internal void DrawDeformedShape(ModelViewSurface modelViewSurface, SKCanvas canvas) { double maxd = 0; for (int i = 0; i < model.Rods.Count; i++) { // Для того, чтобы подобрать подходящий масштаб, сначала определим макисмальное линейное перемещение // (т.е. без учёта углов поворота) for (float x = 0; x < model.Rods[i].Length; x += (float)model.Rods[i].Length / 10f) { double[] d = model.Rods[i].DeformedShape(x); if (maxd <= Math.Abs(d[0])) { maxd = Math.Abs(d[0]); } if (maxd <= Math.Abs(d[1])) { maxd = Math.Abs(d[1]); } } } // Чтобы деформированный вид выглядел информативно, нужно, чтобы максимальное перемещение // составляло примерно 10% от высоты окна просмотра в пикселях float deformedScale = 1.0f; if (maxd > 0) { deformedScale = modelViewSurface.ViewHeight * 0.1f / (float)maxd / modelViewSurface.ScaleFactor; } SKPath deformed = new SKPath(); for (int i = 0; i < model.Rods.Count; i++) { float elementLength = (float)model.Rods[i].Length; float dx = elementLength / 98; // Разбиваем длину элемента на 98 частей // Это гарантирует нам 99 точек по длине элемента - что нужно для // отображения деформированного вида с помощью кубических кривых for (float x = 0; x < elementLength; x += 3 * dx) { double[] xyF1 = model.Rods[i].DeformedShapeGlobalXY(x, deformedScale); double[] xyF2 = model.Rods[i].DeformedShapeGlobalXY(x + dx, deformedScale); double[] xyF3 = model.Rods[i].DeformedShapeGlobalXY(x + 2 * dx, deformedScale); SKPoint pt1 = IssoConvert.IssoPoint2DToSkPoint(new IssoPoint2D() { X = (float)xyF1[0], Y = (float)xyF1[1] }, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt2 = IssoConvert.IssoPoint2DToSkPoint(new IssoPoint2D() { X = (float)xyF2[0], Y = (float)xyF2[1] }, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt3 = IssoConvert.IssoPoint2DToSkPoint(new IssoPoint2D() { X = (float)xyF3[0], Y = (float)xyF3[1] }, surface.ScaleFactor, surface.Origin, surface.ViewHeight); if (x == 0) { deformed.MoveTo(pt1); } deformed.CubicTo(pt1, pt2, pt3); } } for (int i = 0; i < model.Displacements.Length; i += 3) { float x = model.Nodes[(int)i / 3].Location.X; float y = model.Nodes[(int)i / 3].Location.Y; SKPoint node = IssoConvert.IssoPoint2DToSkPoint(new IssoPoint2D() { X = x + (float)model.Displacements[i] * deformedScale, Y = y + (float)model.Displacements[i + 1] * deformedScale }, surface.ScaleFactor, surface.Origin, surface.ViewHeight); deformed.AddCircle(node.X, node.Y, 5); } SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.Goldenrod.ToSKColor(), IsAntialias = true, StrokeWidth = 3 }; canvas.DrawPath(deformed, paint); }
public RodModelVM(RodModel model, SKCanvasView surface) { this.model = model; this.surface = new ModelViewSurface(this, surface); }
// Линейный размер состоит из двух размерных линий, начинающихся у узлов // Горизонтальной (или вертикальной) линии public static void DrawDimension(IssoBinding bin, ModelViewSurface surface, SKCanvas canvas) { SKPath dim = new SKPath(); SKPoint pt1 = IssoConvert.IssoPoint2DToSkPoint(((ComponentNode)bin.Source).Location, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint pt2; SKPoint lp = IssoConvert.IssoPoint2DToSkPoint(bin.LinePlace, surface.ScaleFactor, surface.Origin, surface.ViewHeight); SKPoint vLp = new SKPoint() { X = lp.X, Y = lp.Y }; SKPoint vpt1 = new SKPoint() { X = pt1.X, Y = pt1.Y }; if (bin.Target != null) { pt2 = IssoConvert.IssoPoint2DToSkPoint(((ComponentNode)bin.Target).Location, surface.ScaleFactor, surface.Origin, surface.ViewHeight); } else { pt2 = new SKPoint() { X = lp.X, Y = lp.Y }; } SKPoint vpt2 = new SKPoint() { X = pt2.X, Y = pt2.Y }; // Если размер - вертикальный, то сначала повернём все точки, чтобы рисовать его также, как и горизонтальный, // а затем развернём его снова if (bin.Type == IssoBindingType.Vertical) { SKPath ptPath = new SKPath(); ptPath.AddPoly(new SKPoint[] { pt1, pt2, lp }, false); SKMatrix rmatrix = SKMatrix.MakeRotationDegrees(90, pt1.X, pt1.Y); ptPath.Transform(rmatrix); pt1 = ptPath.GetPoint(0); pt2 = ptPath.GetPoint(1); lp = ptPath.GetPoint(2); } float f1 = Math.Sign(lp.Y - pt1.Y); float f2 = Math.Sign(lp.Y - pt2.Y); // Одна размерная линия dim.MoveTo(pt1.X, pt1.Y + f1 * 5); dim.LineTo(pt1.X, lp.Y + f1 * 5); // Вторая размерная линия dim.MoveTo(pt2.X, pt2.Y + f2 * 5); dim.LineTo(pt2.X, lp.Y + f2 * 5); // Горизонтальная линия dim.MoveTo(pt1.X, lp.Y); dim.LineTo(pt2.X, lp.Y); // Одна стрелка float a = Math.Sign(pt2.X - pt1.X); dim.MoveTo(pt1.X, lp.Y); dim.LineTo(pt1.X + a * 5, lp.Y + 3); dim.MoveTo(pt1.X, lp.Y); dim.LineTo(pt1.X + a * 5, lp.Y - 3); // Вторая стрелка dim.MoveTo(pt2.X, lp.Y); dim.MoveTo(pt2.X, lp.Y); dim.LineTo(pt2.X - a * 5, lp.Y + 3); dim.MoveTo(pt2.X, lp.Y); dim.LineTo(pt2.X - a * 5, lp.Y - 3); SKPaint paint = new SKPaint { Style = SKPaintStyle.Stroke, Color = Color.AliceBlue.ToSKColor(), IsAntialias = true, StrokeWidth = 1, TextAlign = SKTextAlign.Center, TextSize = 16 }; // Текcт размера string ds = (bin.Value * surface.ScaleFactor).ToString("#.00"); if (bin.Type == IssoBindingType.Vertical) { SKMatrix rmatrix = SKMatrix.MakeRotationDegrees(-90, pt1.X, pt1.Y); dim.Transform(rmatrix); SKRect bounds = new SKRect(); paint.MeasureText(ds, ref bounds); SKBitmap bmp = new SKBitmap((int)(Math.Max(bounds.Width, bounds.Height)), (int)(Math.Max(bounds.Width, bounds.Height))); SKCanvas k = new SKCanvas(bmp); k.RotateDegrees(-90, bmp.Width / 2, bmp.Height / 2); k.DrawText(ds, bmp.Width / 2, bounds.Height, paint); canvas.DrawBitmap(bmp, vLp.X - 10 - bounds.Height, (vpt1.Y + vpt2.Y) / 2, paint); } else { canvas.DrawText(ds, (pt1.X + pt2.X) / 2, lp.Y - 10, paint); } canvas.DrawPath(dim, paint); }
private static void DrawMoment(ComponentLoad load, ModelViewSurface surface, SKCanvas canvas) { // }