3

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

ali_m
  • 71,714
  • 23
  • 223
  • 298
user3397178
  • 63
  • 2
  • 9
  • write the equation for the x,y,z coordinates and use arrays of equally spaced angles and equally spaced lengths (use the linspace function) and tada... – Ben K. Mar 09 '14 at 18:45
  • what do you mean with equation for the x,y,z coordinates? I already created the gridded data set. But I dont know how I can lie points on the surface of cylinder? or what kind of transformation is needed? – user3397178 Mar 09 '14 at 19:25

1 Answers1

4

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.

Community
  • 1
  • 1
Daniel
  • 19,179
  • 7
  • 60
  • 74
  • Ophion many thanksss. But let me know where you used the orientation? How can we specify it? – user3397178 Mar 09 '14 at 20:57
  • I think you forgot about "#Orient tube to new vector". Thank you in advance – user3397178 Mar 09 '14 at 21:11
  • 1
    @user3397178 Actually I was hoping to get you far enough along to complete this yourself. In general SO frowns upon a complete "do this for me" question. – Daniel Mar 09 '14 at 21:43
  • many thanks for your help. Now I want to generate one point for each point in 3d as the point with offset. The new point should be in a specific distance from the old one which distributing by gaussian distribution. The angle of new point compared to old one is not important. I converted all points to spherical coordinates and I am trying to generate new points for r direction. no matter what are phi and theta. I used numpy.random.normal.. but it doesnt work. because it is generating some point over mean value and I need to generate these points for each point having 3d coordinates. – user3397178 Mar 16 '14 at 15:40
  • any idea would be appreciated. – user3397178 Mar 16 '14 at 15:41