示例#1
0
        public virtual void Reset(bool shouldResetView = true)
        {
            // reset extents
            MinX = double.MaxValue;
            MaxX = double.MinValue;
            MinY = double.MaxValue;
            MaxY = double.MinValue;

            // update counter
            Count = 0;

            // reset buffers with defaults
            _lines = new List <VertexGroup>()
            {
                new VertexGroup(DefaultLineColor)
            };
            _points = new List <VertexGroup>()
            {
                new VertexGroup(DefaultPointColor)
            };
            _openPolylines   = new List <VertexGroup>();
            _closedPolylines = new List <VertexGroup>();

            // reset mouse position
            Mouse = new MVertex();

            if (shouldResetView)
            {
                ResetView();
            }
        }
示例#2
0
 private double GetAngle(MVertex v1, MVertex v2)
 {
     return(Math.Atan2(
                v2.Y - v1.Y,
                v2.X - v1.X
                ));
 }
        public AlignmentCalculationWrapper(
            MVertex invertsIn,
            MVertex c2bOffsetsIn,
            MVertex fiducialAIn,
            MVertex fiducialStageAIn,
            MVertex fiducialBIn,
            MVertex fiducialStageBIn
            )
        {
            // update the inverts
            Inverts = invertsIn;

            // update the camera to beam offsets
            C2BOffsets = c2bOffsetsIn;

            // update the CAD fiducials
            FiducialA_CAD = fiducialAIn;
            FiducialB_CAD = fiducialBIn;

            // update the stage fiducials
            FiducialA_Stage = fiducialStageAIn;
            FiducialB_Stage = fiducialStageBIn;

            Update();
        }
 private static MVertex Average(MVertex aIn, MVertex bIn)
 {
     return(new MVertex(
                (aIn.X + bIn.X) / 2d,
                (aIn.Y + bIn.Y) / 2d
                ));
 }
 private static MVertex Sum(MVertex aIn, MVertex bIn)
 {
     return(new MVertex(
                (aIn.X + bIn.X),
                (aIn.Y + bIn.Y)
                ));
 }
        /// <summary>
        /// Calculates the target (as per CAD) on the stage centred about the
        /// optical axis. The stage will have limited travel, and may not be
        /// able to reach the target coordinate. In this case, move the mask
        /// stage as close as possible to the target coordinate.
        /// The remaining distance to the target is applied as a SCANNER OFFSET.
        /// </summary>
        /// <param name="targetOnCADIn">The target position as per CAD</param>
        /// <param name="stageLimitsIn">The maximum and minimum stage boundaries</param>
        /// <param name="scannerLimitsIn">The maximum and minimum scanner boundaries</param>
        /// <returns>The actual stage coordinate and scanner offsets</returns>
        public (MVertex StagePosition, MVertex ScannerOffsets, bool IsWithinBounds) GetTargetPositionOnStage(MVertex targetOnCADIn, MLimit stageLimitsIn, MLimit scannerLimitsIn)
        {
            bool isWithinBounds = true;

            // calculate the position on the stage
            MVertex targetOnStage = GetTargetPositionOnStage(targetOnCADIn);

            // constrain the position to the stage's limits
            var constrainedStagePosition = new MVertex(
                Constrain(targetOnStage.X, stageLimitsIn.MinimumX, stageLimitsIn.MaximumX),
                Constrain(targetOnStage.Y, stageLimitsIn.MinimumY, stageLimitsIn.MaximumY)
                );

            // apply remaining offsets to the scanner
            var scannerOffsets = new MVertex(
                -1 * (targetOnStage.X - constrainedStagePosition.X),
                -1 * (targetOnStage.Y - constrainedStagePosition.Y)
                );

            // ensure scanner offsets are within the scanner's limits
            if (
                scannerOffsets.X < scannerLimitsIn.MinimumX ||
                scannerOffsets.X > scannerLimitsIn.MaximumX ||
                scannerOffsets.Y < scannerLimitsIn.MinimumY ||
                scannerOffsets.Y > scannerLimitsIn.MaximumY
                )
            {
                isWithinBounds = false;
            }

            return(constrainedStagePosition, scannerOffsets, isWithinBounds);
        }
 /// <summary>
 /// Calculates the target (as per CAD) on the stage centred about the
 /// optical axis.
 /// </summary>
 /// <param name="stageOriginIn">The stage origin from a previous calculated result</param>
 /// <param name="targetOnCADIn">The target position as per CAD</param>
 /// <param name="stageAngleIn">The angle from a previously calculated result</param>
 /// <returns>The actual stage coordinate</returns>
 public static MVertex GetTargetPositionOnStage(MVertex invertsIn, MarkGeometryPoint targetOnCADIn, MVertex stageOriginIn, double stageAngleIn)
 {
     return(new MVertex(
                (stageOriginIn.X + (invertsIn.X * (((targetOnCADIn.X) * Math.Cos(stageAngleIn)) - ((targetOnCADIn.Y) * Math.Sin(stageAngleIn))))),
                (stageOriginIn.Y + (invertsIn.Y * (((targetOnCADIn.X) * Math.Sin(stageAngleIn)) + ((targetOnCADIn.Y) * Math.Cos(stageAngleIn)))))
                ));
 }
 /// <summary>
 /// Calculates the target (as per CAD) on the stage centred about the
 /// optical axis.
 /// </summary>
 /// <param name="stageOriginIn">The stage origin from a previous calculated result</param>
 /// <param name="targetOnCADIn">The target position as per CAD</param>
 /// <param name="stageAngleIn">The angle from a previously calculated result</param>
 /// <returns>The actual stage coordinate</returns>
 public MVertex GetTargetPositionOnStage(MVertex targetOnCADIn, MVertex stageOriginIn, double stageAngleIn)
 {
     return(new MVertex(
                (stageOriginIn.X + (Inverts.X * (((targetOnCADIn.X) * Math.Cos(stageAngleIn)) - ((targetOnCADIn.Y) * Math.Sin(stageAngleIn))))),
                (stageOriginIn.Y + (Inverts.Y * (((targetOnCADIn.X) * Math.Sin(stageAngleIn)) + ((targetOnCADIn.Y) * Math.Cos(stageAngleIn)))))
                ));
 }
示例#9
0
        public virtual void ZoomToFit(MVertex centrePoint, double width, double height)
        {
            double newScale = _reservedViewPortSize / Math.Max(width, height);

            _panOffset.X = -newScale * (centrePoint.X + _cadOffset.X);
            _panOffset.Y = -newScale * (centrePoint.Y + _cadOffset.Y);
            _zoom        = newScale / _scale;

            Render();
        }
示例#10
0
        }                                         // pointer to e1 (forward) and e2 (backward) edges

        public static LinkedList <IntersectionStructure> Create(MVertex intersectionPoint, STLEdge forwardEdge, STLEdge backwardEdge)
        {
            var iis = new LinkedList <IntersectionStructure>();

            iis.AddLast(
                new IntersectionStructure()
            {
                ForwardEdgeIntersectionPoint = intersectionPoint,
                ForwardEdge  = forwardEdge,
                BackwardEdge = backwardEdge
            }
                );

            return(iis);
        }
示例#11
0
        // TODO: Implement mask angle align func
        //     1. The mask angle is measured directly by camera.
        //     2. The mask is rotated to compensate for the angle.
        //     3. The procedure continues until the angle is zero.

        public MVertex ConvertCADToMachineCoordinate(MVertex cadOrigin, MVertex pointOnCAD)
        {
            var transform = GeometricArithmeticModule.CombineTransformations(
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    -cadOrigin.X, -cadOrigin.Y
                    ),
                GeometricArithmeticModule.GetRotationTransformationMatrix(
                    0, 0, Angle
                    ),
                GeometricArithmeticModule.GetTranslationTransformationMatrix(
                    OriginRelativeBEAM.X, OriginRelativeBEAM.Y
                    )
                );

            var result = Vector3.Transform(
                new Vector3((float)pointOnCAD.X, (float)pointOnCAD.Y, 0),
                transform
                );

            return(new MVertex(Inverts.X * result.X, Inverts.Y * result.Y));
        }
示例#12
0
        public void Update()
        {
            // calculate the expected angle in radians
            // Note: Atan2 is Y / X
            ExpectedAngle = Math.Atan2(
                FiducialB_CAD.Y - FiducialA_CAD.Y,
                FiducialB_CAD.X - FiducialA_CAD.X
                );

            // add the target angle to the expected angle
            ExpectedAngle += TargetAngle;

            // calculate the actual angle in radians
            // Note: Atan2 is Y / X
            ActualAngle = Math.Atan2(
                (Inverts.Y * FiducialB_Stage.Y) - (Inverts.Y * FiducialA_Stage.Y),
                (Inverts.X * FiducialB_Stage.X) - (Inverts.X * FiducialA_Stage.X)
                );

            // calculate the angle in radians
            Angle = ActualAngle - ExpectedAngle;

            // calculate the position based on fiducial A (rel to camera)
            PositionRelativeFidA = new MVertex(
                FiducialA_Stage.X - (Inverts.X * ((FiducialA_CAD.X * Math.Cos(Angle)) - (FiducialA_CAD.Y * Math.Sin(Angle)))),
                FiducialA_Stage.Y - (Inverts.Y * ((FiducialA_CAD.X * Math.Sin(Angle)) + (FiducialA_CAD.Y * Math.Cos(Angle))))
                );

            // calculate the position based on fiducial A (rel to camera)
            PositionRelativeFidB = new MVertex(
                FiducialB_Stage.X - (Inverts.X * ((FiducialB_CAD.X * Math.Cos(Angle)) - (FiducialB_CAD.Y * Math.Sin(Angle)))),
                FiducialB_Stage.Y - (Inverts.Y * ((FiducialB_CAD.X * Math.Sin(Angle)) + (FiducialB_CAD.Y * Math.Cos(Angle))))
                );

            // calculate the origin (rel to camera)
            OriginRelativeCAM = Average(PositionRelativeFidA, PositionRelativeFidB);

            // calculate the origin (rel to beam)
            OriginRelativeBEAM = Sum(OriginRelativeCAM, C2BOffsets);
        }
示例#13
0
 private MarkGeometryPoint ToPoint(MVertex vIn)
 {
     return(new MarkGeometryPoint(vIn.X, vIn.Y));
 }
示例#14
0
        public List <MarkGeometryPoint> ToPoints(double deviationToleranceDeg = 1)
        {
            if (IntersectionList.Count <= 0)
            {
                return(new List <MarkGeometryPoint>());
            }
            else if (IntersectionList.Count <= 1)
            {
                return new List <MarkGeometryPoint> {
                           ToPoint(IntersectionList.First.Value.ForwardEdgeIntersectionPoint)
                }
            }
            ;

            MVertex previousPoint = null;
            var     lastEntry     = IntersectionList.First;
            var     points        = new List <MarkGeometryPoint> {
                ToPoint(lastEntry.Value.ForwardEdgeIntersectionPoint)
            };
            var current = lastEntry.Next;

            double referenceAngle = GetAngle(
                lastEntry.Value.ForwardEdgeIntersectionPoint,
                current.Value.ForwardEdgeIntersectionPoint
                );

            deviationToleranceDeg = GeometricArithmeticModule.ToRadians(deviationToleranceDeg);

            while (current != null)
            {
                var angle = GetAngle(
                    lastEntry.Value.ForwardEdgeIntersectionPoint,
                    current.Value.ForwardEdgeIntersectionPoint
                    );

                if (Math.Abs(referenceAngle - angle) > deviationToleranceDeg)
                {
                    lastEntry = current.Previous;
                    points.Add(ToPoint(lastEntry.Value.ForwardEdgeIntersectionPoint));

                    referenceAngle = GetAngle(
                        lastEntry.Value.ForwardEdgeIntersectionPoint,
                        current.Value.ForwardEdgeIntersectionPoint
                        );
                }

                previousPoint = current.Value.ForwardEdgeIntersectionPoint;
                current       = current.Next;
            }

            if (previousPoint != null)
            {
                points.Add(ToPoint(previousPoint));
            }

            // close contour if closed, i.e. first edge touches last edge
            if (MSTLSlicer.CompareEqual(IntersectionList.First.Value.ForwardEdge, IntersectionList.Last.Value.BackwardEdge))
            {
                points.Add(new MarkGeometryPoint(IntersectionList.First.Value.ForwardEdgeIntersectionPoint.X, IntersectionList.First.Value.ForwardEdgeIntersectionPoint.Y));
            }

            return(points);
        }
示例#15
0
 /// <summary>
 /// Calculates the target (as per CAD) on the stage centred about the
 /// optical axis.
 /// </summary>
 /// <param name="targetOnCADIn">The target position as per CAD</param>
 /// <returns>The actual stage coordinate</returns>
 public MVertex GetTargetPositionOnStage(MVertex targetOnCADIn)
 {
     return(GetTargetPositionOnStage(targetOnCADIn, OriginRelativeBEAM, Angle));
 }