Example #1
0
        public FloatContour TransformContour(float[,] transform, bool disableNotificationEvents = false)
        {
            // Now that we have all the required coefficients, we'll transform
            // the points in the original Contour, and store them in a new one
            FloatContour dstContour = new FloatContour(); //***008OL

            if (disableNotificationEvents)
            {
                dstContour.DisableNotificationEvents();
            }

            for (int i = 0; i < Length; i++)
            {
                float cx = this[i].X;
                float cy = this[i].Y;

                float x = transform[0, 0] * cx
                          + transform[0, 1] * cy
                          + transform[0, 2];

                float y = transform[1, 0] * cx
                          + transform[1, 1] * cy
                          + transform[1, 2];

                dstContour.AddPoint(x, y);
            }

            return(dstContour);
        }
Example #2
0
        /// <summary>
        /// This will do a specific mapping with p1 and desP1 as centers and will
        /// rotate, scale, and translate so that p1 and p2 are on top of desP1 and desP2,
        /// respectively. Note: The precision on this isn't great -- would probably be better
        /// to do the linear equation solving to find a transformation matrix similar to the
        /// regular MapContour method.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="desP1"></param>
        /// <param name="desP2"></param>
        /// <returns></returns>
        public FloatContour MapContour2D(
            PointF p1,
            PointF p2,
            PointF desP1,
            PointF desP2)
        {
            float currentAngle = p1.FindAngle(p2);
            float desiredAngle = desP1.FindAngle(desP2);

            float degreesToRotate = desiredAngle - currentAngle;

            FloatContour transformedContour = this.Rotate(p1, degreesToRotate);

            var p2rotated = p2.Rotate(p1, degreesToRotate);

            // Figure out the scaling ratio
            double currentDistance = MathHelper.GetDistance(p1.X, p1.Y, p2.X, p2.Y);
            double targetDistance  = MathHelper.GetDistance(desP1.X, desP1.Y, desP2.X, desP2.Y);

            double scaleRatio = targetDistance / currentDistance;

            // So we've rotated the contour, let's translate it so that p1 is on top of desP1
            // and scale them at the same time.
            double xDiff = desP1.X - p1.X * scaleRatio;
            double yDiff = desP1.Y - p1.Y * scaleRatio;

            foreach (var p in transformedContour.Points)
            {
                p.X = (float)((p.X + xDiff) * scaleRatio);
                p.Y = (float)((p.Y + yDiff) * scaleRatio);
            }

            return(transformedContour);
        }
Example #3
0
        public FloatContour TrimBeginningToDistanceFromPoint(double distance, PointF referencePoint, out int numPointsTrimmed, bool disableEvents = false)
        {
            FloatContour result = new FloatContour();

            result.Points = new ObservableNotifiableCollection <PointF>();

            if (disableEvents)
            {
                result.DisableNotificationEvents();
            }

            bool foundBeginning = false;

            numPointsTrimmed = 0;

            foreach (var p in this.Points)
            {
                if (!foundBeginning && MathHelper.GetDistance(p.X, p.Y, referencePoint.X, referencePoint.Y) < distance)
                {
                    foundBeginning = true;
                }

                if (foundBeginning)
                {
                    result.Points.Add(p);
                }
                else
                {
                    numPointsTrimmed += 1;
                }
            }

            return(result);
        }
Example #4
0
        public FloatContour Rotate(PointF centerPoint, float degreesToRotate)
        {
            FloatContour result = new FloatContour();

            result.Points = new ObservableNotifiableCollection <PointF>();

            foreach (var p in this.Points)
            {
                result.Points.Add(p.Rotate(centerPoint, degreesToRotate));
            }

            return(result);
        }
Example #5
0
        //********************************************************************
        // FloatContour()
        //
        public FloatContour(FloatContour contour)  //***006FC new
        {
            if (contour == null)
            {
                throw new ArgumentNullException(nameof(contour));
            }

            _points = new ObservableNotifiableCollection <PointF>();

            foreach (var p in contour.Points)
            {
                _points.Add(new PointF(p.X, p.Y, p.Z));
            }
        }
Example #6
0
        public FloatContour TransformTrimBeginningToDistanceFromPoint(float[,] transform, double distance, PointF referencePoint, out int numPointsTrimmed, bool disableEvents = false)
        {
            FloatContour result = new FloatContour();

            if (disableEvents)
            {
                result.DisableNotificationEvents();
            }

            result.Points = new ObservableNotifiableCollection <PointF>();

            bool foundBeginning = false;

            numPointsTrimmed = 0;

            foreach (var p in this.Points)
            {
                float newX = transform[0, 0] * p.X
                             + transform[0, 1] * p.Y
                             + transform[0, 2];

                float newY = transform[1, 0] * p.X
                             + transform[1, 1] * p.Y
                             + transform[1, 2];

                if (!foundBeginning && MathHelper.GetDistance(newX, newY, referencePoint.X, referencePoint.Y) < distance)
                {
                    foundBeginning = true;
                }

                if (foundBeginning)
                {
                    result.Points.Add(new PointF(newX, newY));
                }
                else
                {
                    numPointsTrimmed += 1;
                }
            }

            return(result);
        }
Example #7
0
        //*******************************************************************
        //
        // Chain::Chain(FloatContour *fc)  //***008OL entire function added
        //
        //    Used when FloatContour is read from DB file.
        //
        //    Open Question: Should updateRelativeChain() be used here?
        //
        //    PRE:  fc is normalized and evenly spaced
        //    POST: Chain indices correspond to fc indices
        //
        public Chain(FloatContour fc)
        {
            if (fc == null)
            {
                throw new ArgumentNullException(nameof(fc));
            }

            _numPoints = fc.Length;

            List <double> chain         = new List <double>();
            List <double> relativeChain = new List <double>();

            // NOTE: the Chain angle at each pooint is ALWAYS the angle of
            // the INCOMING edge FROM the previous contour point - JHS

            if (_numPoints > 1)
            {
                // initial angle of chain is angle of first point relative to (0,0)
                //chain.push_back(rtod(atan2((*fc)[0].y, (*fc)[0].x))); //***2.1mt
                //***2.01 - now just duplicate the first relative angle
                chain.Add(MathHelper.RadiansToDegrees(Math.Atan2(fc[1].Y - fc[0].Y, fc[1].X - fc[0].X)));                 //***2.01

                chain.Add(MathHelper.RadiansToDegrees(Math.Atan2(fc[1].Y - fc[0].Y, fc[1].X - fc[0].X)));

                double lastAngle = chain[1];                 //***2.1mt - use this to prevent any quadrant discontinuity

                // initial angle in relativeChain is angle change across point[0]
                //***1.2 - I think initial angle is meaningless and the
                // initial meaningful angle is actually angle change across point[1]
                relativeChain.Add(0.0);                 //***1.2 - added this

                // without line above the relative chain length & indexing are off by one
                relativeChain.Add(chain[0] - chain[1]);

                for (int i = 2; i < _numPoints; i++)
                {
                    double angle = MathHelper.RadiansToDegrees(Math.Atan2(fc[i].Y - fc[i - 1].Y, fc[i].X - fc[i - 1].X));                     //***2.01

                    //***2.01 - prevent ANY discontinuity of greater than 180 degrees
                    if (angle - lastAngle > 180.0)
                    {
                        chain.Add(angle - 360.0);
                    }
                    else if (angle - lastAngle < -180.0)
                    {
                        chain.Add(angle + 360.0);
                    }
                    else
                    {
                        chain.Add(angle);
                    }

                    lastAngle = chain[i];

                    //***2.01 - end

                    //////////////////////////// begin old ///////////////////////
                    relativeChain.Add(chain[i - 1] - chain[i]);
                    //////////////////////// end old ///////////////////////////
                }
            }

            // NOTE: there is NO useful change in angle across either
            // the first point or the last point in fc

            // now copy vectors to double arrays

            _chain         = chain.ToArray();
            _relativeChain = relativeChain.ToArray();
        }
Example #8
0
        public static void FitContoursToSize(double drawingWidth, double drawingHeight, FloatContour unknownContour, FloatContour dbContour,
                                             out Contour displayUnknownContour, out Contour displayDBContour,
                                             out double xOffset, out double yOffset)
        {
            if (unknownContour == null && dbContour == null)
            {
                throw new ArgumentNullException("Both contours null!");
            }

            float xMax, yMax, xMin, yMin;

            if (unknownContour == null)
            {
                xMax = dbContour.MaxX();
                yMax = dbContour.MaxY();
                xMin = dbContour.MinX();
                yMin = dbContour.MinY();
            }
            else if (dbContour == null)
            {
                xMax = unknownContour.MaxX();
                yMax = unknownContour.MaxY();
                xMin = unknownContour.MinX();
                yMin = unknownContour.MinY();
            }
            else
            {
                xMax = (dbContour.MaxX() > (float)unknownContour.MaxX()) ? dbContour.MaxX() : (float)unknownContour.MaxX();
                yMax = (dbContour.MaxY() > (float)unknownContour.MaxY()) ? dbContour.MaxY() : (float)unknownContour.MaxY();
                xMin = (dbContour.MinX() < (float)unknownContour.MinX()) ? dbContour.MinX() : (float)unknownContour.MinX();
                yMin = (dbContour.MinY() < (float)unknownContour.MinY()) ? dbContour.MinY() : (float)unknownContour.MinY();
            }

            float
                xRange = xMax - xMin + 8, //***1.5 - added POINT_SIZE
                yRange = yMax - yMin + 8; //***1.5 - added POINT_SIZE

            float
                heightRatio = (float)(drawingWidth / yRange),
                widthRatio  = (float)(drawingHeight / xRange);

            float ratio;

            if (heightRatio < widthRatio)
            {
                ratio   = heightRatio;
                xOffset = (drawingWidth - ratio * xRange) / 2 - xMin * ratio;
                yOffset = 0 - yMin * ratio;
            }
            else
            {
                ratio   = widthRatio;
                xOffset = 0 - xMin * ratio;
                yOffset = (drawingHeight - ratio * yRange) / 2 - yMin * ratio;
            }

            float ratioInverse = 1 / ratio;

            if (unknownContour == null)
            {
                displayUnknownContour = null;
            }
            else
            {
                displayUnknownContour = new Contour(unknownContour, ratioInverse);
            }

            if (dbContour == null)
            {
                displayDBContour = null;
            }
            else
            {
                displayDBContour = new Contour(dbContour, ratioInverse);
            }
        }
Example #9
0
        //********************************************************************
        // evenlySpaceContourPoints()
        //
        public FloatContour EvenlySpaceContourPoints(int space)
        {
            if (space <= 0)
            {
                return(null);
            }

            float  x, y, ccx, ccy, tx, ty, vx, vy, vsx, vsy;
            int    i;
            double a, b, c, sqrt_b2_4ac, t1, t2, t, tLen;

            ccx = Points[0].X;
            ccy = Points[0].Y;
            i   = 0;
            bool         done       = false;
            FloatContour newContour = new FloatContour();

            while (!done)
            {          // Contour length >= 2
                vsx  = Points[i].X;
                vsy  = Points[i].Y;
                x    = Points[i + 1].X;
                y    = Points[i + 1].Y;
                vx   = x - vsx;
                vy   = y - vsy;
                tx   = x - ccx;
                ty   = y - ccy;
                tLen = Math.Sqrt(tx * tx + ty * ty);
                if (tLen > space)
                {    // then evaluate intersection
                    tx          = vsx - ccx;
                    ty          = vsy - ccy;
                    a           = vx * vx + vy * vy;
                    b           = 2 * (vx * tx + vy * ty); // 2 * dot(v, t)
                    c           = tx * tx + ty * ty - space * space;
                    sqrt_b2_4ac = Math.Sqrt(b * b - 4 * a * c);

                    if (sqrt_b2_4ac < 0.0)  // should never happen - JHS
                    {
                        Trace.WriteLine("Neg Rad in FloatContour::evenlySpaceContourPoints()\n");
                    }

                    t1 = (-b + sqrt_b2_4ac) / (2 * a);
                    t2 = (-b - sqrt_b2_4ac) / (2 * a);
                    if ((t1 >= 0) && (t1 <= 1))
                    {
                        t = t1;
                    }
                    else if ((t2 >= 0) && (t2 <= 1))
                    {
                        t = t2;
                    }
                    else
                    {
                        t = 0;
                    }
                    // update circle ctr for next go
                    ccx = (float)(vsx + t * vx);
                    ccy = (float)(vsy + t * vy);
                    newContour.AddPoint(ccx, ccy);
                }
                else
                {
                    i++;
                }
                if (i >= Length - 1)
                {
                    done = true;
                }
            }

            return(newContour);
        }