0

Python の Pyglet ライブラリを使用して 3D でネットワークを描画しようとしています。

タンパク質を表す球があり、それらを 0,0,0 で描画して位置に変換するのではなく、(x、y、z 座標を指定して) その場で描画します。私は今それらをシリンダーに接続しようとしています。これを行うには、各球座標を中心とする頂点の円を計算し、それらを四角形で接続します。

ただし、2 つの円が互いに向き合うように頂点を計算しようとすると、ちょっとした障害に遭遇しました。

これまでの私のコードは次のとおりです。

class Cylinder(object):
    def __init__(self, start, end, radius, slices, batch, group=None):
        """
        :param start: The (x,y,z) coordinates of the cylinder's start point
        :type start: (float, float, float)
        :param end: The (x,y,z) coordinates of the cylinder's end point
        :type end: (float, float, float)
        :param radius: The radius of the cylinder
        :type radius: float
        :param slices: Number of sections to divide the cylinder into
        :type slices: int
        :param batch: The pyglet batch to add the cylinder to
        :type batch: pyglet.graphics.Batch
        :param group: The pyglet group to add the cylinder to
        :type group: int
        """
        self.start_x, self.start_y, self.start_z = start
        self.end_x, self.end_y, self.end_z = end

        self.num_vertices = 6 * slices
        self.num_faces = slices
        self.num_indexes = 4 * self.num_faces

        self.vertices = numpy.zeros(self.num_vertices, dtype=numpy.float)
        self.normals = numpy.zeros(self.num_vertices, dtype=numpy.float)
        self.indexes = numpy.zeros(self.num_indexes, dtype=numpy.uint32)

        step = 2 * pi / slices
        lat = 0
        lon = 0
        for i in xrange(slices):
            sin_lat = sin(lat)
            cos_lat = cos(lat)
            sin_lon = sin(lon)
            cos_lon = cos(lon)

            # Calculate vertex positions
            sx = self.start_x + radius * cos_lon * sin_lat
            sy = self.start_y + radius * sin_lon * sin_lat
            sz = self.start_z + radius * cos_lat
            ex = self.end_x + radius * cos_lon * sin_lat
            ey = self.end_y + radius * sin_lon * sin_lat
            ez = self.end_z + radius * cos_lat

            # Calculate vertex normals
            snx = cos_lon * sin_lat
            sny = sin_lon * sin_lat
            snz = cos_lat
            enx = cos_lon * sin_lat
            eny = sin_lon * sin_lat
            enz = cos_lat

            # Add vertex positions and normals to
            index = 6 * i
            self.vertices[index:index + 6] = (sx, sy, sz, ex, ey, ez)
            self.normals[index:index + 6] = (snx, sny, snz, enx, eny, enz)

            # Go to next vertex pair
            lat += step

        for i in xrange(slices):
            self.indexes[4 * i:4 * i + 4] = ((2 * i),
                                             (2 * i + 2) % (self.num_vertices // 3),
                                             (2 * i + 3) % (self.num_vertices // 3),
                                             (2 * i + 1))

        if batch:
            self.vertex_list = batch.add_indexed(len(self.vertices) // 3,
                                                 gl.GL_QUADS,
                                                 group,
                                                 self.indexes,
                                                 ('v3f/static', self.vertices),
                                                 ('n3f/static', self.normals))

    def delete(self):
        self.vertex_list.delete()

どんな助けでも大歓迎です!

4

1 に答える 1

0

なぜあなたは互いに向き合う円が必要なのでしょうか?

チューブを作成するには、次のアルゴリズムが必要です。

  1. AからBまでのベクトルABを計算し、それは垂直(ノルム)です。
  2. チューブ半径でノルムをスケーリング
  3. 頂点の追加を開始して、セグメント数Segでチューブを作成します。

    I := 0;
    for K := 0 to Seg-1 do
    begin
      TubeCos := Cos(K/Seg*2*pi);
      TubeSin := Sin(K/Seg*2*pi);
      Vert[I].Normal := (-Norm.X*TubeSin, TubeCos, -Norm.Y*TubeSin);
      Vert[I].Vert := (A.X-Norm.X*TubeRad*TubeSin, TubeRad*TubeCos, A.Y-Norm.Y*TubeRad*TubeSin);
      I++;
      Vert[I].Normal := (-Norm.X*TubeSin, TubeCos, -Norm.Y*TubeSin);
      Vert[I].VertB := (B.X-Norm.X*TubeRad*TubeSin, TubeRad*TubeCos, B.Y-Norm.Y*TubeRad*TubeSin);
      I++;
    end;
    
  4. 頂点を三角形に接続します(順序は重要です)//この例では、0-1-2、2-3-1、2-3-4、4-5-3、..。

于 2013-03-22T06:00:00.240 に答える