コード例 #1
0
ファイル: ellipse.cs プロジェクト: stephensmitchell-forks/OCL
        /// offset-ellipse Brent solver

        /// offfset-ellipse solver using Brent's method
        /// find the EllipsePosition that makes the offset-ellipse point be at p
        /// this is a zero of Ellipse::error()
        /// returns number of iterations
        ///
        /// called (only?) by BullCutter::singleEdgeDropCanonical()
        public int solver_brent()
        {
            int             iters = 1;
            EllipsePosition apos  = new EllipsePosition();            // Brent's method requires bracketing the root in [apos.diangle, bpos.diangle]
            EllipsePosition bpos  = new EllipsePosition();

            apos.setDiangle(0.0);
            Debug.Assert(apos.isValid());
            bpos.setDiangle(3.0);
            Debug.Assert(bpos.isValid());
            if (Math.Abs(error(apos)) < DefineConstants.OE_ERROR_TOLERANCE)
            {                                    // if we are lucky apos is the solution
                EllipsePosition1.CopyFrom(apos); // and we do not need to search further.
                find_EllipsePosition2();
                return(iters);
            }
            else if (Math.Abs(error(bpos)) < DefineConstants.OE_ERROR_TOLERANCE)
            {             // or bpos might be the solution?
                EllipsePosition1.CopyFrom(bpos);
                find_EllipsePosition2();
                return(iters);
            }
            // neither apos nor bpos is the solution
            // but root is now bracketed, so we can use brent_zero
            Debug.Assert(error(apos) * error(bpos) < 0.0);
            // this looks for the diangle that makes the offset-ellipse point y-coordinate zero
            double dia_sln = ocl.GlobalMembers.brent_zero(apos.diangle, bpos.diangle, 3E-16, DefineConstants.OE_ERROR_TOLERANCE, this);             // brent_zero.hpp

            EllipsePosition1.setDiangle(dia_sln);
            Debug.Assert(EllipsePosition1.isValid());
            // because we only work with the y-coordinate of the offset-ellipse-point, there are two symmetric solutions
            find_EllipsePosition2();
            return(iters);
        }
コード例 #2
0
ファイル: ellipse.cs プロジェクト: stephensmitchell-forks/OCL
        /// aligned offset-ellipse solver. callsn Numeric::brent_solver()

        // used by BullCutter pushcutter edge-test
        public bool aligned_solver(Fiber f)
        {
            error_dir.CopyFrom(f.dir.xyPerp()); // now calls to error(diangle) will give the right error
            Debug.Assert(error_dir.xyNorm() > 0.0);
            target.CopyFrom(f.p1);              // target is either x or y-coord of f.p1
            // find position(s) where ellipse tangent is parallel to fiber. Here error() will be minimized/maximized.
            // tangent at point is:  -a t + b s = -a*major_dir*t + b*minor_dir*s
            // -at ma.y + bs mi.y = 0   for X-fiber
            // s = sqrt(1-t^2)
            //  -a*ma.y * t + b*mi.y* sqrt(1-t^2) = 0
            //  =>  t^2 = b^2 / (a^2 + b^2)
            double t1 = 0.0;

            if (f.p1.y == f.p2.y)
            {
                t1 = Math.Sqrt(ocl.GlobalMembers.square(b * minor_dir.y) / (ocl.GlobalMembers.square(a * major_dir.y) + ocl.GlobalMembers.square(b * minor_dir.y)));
            }
            else if (f.p1.x == f.p2.x)
            {
                t1 = Math.Sqrt(ocl.GlobalMembers.square(b * minor_dir.x) / (ocl.GlobalMembers.square(a * major_dir.x) + ocl.GlobalMembers.square(b * minor_dir.x)));
            }
            else
            {
                Debug.Assert(false);
            }
            // bracket root
            EllipsePosition tmp            = new EllipsePosition();
            EllipsePosition apos           = new EllipsePosition();
            EllipsePosition bpos           = new EllipsePosition();
            double          s1             = Math.Sqrt(1.0 - ocl.GlobalMembers.square(t1));
            bool            found_positive = false;
            bool            found_negative = false;

            tmp.setDiangle(GlobalMembers.xyVectorToDiangle(s1, t1));
            if (error(tmp.diangle) > 0)
            {
                found_positive = true;
                apos.CopyFrom(tmp);
            }
            else if (error(tmp.diangle) < 0)
            {
                found_negative = true;
                bpos.CopyFrom(tmp);
            }
            tmp.setDiangle(GlobalMembers.xyVectorToDiangle(s1, -t1));
            if (error(tmp.diangle) > 0)
            {
                found_positive = true;
                apos.CopyFrom(tmp);
            }
            else if (error(tmp.diangle) < 0)
            {
                found_negative = true;
                bpos.CopyFrom(tmp);
            }
            tmp.setDiangle(GlobalMembers.xyVectorToDiangle(-s1, t1));
            if (error(tmp.diangle) > 0)
            {
                found_positive = true;
                apos.CopyFrom(tmp);
            }
            else if (error(tmp.diangle) < 0)
            {
                found_negative = true;
                bpos.CopyFrom(tmp);
            }
            tmp.setDiangle(GlobalMembers.xyVectorToDiangle(-s1, -t1));
            if (error(tmp.diangle) > 0)
            {
                found_positive = true;
                apos.CopyFrom(tmp);
            }
            else if (error(tmp.diangle) < 0)
            {
                found_negative = true;
                bpos.CopyFrom(tmp);
            }

            if (found_positive)
            {
                if (found_negative)
                {
                    Debug.Assert(this.error(apos.diangle) * this.error(bpos.diangle) < 0.0);                     // root is now bracketed.
                    double lolim = 0.0;
                    double hilim = 0.0;
                    if (apos.diangle > bpos.diangle)
                    {
                        lolim = bpos.diangle;
                        hilim = apos.diangle;
                    }
                    else if (bpos.diangle > apos.diangle)
                    {
                        hilim = bpos.diangle;
                        lolim = apos.diangle;
                    }
                    double dia_sln  = ocl.GlobalMembers.brent_zero(lolim, hilim, 3E-16, DefineConstants.OE_ERROR_TOLERANCE, this);
                    double dia_sln2 = ocl.GlobalMembers.brent_zero(hilim - 4.0, lolim, 3E-16, DefineConstants.OE_ERROR_TOLERANCE, this);

                    EllipsePosition1.setDiangle(dia_sln);
                    EllipsePosition2.setDiangle(dia_sln2);

                    Debug.Assert(EllipsePosition1.isValid());
                    Debug.Assert(EllipsePosition2.isValid());

                    /*
                     * // FIXME. This assert fails in some cases (30sphere.stl z=0, for example)
                     * // FIXME. The allowed error should probably be in proportion to the difficulty of the case.
                     *
                     * if (!isZero_tol( error(EllipsePosition1.diangle) )) {
                     *  std::cout << "AlignedEllipse::aligned_solver() ERROR \n";
                     *  std::cout << "error(EllipsePosition1.diangle)= "<< error(EllipsePosition1.diangle) << " (expected zero)\n";
                     *
                     * }
                     * assert( isZero_tol( error(EllipsePosition1.diangle) ) );
                     * assert( isZero_tol( error(EllipsePosition2.diangle) ) );
                     */

                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
ファイル: ellipse.cs プロジェクト: stephensmitchell-forks/OCL
        /// given one EllipsePosition solution, find the other.
        // #define DEBUG_SOLVER
        //
        // given a known EllipsePosition1, look for the other symmetric
        // solution EllipsePosition2
        public bool find_EllipsePosition2()
        {         // a horrible horrible function... :(
            Debug.Assert(EllipsePosition1.isValid());
            double err1 = Math.Abs(this.error(this.EllipsePosition1));

            this.EllipsePosition2.s = this.EllipsePosition1.s;             // plus
            this.EllipsePosition2.t = -this.EllipsePosition1.t;            // minus
            if (Math.Abs(this.error(this.EllipsePosition2)) < err1 + DefineConstants.OE_ERROR_TOLERANCE)
            {
                if ((Math.Abs(this.EllipsePosition2.s - this.EllipsePosition1.s) > 1E-8) || (Math.Abs(this.EllipsePosition2.t - this.EllipsePosition1.t) > 1E-8))
                {
                                        #if DEBUG_SOLVER
                    Console.Write("2nd: (s, t)= ");
                    Console.Write(this.EllipsePosition2);
                    Console.Write(" oePoint()= ");
                    Console.Write(this.oePoint(this.EllipsePosition2));
                    Console.Write(" e=");
                    Console.Write(this.error(this.EllipsePosition2));
                    Console.Write("\n");
                                        #endif
                    return(true);
                }
            }

            this.EllipsePosition2.s = -this.EllipsePosition1.s;
            this.EllipsePosition2.t = this.EllipsePosition1.t;
            if (Math.Abs(this.error(this.EllipsePosition2)) < err1 + DefineConstants.OE_ERROR_TOLERANCE)
            {
                if ((Math.Abs(this.EllipsePosition2.s - this.EllipsePosition1.s) > 1E-8) || (Math.Abs(this.EllipsePosition2.t - this.EllipsePosition1.t) > 1E-8))
                {
                                        #if DEBUG_SOLVER
                    Console.Write("2nd: (s, t)= ");
                    Console.Write(this.EllipsePosition2);
                    Console.Write(" oePoint()= ");
                    Console.Write(this.oePoint(this.EllipsePosition2));
                    Console.Write(" e=");
                    Console.Write(this.error(this.EllipsePosition2));
                    Console.Write("\n");
                                        #endif
                    return(true);
                }
            }

            this.EllipsePosition2.s = -this.EllipsePosition1.s;
            this.EllipsePosition2.t = -this.EllipsePosition1.t;
            if (Math.Abs(this.error(this.EllipsePosition2)) < err1 + DefineConstants.OE_ERROR_TOLERANCE)
            {
                if ((Math.Abs(this.EllipsePosition2.s - this.EllipsePosition1.s) > 1E-8) || (Math.Abs(this.EllipsePosition2.t - this.EllipsePosition1.t) > 1E-8))
                {
                                        #if DEBUG_SOLVER
                    Console.Write("2nd: (s, t)= ");
                    Console.Write(this.EllipsePosition2);
                    Console.Write(" oePoint()= ");
                    Console.Write(this.oePoint(this.EllipsePosition2));
                    Console.Write(" e=");
                    Console.Write(this.error(this.EllipsePosition2));
                    Console.Write("\n");
                                        #endif
                    return(true);
                }
            }

            // last desperate attempt is identical solutions
            this.EllipsePosition2.s = this.EllipsePosition1.s;
            this.EllipsePosition2.t = this.EllipsePosition1.t;
            if (Math.Abs(this.error(this.EllipsePosition2)) < err1 + DefineConstants.OE_ERROR_TOLERANCE)
            {
                // DON'T require solutions to differ
                // if ( (fabs(this->EllipsePosition2.s - this->EllipsePosition1.s) > 1E-8) || (fabs(this->EllipsePosition2.t - this->EllipsePosition1.t) > 1E-8) ) {
                                        #if DEBUG_SOLVER
                Console.Write("2nd: (s, t)= ");
                Console.Write(this.EllipsePosition2);
                Console.Write(" oePoint()= ");
                Console.Write(this.oePoint(this.EllipsePosition2));
                Console.Write(" e=");
                Console.Write(this.error(this.EllipsePosition2));
                Console.Write("\n");
                                        #endif
                //std::cout << " find_EllipsePosition2() desperate-mode\n";
                return(true);
                //}
            }
            Console.Write("Ellipse::find_EllipsePosition2 cannot find EllipsePosition2! \n");
            Console.Write("ellipse= ");
            Console.Write(this);
            Console.Write("\n");
            print_solutions();
            Debug.Assert(false);             // serious error if we get here!

            return(false);
        }