Ejemplo n.º 1
0
        public bool HitsCircle(Circle3d circle, double tmin, double tmax, ref RayHit3d hit)
        {
            var dc = circle.Normal.Dot(Direction);
            var dw = circle.Normal.Dot(circle.Center - Origin);

            // If parallel to plane
            if (dc == 0.0)
            {
                return(false);
            }

            var t = dw / dc;

            if (!ComputeHit(t, tmin, tmax, ref hit))
            {
                return(false);
            }

            if (V3d.Distance(hit.Point, circle.Center) > circle.Radius)
            {
                hit.Point = V3d.NaN;
                hit.T     = tmax;
                return(false);
            }
            return(true);
        }
Ejemplo n.º 2
0
        // searches for oversized triangles and removes and adds all 3 vertex indices to invalid point list
        // (if one triangle side > maxTriangleSize => skip whole triangle)
        public static int[] GetAllPositionsFromOversizedTriangles(int[] invalidpositions, VertexGeometry vg, float maxTriangleSize)
        {
            var invalidPoints = new List <int>(invalidpositions);

            foreach (var t in vg.Triangles)
            {
                V3d p0, p1, p2;
                t.GetVertexPositions(out p0, out p1, out p2);

                if (p0.IsNaN || p1.IsNaN || p2.IsNaN)
                {
                    continue;
                }

                double dist_p0p1 = V3d.Distance(p0, p1);
                double dist_p0p2 = V3d.Distance(p0, p2);
                double dist_p1p2 = V3d.Distance(p1, p2);

                if ((dist_p0p1 > maxTriangleSize) || (dist_p0p2 > maxTriangleSize) || (dist_p1p2 > maxTriangleSize))
                {
                    foreach (var index in t.VertexIndices)
                    {
                        if (!Array.Exists(invalidPoints.ToArray(), x => x == index))
                        {
                            invalidPoints.Add(index);
                        }
                    }
                }
            }

            return(invalidPoints.ToArray());
        }
Ejemplo n.º 3
0
        public static double GetMinimalDistance(V3d p, V3d position, V3d direction, double majorRadius, double minorRadius)
        {
            var plane            = new Plane3d(direction, position);
            var planePoint       = p.GetClosestPointOn(plane);
            var distanceOnPlane  = (V3d.Distance(planePoint, position) - majorRadius).Abs();
            var distanceToCircle = (V3d.DistanceSquared(planePoint, p) + distanceOnPlane.Square()).Sqrt();

            return((distanceToCircle - minorRadius).Abs());
        }
Ejemplo n.º 4
0
        public V3d GetClosestPoint(V3d point)
        {
            var ray    = new Ray3d(Origin, Direction);
            var cp     = point.GetClosestPointOn(ray);
            var radius = GetRadius(GetHeight(point));
            var dir    = (point - cp).Normalized * radius;

            var p0 = cp + dir;
            var p1 = point.GetClosestPointOn(new Ray3d(Origin, (p0 - Origin).Normalized));

            return((V3d.Distance(point, p1) < V3d.Distance(point, p0)) ? p1 : p0);
        }
        /// <summary>
        /// Gets Triangle Set loaded from AaraData and transformed to global space.
        /// Triangles side length < maxTriiangleSize
        /// </summary>
        public static TriangleSet LoadPatchTriangleSetWithoutOversizedTriangles(PatchFileInfo info, string basePath, PositionsType posType, float maxTriangleSize = float.PositiveInfinity)
        {
            var vg = LoadPatch(info, basePath, posType, false, false, false, false);

            if (vg == null)
            {
                return(new TriangleSet());
            }

            vg.Transform(
                posType == PositionsType.V3dPositions ?
                info.Local2Global : info.Local2Global2d);

            var triangles = vg.Triangles
                            .Where(x => !x.Point0.Position.IsNaN &&
                                   !x.Point1.Position.IsNaN &&
                                   !x.Point2.Position.IsNaN &&
                                   (V3d.Distance(x.Point0.Position, x.Point1.Position) < maxTriangleSize) &&
                                   (V3d.Distance(x.Point0.Position, x.Point2.Position) < maxTriangleSize) &&
                                   (V3d.Distance(x.Point1.Position, x.Point2.Position) < maxTriangleSize))
                            .Select(x => x.ToTriangle3d());

            return(new TriangleSet(triangles));
        }
Ejemplo n.º 6
0
 /// <summary>
 /// if zero, point is located on cone
 /// </summary>
 public double GetDistance(V3d point)
 {
     return(V3d.Distance(point, GetClosestPoint(point)));
 }
Ejemplo n.º 7
0
 /// <summary>
 /// if zero, point is located on cone
 /// </summary>
 public double GetDistance(V3d point) => V3d.Distance(point, GetClosestPoint(point));
Ejemplo n.º 8
0
        public bool HitsCylinder(Cylinder3d cylinder,
                                 double tmin, double tmax,
                                 ref RayHit3d hit)
        {
            var axisDir = cylinder.Axis.Direction.Normalized;

            // Vector Cyl.P0 -> Ray.Origin
            var op = Origin - cylinder.P0;

            // normal RayDirection - CylinderAxis
            var normal     = Direction.Cross(axisDir);
            var unitNormal = normal.Normalized;

            // normal (Vec Cyl.P0 -> Ray.Origin) - CylinderAxis
            var normal2 = op.Cross(axisDir);
            var t       = -normal2.Dot(unitNormal) / normal.Length;

            var radius = cylinder.Radius;

            if (cylinder.DistanceScale != 0)
            {   // cylinder gets bigger, the further away it is
                var pnt = GetPointOnRay(t);

                var dis = V3d.Distance(pnt, this.Origin);
                radius = ((cylinder.Radius / cylinder.DistanceScale) * dis) * 2;
            }

            // between enitre rays (caps are ignored)
            var shortestDistance = Fun.Abs(op.Dot(unitNormal));

            if (shortestDistance <= radius)
            {
                var s = Fun.Abs(Fun.Sqrt(radius.Square() - shortestDistance.Square()) / Direction.Length);

                var t1 = t - s; // first hit of Cylinder shell
                var t2 = t + s; // second hit of Cylinder shell

                if (t1 > tmin && t1 < tmax)
                {
                    tmin = t1;
                }
                if (t2 < tmax && t2 > tmin)
                {
                    tmax = t2;
                }

                hit.T     = t1;
                hit.Point = GetPointOnRay(t1);

                // check if found point is outside of Cylinder Caps
                var bottomPlane  = new Plane3d(cylinder.Circle0.Normal, cylinder.Circle0.Center);
                var topPlane     = new Plane3d(cylinder.Circle1.Normal, cylinder.Circle1.Center);
                var heightBottom = bottomPlane.Height(hit.Point);
                var heightTop    = topPlane.Height(hit.Point);
                // t1 lies outside of caps => find closest cap hit
                if (heightBottom > 0 || heightTop > 0)
                {
                    hit.T = tmax;
                    // intersect with bottom Cylinder Cap
                    var bottomHit = HitsPlane(bottomPlane, tmin, tmax, ref hit);
                    // intersect with top Cylinder Cap
                    var topHit = HitsPlane(topPlane, tmin, tmax, ref hit);

                    // hit still close enough to cylinder axis?
                    var distance = cylinder.Axis.Ray3d.GetMinimalDistanceTo(hit.Point);

                    if (distance <= radius && (bottomHit || topHit))
                    {
                        return(true);
                    }
                }
                else
                {
                    return(true);
                }
            }

            hit.T     = tmax;
            hit.Point = V3d.NaN;
            return(false);
        }
Ejemplo n.º 9
0
        // searches for oversized triangles and adds only invalid indices to invalid point list
        // (keep vertex indices for triangle side < maxTriangleSize)
        public static int[] GetInvalidPositionsFromOversizedTriangles(int[] invalidpositions, VertexGeometry vg, float maxTriangleSize)
        {
            var invalidPoints = new List <int>(invalidpositions);

            foreach (var t in vg.Triangles)
            {
                V3d p0, p1, p2;
                t.GetVertexPositions(out p0, out p1, out p2);

                if (p0.IsNaN || p1.IsNaN || p2.IsNaN)
                {
                    continue;
                }

                List <V3d> vertexlist = new List <V3d>();
                int        p0_counter = 0;
                int        p1_counter = 0;
                int        p2_counter = 0;
                if (V3d.Distance(p0, p1) > maxTriangleSize)
                {
                    vertexlist.Add(p0); vertexlist.Add(p1);
                }
                if (V3d.Distance(p0, p2) > maxTriangleSize)
                {
                    vertexlist.Add(p0); vertexlist.Add(p2);
                }
                if (V3d.Distance(p1, p2) > maxTriangleSize)
                {
                    vertexlist.Add(p1); vertexlist.Add(p2);
                }
                foreach (var p in vertexlist)
                {
                    if (p == p0)
                    {
                        p0_counter++;
                    }
                    if (p == p1)
                    {
                        p1_counter++;
                    }
                    if (p == p2)
                    {
                        p2_counter++;
                    }
                }

                if ((p0_counter > 1) && (!Array.Exists(invalidPoints.ToArray(), x => x == t.VertexIndex0)))
                {
                    invalidPoints.Add(t.VertexIndex0);
                }
                if ((p1_counter > 1) && (!Array.Exists(invalidPoints.ToArray(), x => x == t.VertexIndex1)))
                {
                    invalidPoints.Add(t.VertexIndex1);
                }
                if ((p2_counter > 1) && (!Array.Exists(invalidPoints.ToArray(), x => x == t.VertexIndex2)))
                {
                    invalidPoints.Add(t.VertexIndex2);
                }
            }

            return(invalidPoints.ToArray());
        }