예제 #1
0
        public override CartesianList <Point> Visit(Line line)
        {
            CartesianList <Point> intersections = new CartesianList <Point>();

            //      this = 0       line = 1
            // x = v0 + t0 * i0 = v1 + t1 * i1
            // k0.dot(x) = k0.dot(v1) + t1 * k0.dot(i1) = k0.dot(v0)
            // k1.dot(x) = k1.dot(v0) + t0 * k1.dot(i0) = k1.dot(v1)
            // t0 = k1.dot(v1 - v0) / k1.dot(i0)
            // t1 = k0.dot(v0 - v1) / k0.dot(i1)

            double den0 = line.KHat.Dot(this.IHat);
            double den1 = this.KHat.Dot(line.IHat);

            if (System.Math.Abs(den0) > Constants.tol)
            {
                double t0 = line.KHat.Dot(line.Vertex - this.Vertex) / den0;
                double t1 = this.KHat.Dot(this.Vertex - line.Vertex) / den1;

                if (this.Contains(t0) && line.Contains(t1))
                {
                    intersections.Add(GetPoint(t0));
                }
            }

            return(intersections);
        }
예제 #2
0
        private void AddSite(Point tail, Point head)
        {
            PointSite ps = new PointSite(tail, pointSitePrefab, spheres);

            if (!pointSites.ContainsNear(ps))
            {
                pointSites.Add(ps);
                sites.Add(ps);
            }

            LineSite ls = new LineSite(tail, head, lineSitePrefab, cylinders);

            if (!lineSites.Contains(ls))
            {
                lineSites.Add(ls);
                sites.Add(ls);
            }
        }
예제 #3
0
        public override CartesianList <Point> Visit(Line line)
        {
            CartesianList <Point> intersections = new CartesianList <Point>();
            List <double>         solutions     = new List <double>();

            // p = v + x * ihat + z * khat
            // n.dot(p) = n.dot(p0)
            // n.dot(v + x*ihat + z*khat) = n.dot(p0)
            // n.dot(ihat) * x + n.dot(khat) * z = n.dot(p0) - n.dot(v)
            // a*x + b*z = c

            Vector n = line.KHat;

            double a = n.Dot(ihat);
            double b = n.Dot(khat);
            double c = n.Dot(line.Vertex - vertex);

            // z = x^2 / r
            // a*x + b*x^2/r = c
            // t^2 + (a*r/b)*t - c*r/b = 0
            // t^2 + a*r/b*t + a^2*r^2/4*b^2 = a^2*r^2/4*b^2 + c*r/b
            // (t + a*r/2*b)^2 = (1/4*b^2)*(a^2*r^2 + 4*b*c*r)
            // t + a*r/2*b = +- sqrt(r*(a^2*r + 4*b*c)) / 2*b
            // t = (-a*r +- sqrt(r*(a^2*r + 4*b*c)) / 2*b

            double discriminant = latusRectum * (a * a * latusRectum + 4.0 * b * c);

            if (System.Math.Abs(b) > Constants.tol)
            {
                if (System.Math.Abs(discriminant) < Constants.tol)
                {
                    double t = -0.5 * a * latusRectum / b;
                    solutions.Add(t);
                }
                else if (discriminant > Constants.tol)
                {
                    double sqrt = System.Math.Sqrt(discriminant);
                    double t0   = -0.5 * (a * latusRectum - sqrt) / b;
                    double t1   = -0.5 * (a * latusRectum + sqrt) / b;

                    solutions.Add(t0);
                    solutions.Add(t1);
                }
                else
                {
                    // no solution
                }
            }
            else if (System.Math.Abs(a) > Constants.tol)
            {
                double t = c / a;
                solutions.Add(t);
            }

            foreach (double t in solutions)
            {
                if (this.Contains(t))
                {
                    Point p = GetPoint(t);
                    if (line.Contains(p))
                    {
                        intersections.Add(p);
                    }
                }
            }

            return(intersections);
        }
예제 #4
0
        public void Generate()
        {
            wall2point = new Point[maze.Length, 4];

            for (int iwall = 0; iwall < maze.Length; ++iwall)
            {
                Transform wall = maze[iwall];

                for (int icorner = 0; icorner < 4; ++icorner)
                {
                    Point p = Corner(wall, icorner);

                    if (points.ContainsNear(p))
                    {
                        p = points.GetNear(p);
                    }
                    else
                    {
                        points.Add(p);

                        List <WallIndex> walls = new List <WallIndex>();
                        point2wall.Add(p, walls);
                    }

                    point2wall[p].Add(new WallIndex(iwall, icorner));
                    wall2point[iwall, icorner] = p;
                }
            }

            WallIndex currentWall = new WallIndex(0, 2);
            Point     current     = vertices.AddNear(LookupPoint(currentWall));
            Point     first       = current;

            Point     prev     = null;
            WallIndex peekWall = null;
            Point     peek     = null;

            for (int ii = 0; ii < 100; ++ii)
            {
                prev = current;

                currentWall = FindNextWall(currentWall).Rotate;

                current = LookupPoint(currentWall);
                if (current.IsCoincident(first))
                {
                    edges.Add(new PolygonEdge(prev, first));
                    break;
                }

                // combine parallel wall edges
                for (int jj = 0; jj < 5; ++jj)
                {
                    peekWall = FindNextWall(currentWall).Rotate;

                    peek = LookupPoint(peekWall);
                    Vector v0 = current - prev;
                    Vector v1 = peek - current;

                    if (v1.IsParallel(v0)) // (peek - current).IsParallel(current - prev))
                    {
                        currentWall = peekWall;
                        current     = peek;
                    }
                    else
                    {
                        break;
                    }
                }

                current = vertices.AddNear(current);
                edges.Add(new PolygonEdge(prev, current));
            }

            DetermineBounds();
        }