Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
399 views
in Technique[技术] by (71.8m points)

python - How to generate regular points on cylindrical surface

I am a beginner in Python and I have to work on a project using Numpy. I need to generate some points (e.g. one million) on one part of the surface of a cylinder. These points should be regularly distributed on a subregion of the surface defined by a given angle. How could I go about doing this?

My input parameters are:

  1. position of the center of cylinder (e.g. [0,0,0] )

  2. the orientation of cylinder

  3. length of cylinder

  4. radius of cylinder

  5. angle (this defines the part of cylinder which the points should be distributed on it.) for alpha = 360, the whole surface

  6. delta_l is the distance between each two points in the length direction

  7. delta_alpha is the distance between each two points in the alpha (rotation) direction

My output parameters :

  • an array containing the coordinates of all points

Could anyone help me, or give me a hint about how to do this?

Many thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is taken from a previous project of mine:

def make_cylinder(radius, length, nlength, alpha, nalpha, center, orientation):

    #Create the length array
    I = np.linspace(0, length, nlength)

    #Create alpha array avoid duplication of endpoints
    #Conditional should be changed to meet your requirements
    if int(alpha) == 360:
        A = np.linspace(0, alpha, num=nalpha, endpoint=False)/180*np.pi
    else:
        A = np.linspace(0, alpha, num=nalpha)/180*np.pi

    #Calculate X and Y
    X = radius * np.cos(A)
    Y = radius * np.sin(A)

    #Tile/repeat indices so all unique pairs are present
    pz = np.tile(I, nalpha)
    px = np.repeat(X, nlength)
    py = np.repeat(Y, nlength)

    points = np.vstack(( pz, px, py )).T

    #Shift to center
    shift = np.array(center) - np.mean(points, axis=0)
    points += shift

    #Orient tube to new vector

    #Grabbed from an old unutbu answer
    def rotation_matrix(axis,theta):
        a = np.cos(theta/2)
        b,c,d = -axis*np.sin(theta/2)
        return np.array([[a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(b*d+a*c)],
                         [2*(b*c+a*d), a*a+c*c-b*b-d*d, 2*(c*d-a*b)],
                         [2*(b*d-a*c), 2*(c*d+a*b), a*a+d*d-b*b-c*c]])

    ovec = orientation / np.linalg.norm(orientation)
    cylvec = np.array([1,0,0])

    if np.allclose(cylvec, ovec):
        return points

    #Get orthogonal axis and rotation
    oaxis = np.cross(ovec, cylvec)
    rot = np.arccos(np.dot(ovec, cylvec))

    R = rotation_matrix(oaxis, rot)
    return points.dot(R)

Plotted points for:

points = make_cylinder(3, 5, 5, 360, 10, [0,2,0], [1,0,0])

Cylinder

The rotation part is quick and dirty- you should likely double check it. Euler-Rodrigues formula thanks to unutbu.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...