public PathFigure LinearPath(int index, TimeSortedList JointParameters, JointData jData, double offsetX, double offsetY) { var start = new System.Windows.Point(JointParameters[0].Value[index, 0] + offsetX, JointParameters[0].Value[index, 1] + offsetY); var points = new PointCollection(); for (int i = 1; i < JointParameters.Count; i++) { var x = JointParameters[i].Value[index, 0] + offsetX; var y = JointParameters[i].Value[index, 1] + offsetY; points.Add(new System.Windows.Point(x, y)); } #region see if path should be closed //var last_i = JointParameters.Count - 1; ////find a good time step value. //var timeStepLast = JointParameters.Times[last_i] - JointParameters.Times[last_i - 1]; //timeStepLast += JointParameters.Times[1] - JointParameters.Times[0]; //timeStepLast /= 2; //var xLast = JointParameters[last_i].Value[index, 2] * timeStepLast + // JointParameters[last_i].Value[index, 4] * timeStepLast * timeStepLast / 2; //var yLast = JointParameters[last_i].Value[index, 3] * timeStepLast + // JointParameters[last_i].Value[index, 5] * timeStepLast * timeStepLast / 2; //var closePath = (Math.Abs(xLast - start.X) + Math.Abs(yLast - start.Y) < 100 * Constants.epsilon); #endregion return(new PathFigure { StartPoint = start, Segments = new PathSegmentCollection { new PolyLineSegment { Points = points } }, IsClosed = _isClosed }); }
public InputRPJointShape(double jointSize, double strokeThickness, double xPosition, double yPosition, double xAxisOffset, double yAxisOffset, double angle, bool isGround, int jointNum, JointData jointData) : base(2 * jointSize, 2 * jointSize, strokeThickness, xPosition, yPosition, xAxisOffset, yAxisOffset, angle, "PMoveArrows", "PRotateArrows", jointData) { jointShape = new Ellipse { Width = 2 * jointSize, Height = 2 * jointSize, Fill = new SolidColorBrush(Colors.Transparent), Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = strokeThickness, RenderTransformOrigin = new Point(0.5, 0.5), RenderTransform = new TranslateTransform { X = -jointSize, Y = -jointSize } }; Children.Add(jointShape); }
internal void ParseData(Boolean ForceRerunOfSimulation = false) { try { #region table validation if (JointsInfo == null) { return; } numJoints = TrimEmptyJoints(); if (pmks != null && !ForceRerunOfSimulation && SameTopology() && SameParameters()) { return; } DefineInputDriver(); DefineLinkIDs(); if (!(GroundLinkFound() && DuplicateLinkNames() && DefinePositions() && DefineJointTypeList() && DataListsSameLength())) { return; } pmks = new Simulator(LinkIDs, JointTypes, drivingIndex, InitPositions); JointData.UpdateRandomRange(InitPositions); mainViewer.ClearDynamicShapesAndBindings(); PlayButton_Unchecked(null, null); if (pmks.IsDyadic) { status("The mechanism is comprised of only of dyads."); } else { status("The mechanism has non-dyadic loops."); } int dof = pmks.DegreesOfFreedom; App.main.fileAndEditPanel.ReportDOF(dof); status("Degrees of freedom = " + dof); if (dof == 1) { if (JointsInfo.Data[drivingIndex].JointTypeString.Equals("P", StringComparison.InvariantCultureIgnoreCase)) { pmks.InputSpeed = Speed; globalSettings.SpeedHeaderTextBlock.Text = "Speed (unit/sec)"; if (AnalysisStep == AnalysisType.error) { pmks.MaxSmoothingError = Error; } else { pmks.DeltaAngle = AngleIncrement; } } else { pmks.InputSpeed = DisplayConstants.RadiansPerSecToRPM * Speed; globalSettings.SpeedHeaderTextBlock.Text = "Speed (rpm)"; if (AnalysisStep == AnalysisType.error) { pmks.MaxSmoothingError = Error; } else { pmks.DeltaAngle = AngleIncrement / DisplayConstants.RadiansToDegrees; } } } else { mainViewer.UpdateRanges(InitPositions); mainViewer.UpdateScaleAndCenter(); mainViewer.DrawStaticShapes(pmks, JointsInfo.Data); return; } } catch (Exception e) { status("Incomplete or incorrect data: \n" + e.InnerException); return; } #endregion try { #region Simulation of mechanism status("Analyzing..."); var now = DateTime.Now; pmks.FindFullMovement(); status("...done (" + (DateTime.Now - now).TotalMilliseconds.ToString() + "ms)."); switch (pmks.CycleType) { case CycleTypes.LessThanFullCycle: status("Input cannot rotate a full 360 degrees."); break; case CycleTypes.OneCycle: status("Mechanism is completely cyclic with input."); break; case CycleTypes.MoreThanOneCycle: status( "Input rotates a full 360 degrees but motion is not yet cyclic (more rotations are required)."); break; } #endregion #region draw curves status("Drawing..."); now = DateTime.Now; if (pmks.LinkParameters == null || pmks.JointParameters == null || pmks.JointParameters.Count < 2) { status("The mechanism does not move."); // return; } mainViewer.UpdateRanges(pmks); mainViewer.FindVelocityAndAccelerationScalers(pmks); mainViewer.UpdateScaleAndCenter(); mainViewer.DrawStaticShapes(pmks, JointsInfo.Data); mainViewer.DrawDynamicShapes(pmks, JointsInfo.Data, timeSlider); status("...done (" + (DateTime.Now - now).TotalMilliseconds + "ms)."); PlayButton_Checked(null, null); #endregion } catch (Exception e) { status(e.Message); } }
public PathFigure QuadraticPath(int index, TimeSortedList JointParameters, JointData jData, double offsetX, double offsetY) { var start = new System.Windows.Point(JointParameters[0].Value[index, 0] + offsetX, JointParameters[0].Value[index, 1] + offsetY); var points = new PointCollection(); for (int i = 1; i < JointParameters.Count; i++) { var x1 = JointParameters[i - 1].Value[index, 0] + offsetX; var y1 = JointParameters[i - 1].Value[index, 1] + offsetY; var v_1x = JointParameters[i - 1].Value[index, 2]; var v_1y = JointParameters[i - 1].Value[index, 3]; var x2 = JointParameters[i].Value[index, 0] + offsetX; var y2 = JointParameters[i].Value[index, 1] + offsetY; var v_2x = JointParameters[i].Value[index, 2]; var v_2y = JointParameters[i].Value[index, 3]; var interPt = Constants.solveViaIntersectingLines(v_1y / v_1x, new Point(x1, y1), v_2y / v_2x, new Point(x2, y2)); if (double.IsNaN(interPt.X) || double.IsNaN(interPt.Y)) { points.Add(new System.Windows.Point((x1 + x2) / 2, (y1 + y2) / 2)); } else { points.Add(new System.Windows.Point(interPt.X, interPt.Y)); } points.Add(new System.Windows.Point(x2, y2)); } if (_isClosed) { var x1 = JointParameters[JointParameters.LastIndex].Value[index, 0] + offsetX; var y1 = JointParameters[JointParameters.LastIndex].Value[index, 1] + offsetY; var v_1x = JointParameters[JointParameters.LastIndex].Value[index, 2]; var v_1y = JointParameters[JointParameters.LastIndex].Value[index, 3]; var x2 = JointParameters[0].Value[index, 0] + offsetX; var y2 = JointParameters[0].Value[index, 1] + offsetY; var v_2x = JointParameters[0].Value[index, 2]; var v_2y = JointParameters[0].Value[index, 3]; var interPt = Constants.solveViaIntersectingLines(v_1y / v_1x, new Point(x1, y1), v_2y / v_2x, new Point(x2, y2)); if (double.IsNaN(interPt.X) || double.IsNaN(interPt.Y)) { points.Add(new System.Windows.Point((x1 + x2) / 2, (y1 + y2) / 2)); } else { points.Add(new System.Windows.Point(interPt.X, interPt.Y)); } points.Add(new System.Windows.Point(x2, y2)); } #region see if path should be closed //var last_i = JointParameters.Count - 1; ////find a good time step value. //var timeStepLast = JointParameters.Times[last_i] - JointParameters.Times[last_i - 1]; //timeStepLast += JointParameters.Times[1] - JointParameters.Times[0]; //timeStepLast /= 2; //var xLast = JointParameters[last_i].Value[index, 2] * timeStepLast + // JointParameters[last_i].Value[index, 4] * timeStepLast * timeStepLast / 2; //var yLast = JointParameters[last_i].Value[index, 3] * timeStepLast + // JointParameters[last_i].Value[index, 5] * timeStepLast * timeStepLast / 2; //var closePath = (Math.Abs(xLast - start.X) + Math.Abs(yLast - start.Y) < 100 * Constants.epsilon); #endregion return(new PathFigure { StartPoint = start, Segments = new PathSegmentCollection { new PolyQuadraticBezierSegment { Points = points } }, IsClosed = _isClosed }); }
public InputRJointShape(double radius, double strokeThickness, double xPosition, double yPosition, double xAxisOffset, double yAxisOffset, bool isGround, bool isDriver, int jointNum, JointData jointData) : base(2 * radius, 2 * radius, strokeThickness, xPosition, yPosition, xAxisOffset, yAxisOffset, 0, "MoveArrows", "", jointData) { /* now draw the actual joint */ var fillBrush = /*isGround ? new SolidColorBrush(Colors.Black) :*/ new SolidColorBrush(Colors.Transparent); jointShape = new Ellipse { Width = 2 * radius, Height = 2 * radius, Stroke = (isDriver) ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Black), StrokeThickness = (isDriver) ? 3 * strokeThickness : strokeThickness, Fill = fillBrush, RenderTransform = new TranslateTransform { X = -radius, Y = -radius } }; Children.Add(jointShape); }
internal void DrawStaticShapes(Simulator pmks, ObservableCollection <JointData> jointData) { Children.Clear(); Children.Add(axes); initialPositionIcons.Clear(); for (int index = 0; index < pmks.Joints.Count; index++) { var j = pmks.Joints[index]; var isDriver = (index == App.main.drivingIndex); JointData jointRowData = (index < jointData.Count) ? jointData[index] : null; InputJointBaseShape inputJointBaseShape = null; switch (j.TypeOfJoint) { case JointType.R: inputJointBaseShape = new InputRJointShape(jointSize, penThick, j.xInitial, j.yInitial, XAxisOffset, YAxisOffset, j.IsGround, isDriver, index, jointRowData); break; case JointType.P: inputJointBaseShape = new InputPJointShape(jointSize, penThick, j.xInitial, j.yInitial, XAxisOffset, YAxisOffset, j.SlideAngleInitial, j.IsGround, isDriver, index, jointRowData); break; case JointType.RP: inputJointBaseShape = new InputRPJointShape(jointSize, penThick, j.xInitial, j.yInitial, XAxisOffset, YAxisOffset, j.SlideAngleInitial, j.IsGround, index, jointRowData); break; case JointType.G: inputJointBaseShape = new InputGJointShape(jointSize, penThick, j.xInitial, j.yInitial, XAxisOffset, YAxisOffset, j.SlideAngleInitial, j.IsGround, index, jointRowData); break; } Children.Add(inputJointBaseShape); initialPositionIcons.Add(inputJointBaseShape); } /* remove old ground shapes */ Children.Remove(groundLinkShape); groundLinkShape = new GroundLinkShape(pmks.GroundLink, XAxisOffset, YAxisOffset, penThick, jointSize, DisplayConstants.DefaultBufferRadius / ScaleFactor); Children.Add(groundLinkShape); /* now add the link shapes */ for (int i = 0; i < pmks.NumLinks; i++) { if (!pmks.Links[i].name.Equals("ground")) { Children.Add(new LinkShape(i, pmks.Links[i], XAxisOffset, YAxisOffset, penThick, jointSize, null, DisplayConstants.DefaultBufferRadius / ScaleFactor)); } } if (TargetPath != null) { Children.Remove(TargetPath); TargetPath.RenderTransform = new TranslateTransform { X = XAxisOffset, Y = YAxisOffset }; Children.Add(TargetPath); } }
public InputPJointShape(double jointSize, double strokeThickness, double xPosition, double yPosition, double xAxisOffset, double yAxisOffset, double angle, bool isGround, bool isDriver, int jointNum, JointData jointData) : base(2 * jointSize * DisplayConstants.SliderRectangleWidthIncrease, 2 * jointSize, strokeThickness, xPosition, yPosition, xAxisOffset, yAxisOffset, angle, "PMoveArrows", "PRotateArrows", jointData) { jointShape = new Rectangle { Width = 2 * jointSize * DisplayConstants.SliderRectangleWidthIncrease, Height = 2 * jointSize, Fill = (isGround) ? new SolidColorBrush(Colors.White) : new SolidColorBrush(Colors.Transparent), Stroke = (isDriver) ? new SolidColorBrush(Colors.Green) : new SolidColorBrush(Colors.Black), StrokeThickness = (isDriver) ? 3 * strokeThickness : strokeThickness, RenderTransformOrigin = new Point(0.5, 0.5), RenderTransform = new TranslateTransform { X = -jointSize * DisplayConstants.SliderRectangleWidthIncrease, Y = -jointSize } }; Children.Add(jointShape); }