如何在圆柱面上生成正则点 [英] How to generate regular points on cylindrical surface

查看:103
本文介绍了如何在圆柱面上生成正则点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Python的初学者,我必须使用Numpy进行项目. 我需要在圆柱体表面的一部分上生成一些点(例如,一百万个).这些点应规则地分布在由给定角度定义的表面子区域上.我该怎么做呢?

我的输入参数是:

    圆柱中心的
  1. position(例如[0,0,0])

  2. 圆柱体的orientation

  3. 圆柱体的
  4. length

  5. 圆柱体的
  6. radius

  7. angle(定义圆柱点上应该分布点的部分.)对于alpha = 360,整个表面

  8. delta_l是长度方向上每两个点之间的距离

  9. delta_alpha是沿alpha(旋转)方向的每两个点之间的距离

我的输出参数:

  • 包含所有点的坐标的数组

任何人都可以帮助我,或者给我一些有关如何执行此操作的提示吗?

非常感谢

解决方案

这取自我以前的项目:

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)

绘制的点:

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

旋转部分又快又脏-您应该仔细检查一下.得益于 unutbu .

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

解决方案

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])

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

这篇关于如何在圆柱面上生成正则点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆