Пример #1
0
        /// <summary>
        /// Does this ray intersect with the provided face?
        /// </summary>
        /// <param name="face">The Face to intersect with.</param>
        /// <param name="result">The intersection result.</param>
        /// <returns>True if an intersection occurs, otherwise false. If true, check the intersection result for the location of the intersection.</returns>
        internal bool Intersects(Face face, out Vector3 result)
        {
            var plane = face.Plane();

            if (Intersects(plane, out Vector3 intersection))
            {
                var boundaryPolygon      = face.Outer.ToPolygon();
                var voids                = face.Inner?.Select(v => v.ToPolygon())?.ToList();
                var transformToPolygon   = new Transform(plane.Origin, plane.Normal);
                var transformFromPolygon = new Transform(transformToPolygon);
                transformFromPolygon.Invert();
                var transformedIntersection  = transformFromPolygon.OfVector(intersection);
                IEnumerable <Line> curveList = boundaryPolygon.Segments();
                if (voids != null)
                {
                    curveList = curveList.Union(voids.SelectMany(v => v.Segments()));
                }
                curveList = curveList.Select(l => l.TransformedLine(transformFromPolygon));

                if (Polygon.Contains(curveList, transformedIntersection, out _))
                {
                    result = intersection;
                    return(true);
                }
            }
            result = default(Vector3);
            return(false);
        }
Пример #2
0
        /// <summary>
        /// Does this ray intersect with the provided GeometricElement? Only GeometricElements with Solid Representations are currently supported, and voids will be ignored.
        /// </summary>
        /// <param name="element">The element to intersect with.</param>
        /// <param name="result">The list of intersection results.</param>
        /// <returns></returns>
        public bool Intersects(GeometricElement element, out List <Vector3> result)
        {
            if (element.Representation == null || element.Representation.SolidOperations == null || element.Representation.SolidOperations.Count == 0)
            {
                element.UpdateRepresentations();
            }
            List <Vector3> resultsOut           = new List <Vector3>();
            var            transformFromElement = new Transform(element.Transform);

            transformFromElement.Invert();
            var transformToElement = new Transform(element.Transform);
            var transformedRay     = new Ray(transformFromElement.OfPoint(Origin), transformFromElement.OfVector(Direction));
            //TODO: extend to handle voids when void solids in Representations are supported generally
            var intersects = false;

            foreach (var solidOp in element.Representation.SolidOperations.Where(e => !e.IsVoid))
            {
                if (transformedRay.Intersects(solidOp, out List <Vector3> tempResults))
                {
                    intersects = true;
                    resultsOut.AddRange(tempResults.Select(t => transformToElement.OfPoint(t)));
                }
                ;
            }
            result = resultsOut;
            return(intersects);
        }
Пример #3
0
        /// <summary>
        /// Does this ray intersect with the provided GeometricElement? Only GeometricElements with Solid Representations are currently supported, and voids will be ignored.
        /// </summary>
        /// <param name="element">The element to intersect with.</param>
        /// <param name="result">The list of intersection results.</param>
        /// <returns></returns>
        public bool Intersects(GeometricElement element, out List <Vector3> result)
        {
            List <Vector3> resultsOut           = new List <Vector3>();
            var            transformFromElement = new Transform(element.Transform);

            transformFromElement.Invert();
            var transformToElement        = new Transform(element.Transform);
            var transformMinusTranslation = new Transform(transformFromElement);

            // This transform ignores position so it can be used to transform the ray direction vector
            transformMinusTranslation.Move(transformMinusTranslation.Origin.Negate());

            var transformedRay = new Ray(transformFromElement.OfPoint(Origin), transformMinusTranslation.OfVector(Direction));
            //TODO: extend to handle voids when void solids in Representations are supported generally
            var intersects = false;

            foreach (var solidOp in element.Representation.SolidOperations.Where(e => !e.IsVoid))
            {
                if (transformedRay.Intersects(solidOp, out List <Vector3> tempResults))
                {
                    intersects = true;
                    resultsOut.AddRange(tempResults.Select(t => transformToElement.OfPoint(t)));
                }
                ;
            }
            result = resultsOut;
            return(intersects);
        }
Пример #4
0
        /// <summary>
        /// Calculate a counter-clockwise plane angle between this vector and the provided vector, projected to the plane perpendicular to the provided normal.
        /// </summary>
        /// <param name="v">The vector with which to measure the angle.</param>
        /// <param name="normal">The normal of the plane in which you wish to calculate the angle.</param>
        /// <returns>Angle in degrees between 0 and 360, or NaN if the projected input vectors are invalid.</returns>
        public double PlaneAngleTo(Vector3 v, Vector3 normal)
        {
            var transformFromPlane = new Transform(Vector3.Origin, normal);

            transformFromPlane.Invert();
            var thisTransformed  = transformFromPlane.OfVector(this);
            var otherTransformed = transformFromPlane.OfVector(v);
            // project to Plane
            Vector3 a = new Vector3(thisTransformed.X, thisTransformed.Y, 0);
            Vector3 b = new Vector3(otherTransformed.X, otherTransformed.Y, 0);

            // reject very small vectors
            if (a.Length() < Vector3.EPSILON || b.Length() < Vector3.EPSILON)
            {
                return(double.NaN);
            }

            Vector3 aUnitized = a.Unitized();
            Vector3 bUnitized = b.Unitized();

            // Cos^-1(a dot b), a dot b clamped to [-1, 1]
            var angle = Math.Acos(Math.Max(Math.Min(aUnitized.Dot(bUnitized), 1.0), -1.0));

            if (Math.Abs(angle) < Vector3.EPSILON)
            {
                return(0);
            }
            // check if should be reflex angle
            Vector3 aCrossB = aUnitized.Cross(bUnitized).Unitized();

            if (Vector3.ZAxis.Dot(aCrossB) > 0)
            {
                return(angle * 180 / Math.PI);
            }
            else
            {
                return((Math.PI * 2 - angle) * 180 / Math.PI);
            }
        }
Пример #5
0
    public static UnityEngine.Vector3[] ToUnityVertices(this double[] arr, Elements.Geometry.Transform t)
    {
        var verts = new UnityEngine.Vector3[arr.Length / 3];
        var index = 0;

        for (var i = 0; i < arr.Length / 3; i += 3)
        {
            var vt = t != null?t.OfVector(new Vector3(arr[i], arr[i + 1], arr[i + 2])) : new Vector3(arr[i], arr[i + 1], arr[i + 2]);

            var v = vt.ToUnityVector3();
            verts[index] = v;
            index++;
        }
        return(verts);
    }
Пример #6
0
        /// <summary>
        /// Does this ray intersect with the provided face?
        /// </summary>
        /// <param name="face">The Face to intersect with.</param>
        /// <param name="result">The intersection result.</param>
        /// <returns>True if an intersection occurs, otherwise false. If true, check the intersection result for the location of the intersection.</returns>
        internal bool Intersects(Face face, out Vector3 result)
        {
            var plane = face.Plane();

            if (Intersects(plane, out Vector3 intersection))
            {
                var boundaryPolygon      = face.Outer.ToPolygon();
                var transformToPolygon   = new Transform(plane.Origin, plane.Normal);
                var transformFromPolygon = new Transform(transformToPolygon);
                transformFromPolygon.Invert();
                var transformedPolygon      = transformFromPolygon.OfPolygon(boundaryPolygon);
                var transformedIntersection = transformFromPolygon.OfVector(intersection);
                if (transformedPolygon.Contains(transformedIntersection) || transformedPolygon.Touches(transformedIntersection))
                {
                    result = intersection;
                    return(true);
                }
            }
            result = default(Vector3);
            return(false);
        }
Пример #7
0
        /// <summary>
        /// Does this ray intersect the provided polygon area?
        /// </summary>
        /// <param name="polygon">The Polygon to intersect with.</param>
        /// <param name="result">The intersection result.</param>
        /// <returns>True if an intersection occurs, otherwise false. If true, check the intersection result for the location of the intersection.</returns>
        public bool Intersects(Polygon polygon, out Vector3 result)
        {
            var plane = new Plane(polygon.Vertices.First(), polygon.Vertices);

            if (Intersects(plane, out Vector3 intersection))
            {
                var transformToPolygon   = new Transform(plane.Origin, plane.Normal);
                var transformFromPolygon = new Transform(transformToPolygon);
                transformFromPolygon.Invert();
                var transformedIntersection  = transformFromPolygon.OfVector(intersection);
                IEnumerable <Line> curveList = polygon.Segments();
                curveList = curveList.Select(l => l.TransformedLine(transformFromPolygon));

                if (Polygon.Contains(curveList, transformedIntersection, out _))
                {
                    result = intersection;
                    return(true);
                }
            }
            result = default(Vector3);
            return(false);
        }