python vtk 绕线旋转演员
python vtk rotate actor about line
我是 python 和 VTK 的新手所以请耐心等待 :)
简而言之,我有一个演员,我想围绕我使用 vtkLineSource() 绘制的一条线旋转它。我选择了起点和终点,然后画了线。现在我的想法是(如果我错了请纠正我)我应该在线上制作一个轴,然后应用 vtkTransformWXYZ() 绕轴旋转。它不起作用,它会围绕所选点进行奇怪的旋转,但不是我想要的旋转。
我还尝试在我绘制的线的中间定义轴并在其上应用旋转,但是当我尝试时,它围绕全局坐标旋转,而不是局部坐标。我也尝试将点或线作为输入,但同样,旋转非常奇怪。
有没有办法将线定义为轴并围绕它旋转演员?到目前为止,我尝试了以下示例:https://lorensen.github.io/VTKExamples/site/Python/PolyData/RotationAroundLine/ and https://lorensen.github.io/VTKExamples/site/Python/Rendering/Rotations/ 但我的演员总是以一种奇怪的方式旋转。
谁能help/point我在正确的方向吗?
这是我尝试旋转演员的代码部分……
###################### 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)
但它不显示任何内容。
感谢任何帮助!
提前致谢,
戴安娜
您可能需要编写一些函数,例如 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)
我是 python 和 VTK 的新手所以请耐心等待 :)
简而言之,我有一个演员,我想围绕我使用 vtkLineSource() 绘制的一条线旋转它。我选择了起点和终点,然后画了线。现在我的想法是(如果我错了请纠正我)我应该在线上制作一个轴,然后应用 vtkTransformWXYZ() 绕轴旋转。它不起作用,它会围绕所选点进行奇怪的旋转,但不是我想要的旋转。 我还尝试在我绘制的线的中间定义轴并在其上应用旋转,但是当我尝试时,它围绕全局坐标旋转,而不是局部坐标。我也尝试将点或线作为输入,但同样,旋转非常奇怪。
有没有办法将线定义为轴并围绕它旋转演员?到目前为止,我尝试了以下示例:https://lorensen.github.io/VTKExamples/site/Python/PolyData/RotationAroundLine/ and https://lorensen.github.io/VTKExamples/site/Python/Rendering/Rotations/ 但我的演员总是以一种奇怪的方式旋转。
谁能help/point我在正确的方向吗?
这是我尝试旋转演员的代码部分……
###################### 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)
但它不显示任何内容。
感谢任何帮助!
提前致谢, 戴安娜
您可能需要编写一些函数,例如 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)