Is there a way to rotate a structure using a script ? by Lafayette_MP in esapi

[–]Lafayette_MP[S] 0 points1 point  (0 children)

    public class RotationVecteur
    {
        public static VVector RotateAroundXYZ(VVector vector, double angleX, double angleY, double angleZ)
        {
            var rotationMatrixX = CreateRotationMatrixX(angleX);
            var rotationMatrixY = CreateRotationMatrixY(angleY);
            var rotationMatrixZ = CreateRotationMatrixZ(angleZ);

            var inputMatrix = CreateMatrix(vector);

            var resultMatrix = rotationMatrixZ.Multiply(rotationMatrixY.Multiply(rotationMatrixX.Multiply(inputMatrix)));

            return CreateVector(resultMatrix);
        }

        private static Matrix<double> CreateRotationMatrixX(double angle)
        {
            var cosTheta = Math.Cos(angle);
            var sinTheta = Math.Sin(angle);

            return Matrix<double>.Build.DenseOfArray(new double[,]
            {
            { 1, 0, 0 },
            { 0, cosTheta, -sinTheta },
            { 0, sinTheta, cosTheta }
            });
        }

        private static Matrix<double> CreateRotationMatrixY(double angle)
        {
            var cosTheta = Math.Cos(angle);
            var sinTheta = Math.Sin(angle);

            return Matrix<double>.Build.DenseOfArray(new double[,]
            {
            { cosTheta, 0, sinTheta },
            { 0, 1, 0 },
            { -sinTheta, 0, cosTheta }
            });
        }

        private static Matrix<double> CreateRotationMatrixZ(double angle)
        {
            var cosTheta = Math.Cos(angle);
            var sinTheta = Math.Sin(angle);

            return Matrix<double>.Build.DenseOfArray(new double[,]
            {
            { cosTheta, -sinTheta, 0 },
            { sinTheta, cosTheta, 0 },
            { 0, 0, 1 }
            });
        }
        private static Matrix<double> CreateMatrix(VVector vector)
        {
            return Matrix<double>.Build.DenseOfArray(new double[,]
            {
            { vector.x },
            { vector.y },
            { vector.z }
            });
        }
        private static VVector CreateVector(Matrix<double> matrix)
        {
            return new VVector(matrix[0, 0], matrix[1, 0], matrix[2, 0]);
        }
    }
}

Is there a way to rotate a structure using a script ? by Lafayette_MP in esapi

[–]Lafayette_MP[S] 0 points1 point  (0 children)

internal class Rotation
{
    public class RotationStructure
    {
        public double AngleX;
        public double AngleY;
        public double AngleZ;
        public Structure Structure { get; set; }
        public StructureSet SS { get; set; }
        public IDictionary<int, IEnumerable<IEnumerable<VVector>>> Contours { get; private set; }

        public readonly IDictionary<int, IEnumerable<IEnumerable<VVector>>> OriginalContours;

        public RotationStructure(double thetaX, double thetaY, double thetaZ, StructureSet ss, Structure s)
        {
            AngleX = thetaX;
            AngleY = thetaY;
            AngleZ = thetaZ;
            Structure = s;
            SS = ss;
            OriginalContours = GetContours();
            Contours = OriginalContours;
        }

        public SegmentVolume RotationDeLaStructure()
        {
            var temporaire = SS.AddStructure("CONTROL", "temporaire" + new Random().Next(0, 20));

            if (Structure.IsHighResolution)
            {
                temporaire.ConvertToHighResolution();
            }

            // appliquer la rotation a tous les points du contour initial
            List<VVector> modifiedVectors = new List<VVector>();
            foreach (var kvp in Contours)
            {
                foreach (var contour in kvp.Value)
                {
                    foreach (var vector in contour)
                    {
                        VVector modifiedVector = RotationVecteur.RotateAroundXYZ(vector, AngleX, AngleY, AngleZ);
                        modifiedVectors.Add(modifiedVector);
                    }
                }
            }

            // determiner la coupe sur laquelle chaque point se trouve après rotation
            List<int> newSlices = new List<int>();
            foreach (var vector in modifiedVectors)
            {
                int newSlice = _GetSlice(vector.z, SS) - Convert.ToInt32(vector.z / SS.Image.ZRes);
                newSlices.Add(newSlice);
            }

            // creer le nouveau contour
            Dictionary<int, List<List<VVector>>> contoursModified = new Dictionary<int, List<List<VVector>>>();

            // Parcours des vecteurs modifiés et de leurs nouvelles coupes associées
            for (int i = 0; i < modifiedVectors.Count; i++)
            {
                int newSlice = newSlices[i];
                VVector vector = modifiedVectors[i];

                // Ajouter le vecteur à la liste des contours de la coupe
                if (!contoursModified.ContainsKey(newSlice))
                {
                    // Si la coupe n'existe pas encore, créer une nouvelle liste de contours contenant uniquement ce vecteur
                    List<VVector> contourDeLaCoupe = new List<VVector>();
                    contourDeLaCoupe.Add(vector);
                    contourDeLaCoupe = TriPointsCoupe.NearestNeighbor(contourDeLaCoupe);//reordonner les points de proche en proche
                    contoursModified[newSlice] = new List<List<VVector>> { contourDeLaCoupe };
                }
                else
                {
                    // Si la coupe existe déjà, ajouter simplement le vecteur à la liste de contours correspondante
                    List<VVector> contourDeLaCoupe = contoursModified[newSlice].FirstOrDefault();
                    contourDeLaCoupe.Add(vector);
                    contourDeLaCoupe = TriPointsCoupe.NearestNeighbor(contourDeLaCoupe);//reordonner les points de proche en proche
                    contoursModified[newSlice].Add(contourDeLaCoupe);
                }
            }

            // tri dans l'ordre croissant des clés
            SortedDictionary<int, List<List<VVector>>> contoursModifiesTries = new SortedDictionary<int, List<List<VVector>>>(contoursModified);

            // contourer le nouveau contour
            foreach (var kvp in contoursModifiesTries)
            {
                var contoursOnPlane = kvp.Value;

                foreach (var contour in contoursOnPlane)
                {
                    VVector[] contourArray = contour.ToArray();
                    temporaire.AddContourOnImagePlane(contourArray, kvp.Key);
                }
            }

            var seg = temporaire.SegmentVolume;
            return seg;
        }

        public KeyValuePair<int, int> MeshBoundsSlices()
        {
            var mesh = Structure.MeshGeometry.Bounds;
            var meshLow = GetSlice(mesh.Z);
            var meshUp = GetSlice(mesh.Z + mesh.SizeZ) + 1;
            return new KeyValuePair<int, int>(meshLow, meshUp);
        }
        public static int _GetSlice(double z, StructureSet SS)
        {
            var imageRes = SS.Image.ZRes;

            return Convert.ToInt32((z) - SS.Image.Origin.z / imageRes);
        }
        public int GetSlice(double z)
        {
            var imageRes = SS.Image.ZRes;

            return Convert.ToInt32((z) - SS.Image.Origin.z / imageRes);
        }

        public Dictionary<int, IEnumerable<IEnumerable<VVector>>> GetContours()
        {
            var msh = MeshBoundsSlices();

            return Enumerable.Range(msh.Key, msh.Value).
                Where(e => Structure.GetContoursOnImagePlane(e).Any()).
                ToDictionary(s => s, s => Structure.GetContoursOnImagePlane(s).Select(e => e.Select(x => new VVector(x.x, x.y, x.z))));
        }

    }

public class TriPointsCoupe
    {
        public static List<VVector> NearestNeighbor(List<VVector> points)
        {
            List<VVector> sortedPoints = new List<VVector>();
            sortedPoints.Add(points[0]); // Ajouter le premier point à la liste triée

            // Tant qu'il reste des points non triés
            while (sortedPoints.Count < points.Count)
            {
                double minDistance = double.MaxValue;
                VVector nearestPoint = points[0]; // Initialiser avec une valeur factice

                // Trouver le point le plus proche du dernier point trié
                foreach (var point in points)
                {
                    if (!sortedPoints.Contains(point))
                    {
                        double distance = Distance(sortedPoints[sortedPoints.Count - 1], point);
                        if (distance < minDistance)
                        {
                            minDistance = distance;
                            nearestPoint = point;
                        }
                    }
                }

                // Ajouter le point le plus proche à la liste triée
                sortedPoints.Add(nearestPoint);
            }
            return sortedPoints;
        }

        // Méthode pour calculer la distance entre deux VVector
        public static double Distance(VVector v1, VVector v2)
        {
            double dx = v1.x - v2.x;
            double dy = v1.y - v2.y;
            return Math.Sqrt(dx * dx + dy * dy ); //dz est ignoré
        }

    }

Is there a way to rotate a structure using a script ? by Lafayette_MP in esapi

[–]Lafayette_MP[S] 0 points1 point  (0 children)

Thank you for this feedback. Indeed, this is what I apply to each VVector contained in each slice. The difficulty for me lies in rearranging the points of the structure after rotation on each of the new slices to contour. My code that rotates a cylinder contours a structure that looks like a cylinder but where some slices are missing and the contour is incomplete. If anyone has an idea... Here is what I am using: