/// <summary> /// Returns to the caller the index of the point on the Polyline that is nearest to that specified in the single input argument. /// </summary> /// <param name="testPoint">Point for which to find the nearest point on the Polyline.</param> /// <returns>Index of the nearest Polyline point to that specified.</returns> /// <exception cref="Exception">Thrown if the PolyLine contains no points.</exception> public int IndexOfNearestPoint(Point testPoint) { if (Count == 0) { throw new Exception("The polyline does not contain any points"); } // Start with the nearest distance as being the largest possible distance MM nearestDistance = double.PositiveInfinity; int nearestIndex = 0; int index = 0; foreach (Point polylinePoint in this) { // Find out how far this point is from the test point MM thisDistance = (testPoint - polylinePoint).Magnitude; // If it is the nearest one so far then if (thisDistance < nearestDistance) { // Set this as the nearest point nearestDistance = thisDistance; nearestIndex = index; } index += 1; } // Return the nearest index return(nearestIndex); }
/// <summary> /// Rotates the Vector by the specified Euler Angles. /// </summary> /// <param name="eulerAngles">Angles to rotate.</param> public void EulerRotation(Euler.Angles eulerAngles) { int i = 0; int t = 0; double[] M3 = new double[3]; double[] M2 = { I, J, K }; for (i = 0; i <= 2; i++) { M3[i] = 0; for (t = 0; t <= 2; t++) { M3[i] += eulerAngles.Matrix[i, t] * M2[t]; } } _i = M3[0]; _j = M3[1]; _k = M3[2]; }
/// <summary> /// Rotates the Point by the specified Euler Angles. /// </summary> /// <param name="angle">Angles of rotation.</param> public void EulerRotation(Euler.Angles angle) { int i = 0; int t = 0; double[] M3 = new double[3]; double[] M2 = { X, Y, Z }; for (i = 0; i <= 2; i++) { M3[i] = 0; for (t = 0; t <= 2; t++) { M3[i] += angle.Matrix[i, t] * M2[t]; } } X = M3[0]; Y = M3[1]; Z = M3[2]; }
/// <summary> /// Constructs a new SplinePoint with the specified position. If present, directions /// and magnitudes are inferred from the supplied control points. /// </summary> /// <param name="position">Position of the point.</param> /// <param name="controlPointBefore">Control point before position.</param> /// <param name="controlPointAfter">Control point after position.</param> public SplinePoint(Point position, Point controlPointBefore = null, Point controlPointAfter = null) { _x = position.X; _y = position.Y; _z = position.Z; if (controlPointBefore == null) { _directionBefore = new Vector(); _magnitudeBefore = 0; } else { _directionBefore = position - controlPointBefore; _magnitudeBefore = _directionBefore.Magnitude; _directionBefore.Normalize(); } if (controlPointAfter == null) { _directionAfter = new Vector(); _magnitudeAfter = 0; } else { _directionAfter = controlPointAfter - position; _magnitudeAfter = _directionAfter.Magnitude; _directionAfter.Normalize(); } }
/// <summary> /// Rotates Point by the specified angle in radians about the specified Vector. /// </summary> /// <param name="vectorToRotateAbout">Vector about which to rotate the Point.</param> /// <param name="rotationOrigin">Origin of coordinate system.</param> /// <param name="angle">Angle to rotate.</param> public void RotateAboutVector(Vector vectorToRotateAbout, Point rotationOrigin, Radian angle) { Vector vector = vectorToRotateAbout.Clone(); vector.Normalize(); Vector vectorToOrigin = rotationOrigin - new Point(); // Move this point to the rotation origin Point thisPoint = Clone(); thisPoint -= vectorToOrigin; Vector objPointVector = new Vector(thisPoint.X, thisPoint.Y, thisPoint.Z); double dp = Vector.DotProduct(objPointVector, vector); Vector r_p = vector * dp; Vector Vx = objPointVector - r_p; Vector N_rx = Vx * Math.Cos(angle); Vector xCn = Vector.CrossProduct(vector, Vx); Vector N_ry = xCn * Math.Sin(angle); Vector OutP = r_p + N_rx; OutP = OutP + N_ry; // Move the point back thisPoint = new Point(OutP.I, OutP.J, OutP.K); thisPoint += vectorToOrigin; _x = thisPoint.X; _y = thisPoint.Y; _z = thisPoint.Z; }
/// <summary> /// Rebases Point from the world to the specified Workplane /// </summary> /// <param name="toWorkplane">Workplane to rebase the Point to.</param> public void RebaseToWorkplane(Workplane toWorkplane) { Vector fromOrigin = null; fromOrigin = this - toWorkplane.Origin; X = Vector.DotProduct(fromOrigin, toWorkplane.XAxis); Y = Vector.DotProduct(fromOrigin, toWorkplane.YAxis); Z = Vector.DotProduct(fromOrigin, toWorkplane.ZAxis); }
/// <summary> /// Constructs a new SplinePoint about the specified point argument. Directions and magnitudes are unspecified. /// </summary> /// <param name="point">Point about which to base the new SplinePoint.</param> public SplinePoint(Point point) { _x = point.X; _y = point.Y; _z = point.Z; _directionBefore = new Vector(); _magnitudeBefore = 0; _directionAfter = new Vector(); _magnitudeAfter = 0; }
/// <summary> /// Constructs a PointData object with default values. /// </summary> public PointData() { _nominalSurfacePoint = new Point(); _surfaceNormal = new Vector(); _surfaceOffset = 0.0; _upperTolerance = 0.0; _lowerTolerance = 0.0; _probeCentre = new Point(); _probeRadius = 0.0; _measuredSurfacePoint = null; }
/// <summary> /// Constructor initialises the Vector using an array of MM objects. /// </summary> /// <param name="componentArray">Array of MM objects from which to create the vector.</param> /// <exception cref="Exception">Thrown if input array does not contain three coordinates.</exception> public Vector(MM[] componentArray) { // Check that there are three elements in the array if (componentArray.Length != 3) { throw new Exception("Vector constructor requires 3 coordinates"); } _i = componentArray[0]; _j = componentArray[1]; _k = componentArray[2]; }
/// <summary> /// Constructs a point from an array of Doubles. /// </summary> /// <param name="pointArray">Array from which to create the point.</param> public Point(double[] pointArray) { try { _x = pointArray[0]; _y = pointArray[1]; _z = pointArray[2]; } catch (Exception ex) { } }
/// <summary> /// Constructs a point from an array of MM objects. /// </summary> /// <param name="pointArray">Array from which to create the point.</param> /// <exception cref="Exception">Thrown if input array does not contain exactly three coordinates.</exception> public Point(MM[] pointArray) { // Check that there are three elements in the array if (pointArray.Length != 3) { throw new Exception("Point constructor requires 3 coordinates"); } _x = pointArray[0]; _y = pointArray[1]; _z = pointArray[2]; }
/// <summary> /// Rebases this vector to the specified workplane. /// </summary> /// <param name="toWorkplane">Workplane to rebase to.</param> public void RebaseToWorkplane(Workplane toWorkplane) { Vector rebasedVector = new Vector(); rebasedVector.I = DotProduct(this, toWorkplane.XAxis); rebasedVector.J = DotProduct(this, toWorkplane.YAxis); rebasedVector.K = DotProduct(this, toWorkplane.ZAxis); _i = rebasedVector.I; _j = rebasedVector.J; _k = rebasedVector.K; }
/// <summary> /// Returns True if the magnitude of this object is equivalent to that of the specified object. /// If the specified object is neither of type MM or Inch, false will be returned. /// </summary> /// <param name="obj">Object with which to compare this.</param> /// <returns>True if the magnitudes of this and the specified object are equivalent; false otherwise.</returns> public override bool Equals(object obj) { if (obj is MM) { return(this == (MM)obj); } if (obj is Inch) { MM objAsMM = (Inch)obj; return(this == objAsMM); } return(Value == Convert.ToDouble(obj)); }
/// <summary> /// Normalises this vector. /// </summary> /// <exception cref="Exception">Thrown if this is of zero length: a zero length vector cannot be converted to a unit vector.</exception> public void Normalize() { try { MM magnitude = Magnitude; I = _i / magnitude.Value; J = _j / magnitude.Value; K = _k / magnitude.Value; } catch (Exception ex) { throw new Exception("Zero length vector cannot be converted to unit vector."); } }
/// <summary> /// Rebases the Point from the specified workplane to the world. /// </summary> /// <param name="fromWorkplane">Workplane from which to rebase the point.</param> public void RebaseFromWorkplane(Workplane fromWorkplane) { MM x = _x; MM y = _y; MM z = _z; X = x * fromWorkplane.XAxis.I + y * fromWorkplane.YAxis.I + z * fromWorkplane.ZAxis.I; Y = x * fromWorkplane.XAxis.J + y * fromWorkplane.YAxis.J + z * fromWorkplane.ZAxis.J; Z = x * fromWorkplane.XAxis.K + y * fromWorkplane.YAxis.K + z * fromWorkplane.ZAxis.K; X += fromWorkplane.Origin.X; Y += fromWorkplane.Origin.Y; Z += fromWorkplane.Origin.Z; }
/// <summary> /// Rebases this vector from a specified workplane to the world. /// </summary> /// <param name="fromWorkplane">Workplane from which to rebase vector.</param> public void RebaseFromWorkplane(Workplane fromWorkplane) { Vector rebasedVector = new Vector(); double i = _i; double j = _j; double k = _k; rebasedVector.I = i * fromWorkplane.XAxis.I + j * fromWorkplane.YAxis.I + k * fromWorkplane.ZAxis.I; rebasedVector.J = i * fromWorkplane.XAxis.J + j * fromWorkplane.YAxis.J + k * fromWorkplane.ZAxis.J; rebasedVector.K = i * fromWorkplane.XAxis.K + j * fromWorkplane.YAxis.K + k * fromWorkplane.ZAxis.K; _i = rebasedVector.I; _j = rebasedVector.J; _k = rebasedVector.K; }
/// <summary> /// Returns True if the magnitude of this object is equivalent to that of the specified object to the specified number of decimal places. /// If the specified object is neither of type MM or Inch, false will be returned. /// </summary> /// <param name="obj">Object with which to compare this.</param> /// <param name="nDecPts">Number of decimal places to compare.</param> /// <returns>True if the magnitudes of this and the specified object are considered equivalent; false otherwise.</returns> public bool Equals(object obj, int nDecPts) { if (obj is MM) { MM objAsMM = (MM)obj; double roundedObj = Math.Round(objAsMM.Value, nDecPts); double roundedMe = Math.Round(Value, nDecPts); return(roundedObj == roundedMe); } if (obj is Inch) { MM objAsMM = (Inch)obj; double roundedObj = Math.Round(objAsMM.Value, nDecPts); double roundedMe = Math.Round(Value, nDecPts); return(roundedObj == roundedMe); } return(false); }
/// <summary> /// Constructs a PointData object with the specified values. /// </summary> /// <param name="nominalSurfacePoint">Nominal point on the surface to be probed.</param> /// <param name="surfaceNormal">Vector normal to the surface at nominalSurfacePoint.</param> /// <param name="surfaceOffset">Expected offset of the point from the ideal.</param> /// <param name="upperTolerance">Upper permissible offset tolerance.</param> /// <param name="lowerTolerance">Lower permissible offset tolerance.</param> /// <param name="weight">Relative importance of this point in the model.</param> /// <param name="probeCentre">Probe centre on measurement.</param> /// <param name="probeRadius">Probe radius in millimetres.</param> /// <remarks></remarks> public PointData( Point nominalSurfacePoint, Vector surfaceNormal, double surfaceOffset, double upperTolerance, double lowerTolerance, double weight, Point probeCentre, MM probeRadius) { _nominalSurfacePoint = nominalSurfacePoint; _surfaceNormal = surfaceNormal; _surfaceOffset = surfaceOffset; _upperTolerance = upperTolerance; _lowerTolerance = lowerTolerance; _probeCentre = probeCentre; _probeRadius = probeRadius; //Calculate the surface point CalculateMeasuredSurfacePoint(); }
/// <summary> /// Rotates this Vector by the specified angle in radians about the specified vector. /// </summary> /// <param name="vectorToRotateAbout">Vector to rotate about.</param> /// <param name="angle">Angle to rotate.</param> public void RotateAboutVector(Vector vectorToRotateAbout, Radian angle) { Vector vector = vectorToRotateAbout.Clone(); vector.Normalize(); Vector objPointVector = new Vector(_i, _j, _k); double dp = DotProduct(objPointVector, vector); Vector r_p = vector * dp; Vector Vx = objPointVector - r_p; Vector N_rx = Vx * Math.Cos(angle); Vector xCn = CrossProduct(vector, Vx); Vector N_ry = xCn * Math.Sin(angle); Vector OutP = r_p + N_rx; OutP = OutP + N_ry; _i = OutP.I; _j = OutP.J; _k = OutP.K; }
/// <summary> /// Constructs a new SplinePoint with the specified position, directions and magnitudes. /// </summary> /// <param name="point">Position of the point.</param> /// <param name="directionBefore">Direction before the point.</param> /// <param name="magnitudeBefore">Magnitude before the point.</param> /// <param name="magnitudeAfter">Direction after the point.</param> /// <param name="directionAfter">Magnitude after the point.</param> public SplinePoint( Point point, Vector directionBefore = null, MM magnitudeBefore = new MM(), Vector directionAfter = null, MM magnitudeAfter = new MM()) { _x = point.X; _y = point.Y; _z = point.Z; if (directionBefore == null) { directionBefore = new Vector(0.0, 0.0, 1.0); } _directionBefore = directionBefore; _magnitudeBefore = magnitudeBefore; if (directionAfter == null) { directionAfter = new Vector(0.0, 0.0, 1.0); } _directionAfter = directionAfter; _magnitudeAfter = magnitudeAfter; }
/// <summary> /// Constructs a Vector from a single line of text, the magnitudes of which are demarked by the specified delimeter. /// </summary> /// <param name="textLine">Line of text containing the components and separated by the delimiter.</param> /// <param name="delimiter">Delimiter - defaults to a single space.</param> /// <exception cref="Exception">Thrown if the string does not contain exactly three components or cannot be parsed.</exception> public Vector(string textLine, char delimiter = ' ') { // Split the text by the delimiter string[] textLineSplit = textLine.Split(delimiter); // We expect all three components if (textLineSplit.Length != 3) { throw new Exception("Incorrect number of components found in line"); } try { // Assign the values _i = Convert.ToDouble(textLineSplit[0]); _j = Convert.ToDouble(textLineSplit[1]); _k = Convert.ToDouble(textLineSplit[2]); } catch (Exception ex) { throw new Exception("Error parsing component values", ex); } }
/// <summary> /// Rotates Point by the specified angle in radians about the specified Point in the X axis. /// </summary> /// <param name="pointToRotateAbout">Point about which to rotate.</param> /// <param name="angle">Angle to rotate.</param> public void RotateAboutXAxis(Point pointToRotateAbout, Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double yLength = 0; double zLength = 0; yLength = _y - pointToRotateAbout.Y; zLength = _z - pointToRotateAbout.Z; double newYLength = 0; double newZLength = 0; newYLength = yLength * cosAngle - zLength * sinAngle; newZLength = yLength * sinAngle + zLength * cosAngle; X = _x; Y = newYLength + pointToRotateAbout.Y; Z = newZLength + pointToRotateAbout.Z; }
/// <summary> /// Rotates Point by the specified angle in radians about the specified Point in the Y axis. /// </summary> /// <param name="pointToRotateAbout">Point about which to rotate.</param> /// <param name="angle">Angle to rotate.</param> public void RotateAboutYAxis(Point pointToRotateAbout, Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double zLength = 0; double xLength = 0; zLength = _z - pointToRotateAbout.Z; xLength = _x - pointToRotateAbout.X; double newZLength = 0; double newXLength = 0; newZLength = zLength * cosAngle - xLength * sinAngle; newXLength = zLength * sinAngle + xLength * cosAngle; Z = newZLength + pointToRotateAbout.Z; Y = _y; X = newXLength + pointToRotateAbout.X; }
/// <summary> /// Rotates Point by the specified angle in radians about the specified Point in the Z axis. /// </summary> /// <param name="pointToRotateAbout">Point about which to rotate.</param> /// <param name="angle">Angle to rotate.</param> public void RotateAboutZAxis(Point pointToRotateAbout, Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double xLength = 0; double yLength = 0; xLength = _x - pointToRotateAbout.X; yLength = _y - pointToRotateAbout.Y; double newXLength = 0; double newYLength = 0; newXLength = xLength * cosAngle - yLength * sinAngle; newYLength = xLength * sinAngle + yLength * cosAngle; X = newXLength + pointToRotateAbout.X; Y = newYLength + pointToRotateAbout.Y; Z = _z; }
/// <summary> /// Rotates this Vector by the specified angle in Radians about Z. /// </summary> /// <param name="angle">Angle to rotate.</param> public void RotateAboutZAxis(Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double xLength = 0; double yLength = 0; xLength = _i; yLength = _j; double dblNewXLength = 0; double dblNewYLength = 0; dblNewXLength = xLength * cosAngle - yLength * sinAngle; dblNewYLength = xLength * sinAngle + yLength * cosAngle; _i = dblNewXLength; _j = dblNewYLength; _k = _k; }
/// <summary> /// Rotates this Vector by the specified angle in Radians about Y. /// </summary> /// <param name="angle">Angle to rotate.</param> public void RotateAboutYAxis(Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double zLength = 0; double xLength = 0; zLength = _k; xLength = _i; double newZLength = 0; double newXLength = 0; newZLength = zLength * cosAngle - xLength * sinAngle; newXLength = zLength * sinAngle + xLength * cosAngle; _i = newXLength; _j = _j; _k = newZLength; }
/// <summary> /// Rotates this Vector by the specified angle in Radians about X. /// </summary> /// <param name="angle">Angle to rotate.</param> public void RotateAboutXAxis(Radian angle) { double cosAngle = 0; double sinAngle = 0; cosAngle = Math.Cos(angle); sinAngle = Math.Sin(angle); double yLength = 0; double zLength = 0; yLength = _j; zLength = _k; double newYLength = 0; double newZLength = 0; newYLength = yLength * cosAngle - zLength * sinAngle; newZLength = yLength * sinAngle + zLength * cosAngle; _i = _i; _j = newYLength; _k = newZLength; }
/// <summary> /// Initialises the vertex position and the IJK components of the normal to the values specified. /// </summary> /// <param name="x">Vertex position in X.</param> /// <param name="y">Vertex position in Y.</param> /// <param name="z">Vertex position in Z.</param> /// <param name="i">I component of the normal vector.</param> /// <param name="j">J component of the normal vector.</param> /// <param name="k">K component of the normal vector.</param> public DMTVertex(MM x, MM y, MM z, MM i, MM j, MM k) { _position = new Point(x, y, z); }
/// <summary> /// Initialises the vertex position to the specified values. /// </summary> /// <param name="x">Position in X.</param> /// <param name="y">Position in Y.</param> /// <param name="z">Position in Z.</param> public DMTVertex(MM x, MM y, MM z) { _position = new Point(x, y, z); }
/// <summary> /// Constructs a vector between the specified start and end points. /// </summary> /// <param name="startPoint">Vector start point.</param> /// <param name="endPoint">Vector end point.</param> public Vector(Point startPoint, Point endPoint) { _i = endPoint.X - startPoint.X; _j = endPoint.Y - startPoint.Y; _k = endPoint.Z - startPoint.Z; }