示例#1
0
        public override bool HitTest(Ray3 ray, out double t)
        {
            ray = ray.Transform(InvPosition);

            double dx = ray.Direction.X;
            double dy = ray.Direction.Y;
            double dz = ray.Direction.Z;
            double x0 = ray.Position.X;
            double y0 = ray.Position.Y;
            double z0 = ray.Position.Z;

            double a = dx * dx * dx * dx + dy * dy * dy * dy + dz * dz * dz * dz;
            double b = 4.0 * dx * dx * dx * x0 + 4.0 * dy * dy * dy * y0 + 4.0 * dz * dz * dz;
            double c = 6.0 * dx * dx * x0 * x0 - 5.0 * dx * dx + 6.0 * dy * dy * y0 * y0 - 5.0 * dy * dy + 6.0 * dz * dz * z0 * z0 - 5.0 * dz * dz;
            double d = 4.0 * dx * x0 * x0 * x0 - 10.0 * dx * x0 + 4.0 * dy * y0 * y0 * y0 - 10.0 * dy * y0 + 4.0 * dz * z0 * z0 * z0;
            double e = x0 * x0 * x0 * x0 - 5.0 * x0 * x0 + y0 * y0 * y0 * y0 - 5.0 * y0 * y0 + z0 * z0 * z0 * z0 - 5.0 * z0 * z0 + 11.8;

            RealPolynomial poly = new RealPolynomial(a, b, c, d, e);
            //poly /= new RealPolynomial(100000);
            //poly.Normalize();

            double ev = poly.Eval(1.0);

            double[] cof = poly.FindRoots(MathUtil.Epsilon, false);
            //double[] cof=RealPolynomial.SolveQuartic(a, b, c, d, e);

            bool found = false;

            t = double.MaxValue;
            foreach (var tt in RealPolynomial.SolveQuadric(a, b, c))
            {
                if (tt > 1e-4 && tt < t)
                {
                    t     = tt;
                    found = true;
                }
            }

            return(found);
        }
示例#2
0
        private static double[] GetRealRoots(double c3, double c2, double c1, double c0)
        {
            RealPolynomial rp = new RealPolynomial(c3, c2, c1, c0);

            return(rp.FindRoots(true));
        }
示例#3
0
        public static Point2d[] EllipseCircle(Ellipse2d el, Circle2d ci)
        {
            Transform2d tr = el.ToStandardPosition;

            ci = new Circle2d(ci); //dont modify original circle, but this copy
            ci.Transform(tr);

            double b = el.Ratio, b2 = b * b, b4 = b2 * b2;
            double i = ci.Center.X, i2 = i * i, i4 = i2 * i2;
            double j = ci.Center.Y, j2 = j * j, j4 = j2 * j2;
            double r = ci.Radius, r2 = r * r, r4 = r2 * r2;

            double x4 = b4 - 2 * b2 + 1;
            double x3 = 4 * b2 * i - 4 * i;
            double x2 = b2 * (2 * r2 + 2 * j2 - 2 * i2 + 2) - 2 * r2 + 2 * j2 + 6 * i2 - 2 * b4;
            double x1 = 4 * i * r2 - 4 * i * j2 - 4 * i * i * i - 4 * b2 * i;
            double x0 = r4 + (-2 * j2 - 2 * i2) * r2 + b2 * (-2 * r2 - 2 * j2 + 2 * i2) + j4 + 2 * i2 * j2 + i4 + b4;
            //double[] xs = RealPolynomial.SolveQuartic2(x4, x3, x2, x1, x0, 1e-30);

            RealPolynomial rp = new RealPolynomial(x4, x3, x2, x1, x0);

            double[] xs = rp.FindRoots(true);

            if (xs == null)
            {
                return(null);               //no intersections
            }
            Point2dSet resultset = new Point2dSet();

            foreach (double x in xs)
            {
                //test the two possible y:s to be solutions for this x
                double y = (1 - x * x) * b2;
                if (y < 0.0)
                {
                    continue;
                }
                y = Math.Sqrt(y);

                for (int t = 0; t < 2; t++)                                             //test booth y solutions...
                {
                    double err  = x * x + y * y / b2 - 1.0;                             //on ellipse
                    double err2 = MathUtil.Square(x - i) + MathUtil.Square(y - j) - r2; //on circle
                    if (MathUtil.IsZero(err, 1e-7) && MathUtil.IsZero(err2, MathUtil.Epsilon))
                    {
                        resultset.Add(new Point2d(x, y));
                    }

                    y = -y;  // ...by inverting y in second turn
                }
            }

            if (resultset.Count == 0)
            {
                return(null);
            }

            resultset.Transform(tr.Inversed); //back to original position

            return(resultset.ToArray());
        }
示例#4
0
        public override bool HitTest(Ray3 ray, out double t)
        {
            ray = ray.Transform(InvPosition);

            double x0 = ray.Position.X;
            double y0 = ray.Position.Y;
            double z0 = ray.Position.Z;
            double dx = ray.Direction.X;
            double dy = ray.Direction.Y;
            double dz = ray.Direction.Z;


            double A  = x0 * x0 + y0 * y0 + z0 * z0;
            double B  = 2 * (x0 * dx + y0 * dy + z0 * dz);
            double R2 = R * R;
            double r2 = r * r;

            double t4 = A * A;
            double t3 = 2 * A * B;
            double t2 = 2 * A * R2 + B * B + 2 * A * A - 2 * r2 * A;
            double t1 = 2 * B * (R2 + A - r2);
            double t0 = (2 * A - 2 * r2) * R2 + A * A - 2 * r2 * A + r2 * r2;


            t2 -= 4 * R2 * (dx * dx + dy * dy);
            t1 -= 8 * R2 * (dx * x0 + dy * y0);
            t0 -= 4 * R2 * (x0 * x0 + y0 * y0);



            RealPolynomial rp = new RealPolynomial(t4, t3, 2, t1, t0);

            //rp.Normalize();
            double[] roots = rp.FindRoots();

            /*
             *
             * Vector3 p = ray.Position.ToVector();
             * Vector3 d = ray.Direction;
             *
             * double alpha = d.Dot(d);
             * double beta = 2.0 * p.Dot(d);
             * double gamma = p.Dot(p) - tubeRadius*tubeRadius - centralRadius*centralRadius;
             *
             * // quatric coefficients
             * double a4 = alpha*alpha;
             * double a3 = 2.0 * alpha * beta;
             * double a2 = beta*beta + (2.0 * alpha * gamma) + (4.0 * centralRadius*centralRadius * d.Z*d.Z);
             * double a1 = (2.0 * beta * gamma) + (8 * centralRadius*centralRadius * p.Z * d.Z);
             * double a0 = gamma*gamma + (4.0 * centralRadius*centralRadius * p.Z*p.Z) - (4.0 * centralRadius*centralRadius * tubeRadius*tubeRadius);
             *
             * // solve polynomial
             * double[] roots = RealPolynomial.SolveQuartic(a4, a3, a2, a1, a0);
             */
            bool found = false;

            t = double.MaxValue;
            foreach (var tt in roots)
            {
                if (tt > 1e-4 && tt < t)
                {
                    t     = tt;
                    found = true;
                }
            }

            return(found);
        }