python-vtk围绕行旋转actor

2024-07-08 16:23:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我是python和VTK新手,请耐心等待:)

简言之,我有一个演员,我想围绕我使用vtkLineSource()绘制的一条线旋转它。我选择了起点和终点,然后画了一条线。现在我想的是(如果我错了,请纠正我),我应该在直线上做一个轴,然后应用vtkTransformWXYZ()绕轴旋转。它不起作用,它会围绕所选的点进行奇怪的旋转,但不是我想要的。 我还尝试在我绘制的线的中间定义轴并对其应用旋转,但当我尝试时,它会围绕全局坐标旋转,而不是局部坐标。我也试着输入点或线,但同样,旋转非常奇怪

有没有办法将直线定义为一个轴,并围绕轴旋转演员?到目前为止,我尝试了以下例子:https://lorensen.github.io/VTKExamples/site/Python/PolyData/RotationAroundLine/https://lorensen.github.io/VTKExamples/site/Python/Rendering/Rotations/但是我的演员总是以一种奇怪的方式旋转

谁能帮我指一下正确的方向吗

这是我的代码中我试图旋转演员的部分

###################### create line to rotate about and display it

    lineStart = [16.8879, -106.476, -782.449]       
    lineFinish = [-17.827, -92.2757, lineStart[2]]
    lineMiddle = [(lineStart[0]+lineFinish[0])/2, (lineStart[1]+lineFinish[1])/2, lineStart[2]]
    
    lineSource = vtk.vtkLineSource()
    lineSource.SetPoint1(lineStart)
    lineSource.SetPoint2(lineFinish)
    lineSource.Update()
    
    mapperLine = vtk.vtkPolyDataMapper()
    mapperLine.SetInputConnection(lineSource.GetOutputPort())
    
    actorLine = vtk.vtkActor()
    actorLine.SetMapper(mapperLine)
    actorLine.GetProperty().SetLineWidth(4)
    actorLine.GetProperty().SetColor(1,0,0)
    ren.AddActor(actorLine)

############# rotate about the line

    modelMapper = vtk.vtkPolyDataMapper()
    modelMapper.SetInputData(cleanFilter.GetOutput())

    modelActor = vtk.vtkActor()
    modelActor.SetMapper(modelMapper)
    
    modelAxesSource = vtk.vtkAxes()
    modelAxesSource.SetScaleFactor(100)
    modelAxesSource.SetOrigin(lineMiddle)

    
    modelAxesMapper = vtk.vtkPolyDataMapper()
    modelAxesMapper.SetInputConnection(modelAxesSource.GetOutputPort())

    modelAxes = vtk.vtkActor()
    modelAxes.SetMapper(modelAxesMapper)


    ren.AddActor(modelAxes)
    modelAxes.VisibilityOn()
    ##this did not work
    ##modelActor.SetOrientation(lineMiddle)
    ##modelActor.RotateZ(45)
    ##ren.AddActor(modelActor)

transform = vtk.vtkTransform()
    transform.RotateWXYZ(45, lineMiddle)
    transformFilter = vtk.vtkTransformPolyDataFilter()
    transformFilter.SetTransform(transform)
    transformFilter.SetInputConnection(cleanFilter.GetOutputPort())
    transformFilter.Update()
    
    NewMapper = vtk.vtkPolyDataMapper()
    NewMapper.SetInputConnection(transformFilter.GetOutputPort())
    
    actorRotated = vtk.vtkActor()
    actorRotated.SetMapper(NewMapper)

    
    ren.AddActor(actorRotated)

我还尝试了以下方法:

    rotate = vtk.vtkRotationFilter()
    rotate.SetInputConnection(cleanFilter.GetOutputPort())
    rotate.SetAxisToY()
    rotate.SetCenter(lineMiddle)
    rotate.SetAngle(45)
    mapper = vtk.vtkDataSetMapper()
    mapper.SetInputConnection(rotate.GetOutputPort())
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    ren.AddActor(actor)

但它没有显示任何内容

感谢您的帮助

提前感谢,, 戴安娜


Tags: vtkrotate演员rengetoutputportsetinputconnectionlinestartaddactor
1条回答
网友
1楼 · 发布于 2024-07-08 16:23:34

您可能需要编写一些函数,如this

    def rotate(obj, angle, axis=(1, 0, 0), axis_point=(0, 0, 0), rad=False):
        """Rotate around an arbitrary `axis` passing through `axis_point`."""
        if rad:
            anglerad = angle
        else:
            anglerad = np.deg2rad(angle)
        axis = utils.versor(axis)
        a = np.cos(anglerad / 2)
        b, c, d = -axis * np.sin(anglerad / 2)
        aa, bb, cc, dd = a * a, b * b, c * c, d * d
        bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
        R = np.array(
            [
                [aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
                [2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
                [2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
            ]
        )
        rv = np.dot(R, obj.GetPosition() - np.array(axis_point)) + axis_point

        if rad:
            angle *= 180.0 / np.pi
        # this vtk method only rotates in the origin of the object:
        obj.RotateWXYZ(angle, axis[0], axis[1], axis[2])
        pbj.SetPosition(rv)

使用vedo测试它:

from vedo import *

c1 = Cube() # vtkActor
c2 = c1.clone().c('violet').alpha(0.5) # make a clone copy

v = vector(0.2,1,0)
p = vector(1,0,0)
c2.rotate(90, axis=v, point=p)

l = Line(-v+p, v+p).lw(3).c('red') # vtkActor
show(c1, c2, l, axes=1)

enter image description here

相关问题 更多 >

    热门问题