Exemplo n.º 1
0
        private Vector3D GetOrientation(
            EllipseParams topEllipse,
            EllipseParams botEllipse,
            Vector3D axisApproximation)
        {
            var topCircleBasis = EllipseHelper.CircleOrientation(topEllipse);
            var botCircleBasis = EllipseHelper.CircleOrientation(botEllipse);

            var topOrientation = GetOrientation(topCircleBasis, axisApproximation);
            var botOrientation = GetOrientation(botCircleBasis, axisApproximation);

            if (Vector3D.DotProduct(botOrientation, topOrientation) < 0)
            {
                botOrientation = -botOrientation;
            }

            var topPerimeter = EllipseHelper.ApproxPerimeter(topEllipse.XRadius, topEllipse.YRadius);
            var botPerimeter = EllipseHelper.ApproxPerimeter(botEllipse.XRadius, botEllipse.YRadius);

            //return result;
            if (topPerimeter > botPerimeter)
            {
                return(topOrientation);
            }
            else
            {
                return(botOrientation);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes 3D circle orientation given its projection as a 2D ellipse.
        /// </summary>
        /// <param name="ellipseParams">The parameters of the 2D ellipse</param>
        /// <returns>A tuple containing two basis vectors for the circle's plane. The second
        /// vector is correct up to the sign of its Z component.</returns>
        public static Tuple <Vector3D, Vector3D> CircleOrientation(EllipseParams ellipseParams)
        {
            Contract.Ensures(Contract.Result <Tuple <Vector3D, Vector3D> >() != null);

            var rotation = Matrix.Identity;

            rotation.Rotate(ellipseParams.Degrees);

            var a = rotation.Transform(new Vector(ellipseParams.XRadius, 0));
            var b = rotation.Transform(new Vector(0, ellipseParams.YRadius));

            // we swap a and b in case Y radius is larger than X radius
            // becuase we want a to be the major axis.
            if (ellipseParams.YRadius > ellipseParams.XRadius)
            {
                var temp = a;
                a = b;
                b = temp;
            }

            var result1 = new Vector3D(a.X, a.Y, 0);
            var result2 = new Vector3D(b.X, b.Y, Math.Sqrt(a.LengthSquared - b.LengthSquared));

            return(Tuple.Create(result1, result2));
        }
Exemplo n.º 3
0
        private Vector3D GetOrientation(
            EllipseParams botEllipse,
            Point[] spineApproximation,
            ref bool Reverse)
        {
            int nspine = spineApproximation.Length;

            Vector vnormal  = new Vector(botEllipse.Center.X - spineApproximation[0].X, botEllipse.Center.Y + spineApproximation[0].Y);
            Vector vreverse = new Vector(botEllipse.Center.X - spineApproximation[spineApproximation.Length - 1].X, botEllipse.Center.Y + spineApproximation[spineApproximation.Length - 1].Y);

            Reverse = false;
            if (vnormal.Length > vreverse.Length)
            {
                Reverse = true;
            }
            Vector botAxis = new Vector();

            if (!Reverse)
            {
                botAxis = new Vector(spineApproximation[1].X - spineApproximation[0].X, spineApproximation[0].Y - spineApproximation[1].Y);
            }
            else
            {
                botAxis = new Vector(spineApproximation[nspine - 2].X - spineApproximation[nspine - 1].X, spineApproximation[nspine - 1].Y - spineApproximation[nspine - 2].Y);
            }


            var botCircleBasis = EllipseHelper.CircleOrientation(botEllipse);
            var botOrientation = GetOrientation(botCircleBasis);

            Vector ApproxOrientationBotProj = new Vector(botOrientation.X, botOrientation.Y);

            if (ApproxOrientationBotProj * botAxis < 0)
            {
                botOrientation = -botOrientation;
            }

            //var topPerimeter = EllipseHelper.ApproxPerimeter(topEllipse.XRadius, topEllipse.YRadius);
            //var botPerimeter = EllipseHelper.ApproxPerimeter(botEllipse.XRadius, botEllipse.YRadius);

            //return result;
            //if (topPerimeter > botPerimeter)
            //    return topOrientation;
            //else
            return(botOrientation);
        }
Exemplo n.º 4
0
        private Vector3D NewGetOrientation(
            Point[] topPnts,
            Point[] botPnts,
            EllipseParams topEllipse,
            EllipseParams botEllipse,
            Vector3D axisApproximation)
        {
            double mx = 0.0;
            double my = 0.0;

            foreach (Point pnt in topPnts)
            {
                mx += pnt.X;
                my += pnt.Y;
            }
            mx /= topPnts.Length;
            my /= topPnts.Length;
            double Cxx = 0.0;
            double Cyy = 0.0;
            double Cxy = 0.0;

            foreach (Point pnt in topPnts)
            {
                Cxx += Math.Pow(pnt.X - mx, 2.0);
                Cyy += Math.Pow(pnt.Y - my, 2.0);
                Cxy += (pnt.X - mx) * (pnt.Y - my);
            }
            Cxx *= 1.0 / topPnts.Length;
            Cyy *= 1.0 / topPnts.Length;
            Cxy *= 1.0 / topPnts.Length;
            double trC  = Cxx + Cyy;
            double detC = Cxx * Cyy - Cxy * Cxy;
            double l1   = 0.5 * trC + Math.Sqrt(0.25 * trC * trC - detC);
            double l2   = 0.5 * trC - Math.Sqrt(0.25 * trC * trC - detC);

            double a1 = 2 * Math.Sqrt(l1);
            double a2 = 2 * Math.Sqrt(l2);

            /*if (a1 < a2){
             *  double temp = a1;
             *  a1 = a2;
             *  a2 = temp;
             * }*/
            Vector3D ApproxOrientation1 = new Vector3D(Math.Sqrt(a1 * a1 - 4 * Cxx) / a1, Math.Sqrt(a1 * a1 - 4 * Cyy) / a1, a2 / a1);

            mx = 0.0;
            my = 0.0;
            foreach (Point pnt in botPnts)
            {
                mx += pnt.X;
                my += pnt.Y;
            }
            mx /= topPnts.Length;
            my /= topPnts.Length;
            Cxx = 0.0;
            Cyy = 0.0;
            Cxy = 0.0;

            foreach (Point pnt in botPnts)
            {
                Cxx += Math.Pow(pnt.X - mx, 2.0);
                Cyy += Math.Pow(pnt.Y - my, 2.0);
                Cxy += (pnt.X - mx) * (pnt.Y - my);
            }
            Cxx *= 1.0 / botPnts.Length;
            Cyy *= 1.0 / botPnts.Length;
            Cxy *= 1.0 / botPnts.Length;
            trC  = Cxx + Cyy;
            detC = Cxx * Cyy - Cxy * Cxy;
            l1   = 0.5 * trC + Math.Sqrt(0.25 * trC * trC - detC);
            l2   = 0.5 * trC - Math.Sqrt(0.25 * trC * trC - detC);

            a1 = 2 * Math.Sqrt(l1);
            a2 = 2 * Math.Sqrt(l2);

            /*if (a1 < a2){
             *  double temp = a1;
             *  a1 = a2;
             *  a2 = temp;
             * }*/
            Vector3D ApproxOrientation2 = new Vector3D(Math.Sqrt(a1 * a1 - 4 * Cxx) / a1, Math.Sqrt(a1 * a1 - 4 * Cyy) / a1, a2 / a1);
            short    sign = 1;

            if (Vector3D.DotProduct(ApproxOrientation2, ApproxOrientation1) < 0)
            {
                sign = -1;
            }

            Vector3D ApproxOrientation = 0.5 * (ApproxOrientation1.Normalized() + sign * ApproxOrientation2.Normalized());

            return(ApproxOrientation.Normalized());
        }
Exemplo n.º 5
0
        private Vector3D NewGetOrientation(
            Point[] topPnts,
            Point[] botPnts,
            EllipseParams topEllipse,
            EllipseParams botEllipse,
            Point[] spineApproximation,
            ref bool Reverse)
        {
            /*MessageBox.Show(String.Format("Ellipse Center : ({0},{1})", botEllipse.Center.X, botEllipse.Center.Y));
             * MessageBox.Show(String.Format("Ellipse Center : ({0},{1})", spineApproximation[0].X, -spineApproximation[0].Y));
             * MessageBox.Show(String.Format("Ellipse Center : ({0},{1})", spineApproximation[spineApproximation.Length - 1].X, -spineApproximation[spineApproximation.Length - 1].Y));*/
            int nspine = spineApproximation.Length;
            // Here we check whether the bottom feature curve is the start of the computed spine or the spine is reversed
            Vector vnormal  = new Vector(botEllipse.Center.X - spineApproximation[0].X, botEllipse.Center.Y + spineApproximation[0].Y);
            Vector vreverse = new Vector(botEllipse.Center.X - spineApproximation[spineApproximation.Length - 1].X, botEllipse.Center.Y + spineApproximation[spineApproximation.Length - 1].Y);

            Reverse = false;
            if (vnormal.Length > vreverse.Length)
            {
                Reverse = true;
            }
            Vector botAxis = new Vector();
            Vector topAxis = new Vector();

            if (!Reverse)
            {
                botAxis = new Vector(spineApproximation[1].X - spineApproximation[0].X, spineApproximation[0].Y - spineApproximation[1].Y);
                topAxis = new Vector(spineApproximation[nspine - 1].X - spineApproximation[nspine - 2].X, spineApproximation[nspine - 2].Y - spineApproximation[nspine - 1].Y);
            }
            else
            {
                topAxis = new Vector(spineApproximation[0].X - spineApproximation[1].X, spineApproximation[1].Y - spineApproximation[0].Y);
                botAxis = new Vector(spineApproximation[nspine - 2].X - spineApproximation[nspine - 1].X, spineApproximation[nspine - 1].Y - spineApproximation[nspine - 2].Y);
            }
            //MessageBox.Show(String.Format("Bottom Vector:{0}, {1}", botAxis.X, botAxis.Y));
            //MessageBox.Show(String.Format("Top Vector:{0}, {1}", topAxis.X, topAxis.Y));
            double mx = 0.0;
            double my = 0.0;

            foreach (Point pnt in topPnts)
            {
                mx += pnt.X;
                my += pnt.Y;
            }
            mx /= topPnts.Length;
            my /= topPnts.Length;
            double Cxx = 0.0;
            double Cyy = 0.0;
            double Cxy = 0.0;

            foreach (Point pnt in topPnts)
            {
                Cxx += Math.Pow(pnt.X - mx, 2.0);
                Cyy += Math.Pow(pnt.Y - my, 2.0);
                Cxy += (pnt.X - mx) * (pnt.Y - my);
            }
            Cxx /= topPnts.Length;
            Cyy /= topPnts.Length;
            Cxy /= topPnts.Length;
            double trC  = Cxx + Cyy;
            double detC = Cxx * Cyy - Cxy * Cxy;
            double l1   = 0.5 * trC + Math.Sqrt(0.25 * trC * trC - detC);
            double l2   = 0.5 * trC - Math.Sqrt(0.25 * trC * trC - detC);

            double   a1 = 2 * Math.Sqrt(l1);
            double   a2 = 2 * Math.Sqrt(l2);
            Vector3D ApproxOrientationTop     = new Vector3D(Math.Sqrt(a1 * a1 - 4 * Cxx) / a1, Math.Sqrt(a1 * a1 - 4 * Cyy) / a1, a2 / a1);
            Vector   ApproxOrientationTopProj = new Vector(ApproxOrientationTop.X, ApproxOrientationTop.Y);

            if (ApproxOrientationTopProj * topAxis < 0)
            {
                ApproxOrientationTop = -ApproxOrientationTop;
            }
            mx = 0; //botEllipse.Center.X;
            my = 0; // botEllipse.Center.Y;
            /*MessageBox.Show(String.Format("Number of points of bottom feature : {0}", botPnts.Length));*/

            foreach (Point pnt in botPnts)
            {
                mx += pnt.X;
                my += pnt.Y;
            }
            mx /= topPnts.Length;
            my /= topPnts.Length;

            Cxx = 0.0;
            Cyy = 0.0;
            Cxy = 0.0;

            foreach (Point pnt in botPnts)
            {
                Cxx += Math.Pow(pnt.X - mx, 2.0);
                Cyy += Math.Pow(pnt.Y - my, 2.0);
                Cxy += (pnt.X - mx) * (pnt.Y - my);
            }
            Cxx /= botPnts.Length;
            Cyy /= botPnts.Length;
            Cxy /= botPnts.Length;
            trC  = Cxx + Cyy;
            detC = Cxx * Cyy - Cxy * Cxy;
            l1   = 0.5 * trC + Math.Sqrt(0.25 * trC * trC - detC);
            l2   = 0.5 * trC - Math.Sqrt(0.25 * trC * trC - detC);
            //MessageBox.Show(String.Format("({0}, {1}), ({2}, {3})", 2*botEllipse.XRadius, 2*botEllipse.YRadius, 2 * Math.Sqrt(l1), 2 * Math.Sqrt(l2)));
            a1 = 2 * Math.Sqrt(l1);
            a2 = 2 * Math.Sqrt(l2);
            if (a1 < a2)
            {
                double temp = a1;
                a1 = a2;
                a2 = temp;
            }
            Vector3D ApproxOrientationBot     = new Vector3D(Math.Sqrt(a1 * a1 - 4 * Cxx) / a1, Math.Sqrt(a1 * a1 - 4 * Cyy) / a1, a2 / a1);
            Vector   ApproxOrientationBotProj = new Vector(ApproxOrientationBot.X, ApproxOrientationBot.Y);

            if (ApproxOrientationBotProj * botAxis < 0)
            {
                ApproxOrientationBot = -ApproxOrientationBot;
            }
            //MessageBox.Show(String.Format("Top Vector:{0}, {1}", botAxis.X, botAxis.Y));
            //MessageBox.Show(String.Format("Bottom Vector Estimation :{0}, {1}, {2}, {3}", ApproxOrientationBot.X, ApproxOrientationBot.Y, ApproxOrientationBot.Z, ApproxOrientationBot.Length));
            Vector3D ApproxOrientation = 0.5 * (ApproxOrientationTop.Normalized() + ApproxOrientationBot.Normalized());

            //return ApproxOrientation;

            /*if (Reverse)
             * {
             *  MessageBox.Show("Reverse!!!");
             *  return -ApproxOrientationBot.Normalized();
             * }*/
            //else
            return(ApproxOrientationBot.Normalized());
        }