コード例 #1
0
        public static bool FindClosestRayIntersection(ISampledCurve3d c, double segRadius, Ray3d ray, out double minRayT)
        {
            minRayT = double.MaxValue;
            int nNearSegment = -1;

            int nSegs = c.SegmentCount;

            for (int i = 0; i < nSegs; ++i)
            {
                Segment3d seg = c.GetSegment(i);

                // raycast to line bounding-sphere first (is this going ot be faster??)
                double fSphereHitT;
                bool   bHitBoundSphere = RayIntersection.SphereSigned(ref ray.Origin, ref ray.Direction,
                                                                      ref seg.Center, seg.Extent + segRadius, out fSphereHitT);
                if (bHitBoundSphere == false)
                {
                    continue;
                }

                double rayt, segt;
                double dSqr = DistRay3Segment3.SquaredDistance(ref ray, ref seg, out rayt, out segt);
                if (dSqr < segRadius * segRadius)
                {
                    if (rayt < minRayT)
                    {
                        minRayT      = rayt;
                        nNearSegment = i;
                    }
                }
            }
            return(nNearSegment >= 0);
        }
コード例 #2
0
        // will return null if no edges need to be split!
        public List <Vector3d> SplitResample(ISampledCurve3d curve, double fMaxEdgeLen)
        {
            double fMaxSqr = fMaxEdgeLen * fMaxEdgeLen;

            int N     = curve.VertexCount;
            int Nstop = (curve.Closed) ? N + 1 : N;

            if (lengths == null || lengths.Length < Nstop)
            {
                lengths = new double[Nstop];
            }
            bool bFoundSplit = false;

            for (int i = 0; i < Nstop; ++i)
            {
                lengths[i] = curve.GetVertex(i).DistanceSquared(curve.GetVertex((i + 1) % N));
                if (lengths[i] > fMaxSqr)
                {
                    bFoundSplit = true;
                }
            }
            if (!bFoundSplit)
            {
                return(null);
            }


            List <Vector3d> vNew = new List <Vector3d>();
            Vector3d        prev = curve.GetVertex(0);

            vNew.Add(prev);
            for (int i = 0; i < Nstop - 1; ++i)
            {
                Vector3d next = curve.GetVertex((i + 1) % N);

                if (lengths[i] > fMaxSqr)
                {
                    double fLen   = Math.Sqrt(lengths[i]);
                    int    nSteps = (int)(fLen / fMaxEdgeLen) + 1;
                    for (int k = 1; k < nSteps; ++k)
                    {
                        double   t   = (double)k / (double)nSteps;
                        Vector3d mid = Vector3d.Lerp(prev, next, t);
                        vNew.Add(mid);
                    }
                }
                vNew.Add(next);
                prev = next;
            }

            return(vNew);
        }
コード例 #3
0
        public static int FindNearestIndex(ISampledCurve3d c, Vector3d v)
        {
            int    iNearest = -1;
            double dNear    = Double.MaxValue;
            int    N        = c.VertexCount;

            for (int i = 0; i < N; ++i)
            {
                double dSqr = (c.GetVertex(i) - v).LengthSquared;
                if (dSqr < dNear)
                {
                    dNear    = dSqr;
                    iNearest = i;
                }
            }
            return(iNearest);
        }
コード例 #4
0
        public static bool FindClosestRayIntersection(ISampledCurve3d c, double segRadius, Ray3d ray, out double rayT)
        {
            rayT = double.MaxValue;
            int nNearSegment = -1;
            //double fNearSegT = 0.0;

            int N     = c.VertexCount;
            int iStop = (c.Closed) ? N : N - 1;

            for (int i = 0; i < iStop; ++i)
            {
                DistRay3Segment3 dist = new DistRay3Segment3(ray,
                                                             new Segment3d(c.GetVertex(i), c.GetVertex((i + 1) % N)));

                // raycast to line bounding-sphere first (is this going ot be faster??)
                double fSphereHitT;
                bool   bHitBoundSphere = RayIntersection.SphereSigned(ray.Origin, ray.Direction,
                                                                      dist.Segment.Center, dist.Segment.Extent + segRadius, out fSphereHitT);
                if (bHitBoundSphere == false)
                {
                    continue;
                }

                // find ray/seg min-distance and use ray T
                double dSqr = dist.GetSquared();
                if (dSqr < segRadius * segRadius)
                {
                    if (dist.RayParameter < rayT)
                    {
                        rayT = dist.RayParameter;
                        //fNearSegT = dist.SegmentParameter;
                        nNearSegment = i;
                    }
                }
            }
            return(nNearSegment >= 0);
        }
コード例 #5
0
 public DCurve3(ISampledCurve3d icurve)
 {
     this.vertices = new List <Vector3d>(icurve.Vertices);
     Closed        = icurve.Closed;
     Timestamp     = 1;
 }
コード例 #6
0
        // will return null if no edges need to be split!
        public List <Vector3d> SplitCollapseResample(ISampledCurve3d curve, double fMaxEdgeLen, double fMinEdgeLen)
        {
            double fMaxSqr = fMaxEdgeLen * fMaxEdgeLen;
            double fMinSqr = fMinEdgeLen * fMinEdgeLen;

            int N     = curve.VertexCount;
            int Nstop = (curve.Closed) ? N + 1 : N;

            if (lengths == null || lengths.Length < Nstop)
            {
                lengths = new double[Nstop];
            }
            bool bFoundSplit    = false;
            bool bFoundCollapse = false;

            for (int i = 0; i < Nstop - 1; ++i)
            {
                lengths[i] = curve.GetVertex(i).DistanceSquared(curve.GetVertex((i + 1) % N));
                if (lengths[i] > fMaxSqr)
                {
                    bFoundSplit = true;
                }
                else if (lengths[i] < fMinSqr)
                {
                    bFoundCollapse = true;
                }
            }
            if (bFoundSplit == false && bFoundCollapse == false)
            {
                return(null);
            }


            List <Vector3d> vNew = new List <Vector3d>();
            Vector3d        prev = curve.GetVertex(0);

            vNew.Add(prev);
            double collapse_accum = 0;

            for (int i = 0; i < Nstop - 1; ++i)
            {
                Vector3d next = curve.GetVertex((i + 1) % N);

                // accumulate collapsed edges. if we accumulate past min-edge length,
                // then need to drop a vertex
                if (lengths[i] < fMinSqr)
                {
                    collapse_accum += Math.Sqrt(lengths[i]);
                    if (collapse_accum > fMinEdgeLen)
                    {
                        collapse_accum = 0;
                        vNew.Add(next);
                    }
                    prev = next;
                    continue;
                }

                // if we have been accumulating collapses, then we need to
                // drop a new vertex  (todo: is this right? shouldn't we just
                //   continue from previous?)
                if (collapse_accum > 0)
                {
                    vNew.Add(prev);
                    collapse_accum = 0;
                }

                // split edge if it is too long
                if (lengths[i] > fMaxSqr)
                {
                    double fLen   = Math.Sqrt(lengths[i]);
                    int    nSteps = (int)(fLen / fMaxEdgeLen) + 1;
                    for (int k = 1; k < nSteps; ++k)
                    {
                        double   t   = (double)k / (double)nSteps;
                        Vector3d mid = Vector3d.Lerp(prev, next, t);
                        vNew.Add(mid);
                    }
                }
                vNew.Add(next);
                prev = next;
            }

            return(vNew);
        }