简体   繁体   中英

Finding points on a cylinder in 3d room c#

Example Image here I am trying to find a way to calculate points on my cylinders top circle surface. My situation looks like this, I have a vector which is defining my cylinders direction in 3d room. Then I already calculated me a perpendicular vector with

Vector3.Cross(vector1, vector2)

Now I use the diameter/2 to calculate the point which is lying on the edge of the circular top surface of my cylinder. Now I want to rotate my vector always 90 degrees in order to get 4 points on the edge of the surface. All the 4 vectors defining them should be perpendicular to the cylinders direction. Can you help me how I can rotate the first perpendicular to achieve this?

I already tried:

Matrix4x4.CreateFromAxisAngle(vectorcylinderdirection, radiant)

Then I calculated again cross product but it doesnt work like I want to.

Edit:

        public static void calculatePontsOnCylinder()
    {

        //Calculate Orthogonal Vector to Direction
        Vector3 tCylinderDirection = new Vector3(1, 0, 0);
        Vector3 tOrthogonal = Vector3.Cross(tCylinderDirection, new Vector3(-tCylinderDirection.Z,tCylinderDirection.X,tCylinderDirection.Y));
        Vector3 tNormOrthogonal = Vector3.Normalize(tOrthogonal);

        //Calculate point on surface circle of cylinder
        //10mm radius
        int tRadius = 10;
        Vector3 tPointFinder = tNormOrthogonal * tRadius;

        //tPointFinder add the cylinder start point
        //not yet implemented

        //now i need to rotate the vector always 90 degrees to find the 3 other points on the circular top surface of the cylinder
        //don't know how to do this
        // I thought this should do it
        Matrix4x4.CreateFromAxisAngle(tCylinderDirection, (float)DegreeToRadian(90));



    }

    private static double DegreeToRadian(double angle)
    {
        return Math.PI * angle / 180.0;
    }

In the picture you can see a example, the vector1 is what I need, always rotated 90 degrees and vector2 would be my cylinder direction vector

I possibly have found the correct formula:

Vector3 tFinal = Vector3.Multiply((float)Math.Cos(DegreeToRadian(90)), tPointFinder) + Vector3.Multiply((float)Math.Sin(DegreeToRadian(90)), Vector3.Cross(tCylinderDirection, tPointFinder));
        Vector3 tFinal180 = Vector3.Multiply((float)Math.Cos(DegreeToRadian(180)), tPointFinder) + Vector3.Multiply((float)Math.Sin(DegreeToRadian(180)), Vector3.Cross(tCylinderDirection, tPointFinder));
        Vector3 tFinal270= Vector3.Multiply((float)Math.Cos(DegreeToRadian(270)), tPointFinder) + Vector3.Multiply((float)Math.Sin(DegreeToRadian(270)), Vector3.Cross(tCylinderDirection, tPointFinder));

Interesting is that if I try it with (1,1,0) as cylinder direction it gives me correct directions but the length is different for 90 degrees and 270.

Here is the code that should solve your problem assuming that the input requirements are satisfied.

        float zCutPlaneLocation = 20; // should not get bigger than cylinder length
        float cylinderRadius = 100;
        Vector3 cylinderCenter = new Vector3(0, 0, 0); // or whatever you got as cylinder center point, given as Vector3 since Point type is not defined

        // will return 360 points on cylinder edge, corresponding to this z section (cut plane),
        // another z section will give another 360 points and so on
        List<Vector3> cylinderRotatedPointsIn3D = new List<Vector3>();

        for (int angleToRotate = 0; angleToRotate < 360; angleToRotate++)
        {
            cylinderRotatedPointsIn3D.Add(GetRotatedPoint(zCutPlaneLocation, angleToRotate, cylinderRadius, cylinderCenter));
        }

         ....

       private static Vector3 GetRotatedPoint(
        float zLocation, double rotationAngleInRadian, float cylinderRadius, Vector3 cylinderCenter)
       {
        Vector2 cylinderCenterInSection = new Vector2(cylinderCenter.X, cylinderCenter.Y);

        float xOfRotatedPoint = cylinderRadius * (float)Math.Cos(rotationAngleInRadian);
        float yOfRotatedPoint = cylinderRadius * (float)Math.Sin(rotationAngleInRadian);

        Vector2 rotatedVector = new Vector2(xOfRotatedPoint, yOfRotatedPoint);
        Vector2 rotatedSectionPointOnCylinder = rotatedVector + cylinderCenterInSection;

        Vector3 rotatedPointOnCylinderIn3D = new Vector3(
                                                    rotatedSectionPointOnCylinder.X,
                                                    rotatedSectionPointOnCylinder.Y,
                                                    zLocation + cylinderCenter.Z);

        return rotatedPointOnCylinderIn3D;
       }

I just created a console app for this. First part of code should be added in main method. Working with those matrices seems is not that easy. Also I am not sure if your solution works ok for any kind of angle. Here the idea is that the rotated points from cylinder are calculated in a section of the cylinder so in 2D than the result is moved in 3D by just adding the z where the Z section was made on cylinder. I suppose that world axis and cylinder axis are on the same directions. Also if your cylinder gets along (increases) on the X axis, instead of Z axis as in example just switch in code the Z with X.

I attached also a picture图片 for more details. This should work if you have the cylinder center, radius, rotation angle and you know the length of the cylinder so that you create valid Z sections on cylinder. This could get tricky for clockwise/counter clock wise cases but lets see how it works for you.

If you want to handle this with matrices or whatever else I think that you will end up having this kind of result. So I think that you cannot have "all" the rotated points in just a list for the entire cylinder surface, they would depend on something like the rotated points of a Z section on the cylinder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM