def move(self, x, y, width, height): self.currentPos = self.mapToSphere(x, y, width, height) self._axis = QVector3D.crossProduct(self.lastPos, self.currentPos) length = math.sqrt(QVector3D.dotProduct(self.axis, self.axis)) self.angle = QVector3D.dotProduct(self.lastPos, self.currentPos) self.lastPos = self.currentPos if length > EPSILON: return QQuaternion.fromAxisAndAngle(self._axis, self.angle) return QQuaternion.fromAxisAndAngle(0, 0, 0, 0)
def createScene(): # Root entity. rootEntity = QEntity() # Material. material = QPhongMaterial(rootEntity) # Torus. torusEntity = QEntity(rootEntity) torusMesh = QTorusMesh() torusMesh.setRadius(5) torusMesh.setMinorRadius(1) torusMesh.setRings(100) torusMesh.setSlices(20) torusTransform = QTransform() torusTransform.setScale3D(QVector3D(1.5, 1.0, 0.5)) torusTransform.setRotation( QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0)) torusEntity.addComponent(torusMesh) torusEntity.addComponent(torusTransform) torusEntity.addComponent(material) # Sphere. sphereEntity = QEntity(rootEntity) sphereMesh = QSphereMesh() sphereMesh.setRadius(3) sphereEntity.addComponent(sphereMesh) sphereEntity.addComponent(material) return rootEntity
def generateData(self): # 生成模拟数据 magneticFieldArray = [] for i in range(self.m_fieldLines): horizontalAngle = (self.doublePi * i) / self.m_fieldLines xCenter = self.ellipse_a * math.cos(horizontalAngle) zCenter = self.ellipse_a * math.sin(horizontalAngle) # Rotate - arrow is always tangential to the origin. # 旋转-箭头始终与原点相切。 yRotation = QQuaternion.fromAxisAndAngle( 0.0, 1.0, 0.0, horizontalAngle * self.radiansToDegrees) for j in range(self.m_arrowsPerLine): # Calculate the point on the ellipse centered on the origin and # 计算椭圆上以原点为中心的点 # parallel to the x-axis. # 平行于X轴。 verticalAngle = ((self.doublePi * j) / self.m_arrowsPerLine) + self.m_angleOffset xUnrotated = self.ellipse_a * math.cos(verticalAngle) y = self.ellipse_b * math.sin(verticalAngle) # Rotate the ellipse around the y-axis. # 围绕Y轴旋转椭圆。 xRotated = xUnrotated * math.cos(horizontalAngle) zRotated = xUnrotated * math.sin(horizontalAngle) # Add the offset. # 添加偏移量。 x = xCenter + xRotated z = zCenter + zRotated zRotation = QQuaternion.fromAxisAndAngle( 0.0, 0.0, 1.0, verticalAngle * self.radiansToDegrees) totalRotation = yRotation * zRotation itm = QScatterDataItem(QVector3D(x, y, z), totalRotation) magneticFieldArray.append(itm) if self.m_graph.selectedSeries() is self.m_magneticField: self.m_graph.clearSelection() self.m_magneticField.dataProxy().resetArray(magneticFieldArray)
def mouseMoveEvent(self, event): """ Called by the Qt libraries whenever the window receives a mouse move/drag event. """ btns = event.buttons() # pixel coordinates relative to the window x = event.localPos().x() y = event.localPos().y() if btns & Qt.LeftButton: # Rotation via emulated trackball using quaternions. # For method employed see: # https://en.wikipedia.org/wiki/Quaternions_and_spatial_rotation # get current vector from sphere/trackball center to surface mouse_rotation_current_vec = self._find_trackball_vector(x, y) # get the angle between the vector which was stored at the # time of mouse click and the current vector angle_between = PainterWidget.angle_between( mouse_rotation_current_vec, self._mouse_rotation_start_vec) angle_between *= 20 # arbitrary amplification for faster rotation # get the rotation axis which is perpendicular to both vectors rotation_axis = QVector3D.crossProduct( self._mouse_rotation_start_vec, mouse_rotation_current_vec) # create a rotated normalized quaternion corresponding to the # drag distance travelled by the mouse since the click delta = QQuaternion.fromAxisAndAngle(rotation_axis, angle_between) delta.normalize() # rotate self._rotation_quat (used to rotate the View matrix) self._rotation_quat = delta * self._rotation_quat_start self._rotation_quat.normalize() elif btns & Qt.MidButton: # Translation left/right and up/down depending on camera orientation diff = QVector3D(x, y, 0) - self._mouse_translation_start_vec diff_x = diff[0] diff_y = diff[1] self._translation_vec = self._translation_vec_start - self.cam_right * diff_x * 2 + self.cam_up * diff_y * 2 elif btns & Qt.RightButton: # Translation forward/backward depending on camera orientation diff_y = y - self._mouse_camforward_start self._translation_vec = self._translation_vec_start - self.cam_look * diff_y * 2 # re-draw at next timer tick self.dirty = True
def rotation(self): """Returns rotation quarternion""" if self._paused or self._pressed: return self._rotation currentTime = QTime.currentTime() angle = self._angularVelocity * self._lastTime.msecsTo(currentTime) return QQuaternion.fromAxisAndAngle(self._axis, angle) * self._rotation
def move(self, point, quat): """Move trackball""" if not self._pressed: return currentTime = QTime.currentTime() msecs = self._lastTime.msecsTo(currentTime) if msecs <= 20: return if self._mode == self.TrackballMode.Planar: delta = QLineF(self._lastPos, point) self._angularVelocity = 180.0 * delta.length() / (math.pi * msecs) self._axis = QVector3D(-delta.dy(), delta.dx(), 0.0).normalized() self._axis = quat.rotatedVector(self._axis) self._rotation = QQuaternion.fromAxisAndAngle(self._axis, 180.0 / math.pi * delta.length()) * self._rotation elif self._mode == self.TrackballMode.Spherical: lastPos3D = QVector3D(self._lastPos.x(), self._lastPos.y(), 0.0) sqrZ = 1.0 - QVector3D.dotProduct(lastPos3D, lastPos3D) if sqrZ > 0: lastPos3D.setZ(math.sqrt(sqrZ)) else: lastPos3D.normalize() currentPos3D = QVector3D(point.x(), point.y(), 0.0) sqrZ = 1.0 - QVector3D.dotProduct(currentPos3D, currentPos3D) if sqrZ > 0: currentPos3D.setZ(math.sqrt(sqrZ)) else: currentPos3D.normalize() self._axis = QVector3D.crossProduct(lastPos3D, currentPos3D) angle = 180.0 / math.pi * math.asin(math.sqrt(QVector3D.dotProduct(self._axis, self._axis))) self._angularVelocity = angle / msecs self._axis.normalize() self._axis = quat.rotatedVector(self._axis) self._rotation = QQuaternion.fromAxisAndAngle(self._axis, angle) * self._rotation self._lastPos = point self._lastTime = currentTime
def createScene(): # Root entity rootEntity = QEntity() # Material material = QPhongMaterial(rootEntity) # Torus torusEntity = QEntity(rootEntity) # Qt3DExtras.QTorusMesh * torusMesh = QTorusMesh() torusMesh.setRadius(5) torusMesh.setMinorRadius(1) torusMesh.setRings(100) torusMesh.setSlices(20) # Qt3DCore.QTransform * torusTransform = QTransform() torusTransform.setScale3D(QVector3D(1.5, 1, 0.5)) torusTransform.setRotation( QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45.0)) torusEntity.addComponent(torusMesh) torusEntity.addComponent(torusTransform) torusEntity.addComponent(material) # Sphere sphereEntity = QEntity(rootEntity) sphereMesh = QSphereMesh() sphereMesh.setRadius(3) # Qt3DCore.QTransform * sphereTransform = QTransform() # OrbitTransformController * controller = OrbitTransformController(sphereTransform) controller.setTarget(sphereTransform) controller.setRadius(20.0) # QPropertyAnimation * sphereRotateTransformAnimation = QPropertyAnimation(sphereTransform) sphereRotateTransformAnimation.setTargetObject(controller) sphereRotateTransformAnimation.setPropertyName(b"angle") sphereRotateTransformAnimation.setStartValue(0) sphereRotateTransformAnimation.setEndValue(360) sphereRotateTransformAnimation.setDuration(10000) sphereRotateTransformAnimation.setLoopCount(-1) sphereRotateTransformAnimation.start() sphereEntity.addComponent(sphereMesh) sphereEntity.addComponent(sphereTransform) sphereEntity.addComponent(material) return rootEntity
def createScene(self): # root rootEntity = QSkyboxEntity() material = QPhongMaterial(rootEntity) #skybox = QSkyboxEntity(rootEntity) # torus cubeEntity = QEntity(rootEntity) cubeMesh = QCuboidMesh() cubeTransform = QTransform() #cubeMaterial = getRgbCubeMaterial(cubeEntity) cubeMaterial = QPhongMaterial(cubeEntity) cubeTransform.setTranslation(QVector3D(5.0, -4.0, 0.0)) cubeTransform.setScale(4.0) cubeTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45)) cubeEntity.addComponent(cubeMesh) cubeEntity.addComponent(cubeTransform) cubeEntity.addComponent(cubeMaterial) return rootEntity
def create_matrix(model, links, frames, bf): # ローカル位置 trans_vs = [QVector3D() for i in range(len(links))] # 加算用クォータニオン add_qs = [QQuaternion() for i in range(len(links))] for lidx, lbone in enumerate(reversed(links)): # 位置 if lidx == 0: # 一番親は、グローバル座標を考慮 trans_vs[lidx] = lbone.position + calc_bone_by_complement( frames, lbone.name, bf.frame).position else: # 位置:自身から親の位置を引いた値 trans_vs[lidx] = lbone.position + calc_bone_by_complement( frames, lbone.name, bf.frame).position - links[len(links) - lidx].position # 回転 rot = calc_bone_by_complement(frames, lbone.name, bf.frame).rotation if lbone.fixed_axis != QVector3D(): # 軸固定の場合、回転を制限する rot = QQuaternion.fromAxisAndAngle(lbone.fixed_axis, rot.lengthSquared()) add_qs[lidx] = rot # if "ひじ" in lbone.name: # # 右手系→左手系への変換 # # trans_vs[lidx].setX(trans_vs[lidx].x() * -1) # add_qs[lidx].setX(add_qs[lidx].x() * -1) # add_qs[lidx].setY(add_qs[lidx].y() * -1) # # add_qs[lidx].setScalar(add_qs[lidx].scalar() * -1) # # logger.info("%s: fix: %s, vs: %s, qs: %s", lbone.name, lbone.fixed_axis, trans_vs[lidx], add_qs[lidx].toEulerAngles()) # logger.info("trans_vs[%s]: %s", lidx, trans_vs[lidx]) # logger.info("add_qs[%s]: %s", lidx, add_qs[lidx]) # 行列 matrixs = [QMatrix4x4() for i in range(len(links))] for n in range(len(matrixs)): # 行列を生成 matrixs[n] = QMatrix4x4() # 移動 matrixs[n].translate(trans_vs[n]) # 回転 matrixs[n].rotate(add_qs[n]) # logger.info("matrixs n: %s, %s", n, matrixs[n]) # 各関節の位置 global_4ds = [QVector4D() for i in range(len(links))] for n in range(len(global_4ds)): for m in range(n): if m == 0: # 0番目の位置を初期値とする global_4ds[n] = copy.deepcopy(matrixs[0]) else: # 自分より前の行列結果を掛け算する global_4ds[n] *= copy.deepcopy(matrixs[m]) # 自分は、位置だけ掛ける global_4ds[n] *= QVector4D(trans_vs[n], 1) # if bf.frame == 0: # logger.info("global_4ds %s, %s, %s", n, links[len(links) - n - 1].name, global_4ds[n].toVector3D()) return trans_vs, add_qs, matrixs, global_4ds
def roll(self, _eye, _up, delta): self.up = QQuaternion.fromAxisAndAngle(self._center - _eye, delta).rotatedVector(_up)
def pan_tilt(self, _eye, _up, dx, dy): _front = self._center - _eye _right = QVector3D.crossProduct(_front, _up).normalized() q = QQuaternion.fromAxisAndAngle(_up, dx) * QQuaternion.fromAxisAndAngle(_right, dy) self.eye = self._center - q.rotatedVector(_front) self.up = q.rotatedVector(_up)
def qFromAA(self, axis, angle_rad): return QQuaternion.fromAxisAndAngle(axis, math.degrees(angle_rad))
def __init__(self, rootEntity): super(SceneModifier, self).__init__(rootEntity) # Torus shape data self.m_torus = Qt3DExtras.QTorusMesh() self.m_torus.setRadius(1.0) self.m_torus.setMinorRadius(0.4) self.m_torus.setRings(100) self.m_torus.setSlices(20) # TorusMesh Transform torusTransform = Qt3DCore.QTransform() torusTransform.setScale(2.0) torusTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(0.0, 1.0, 0.0), 25.0)) torusTransform.setTranslation(QVector3D(5.0, 4.0, 0.0)) torusMaterial = Qt3DExtras.QPhongMaterial() torusMaterial.setDiffuse(QColor('#beb32b')) # Torus self.m_torusEntity = Qt3DCore.QEntity(rootEntity) self.m_torusEntity.addComponent(self.m_torus) self.m_torusEntity.addComponent(torusMaterial) self.m_torusEntity.addComponent(torusTransform) # Cone shape data cone = Qt3DExtras.QConeMesh() cone.setTopRadius(0.5) cone.setBottomRadius(1) cone.setLength(3) cone.setRings(50) cone.setSlices(20) # ConeMesh Transform coneTransform = Qt3DCore.QTransform() coneTransform.setScale(1.5) coneTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0)) coneTransform.setTranslation(QVector3D(0.0, 4.0, -1.5)) coneMaterial = Qt3DExtras.QPhongMaterial() coneMaterial.setDiffuse(QColor('#928327')) # Cone self.m_coneEntity = Qt3DCore.QEntity(rootEntity) self.m_coneEntity.addComponent(cone) self.m_coneEntity.addComponent(coneMaterial) self.m_coneEntity.addComponent(coneTransform) # Cylinder shape data cylinder = Qt3DExtras.QCylinderMesh() cylinder.setRadius(1) cylinder.setLength(3) cylinder.setRings(100) cylinder.setSlices(20) # CylinderMesh Transform cylinderTransform = Qt3DCore.QTransform() cylinderTransform.setScale(1.5) cylinderTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0)) cylinderTransform.setTranslation(QVector3D(-5.0, 4.0, -1.5)) cylinderMaterial = Qt3DExtras.QPhongMaterial() cylinderMaterial.setDiffuse(QColor('#928327')) # Cylinder self.m_cylinderEntity = Qt3DCore.QEntity(rootEntity) self.m_cylinderEntity.addComponent(cylinder) self.m_cylinderEntity.addComponent(cylinderMaterial) self.m_cylinderEntity.addComponent(cylinderTransform) # Cuboid shape data cuboid = Qt3DExtras.QCuboidMesh() # CuboidMesh Transform cuboidTransform = Qt3DCore.QTransform() cuboidTransform.setScale(4.0) cuboidTransform.setTranslation(QVector3D(5.0, -4.0, 0.0)) cuboidMaterial = Qt3DExtras.QPhongMaterial() cuboidMaterial.setDiffuse(QColor('#665423')) # Cuboid self.m_cuboidEntity = Qt3DCore.QEntity(rootEntity) self.m_cuboidEntity.addComponent(cuboid) self.m_cuboidEntity.addComponent(cuboidMaterial) self.m_cuboidEntity.addComponent(cuboidTransform) # Plane shape data planeMesh = Qt3DExtras.QPlaneMesh() planeMesh.setWidth(2) planeMesh.setHeight(2) # Plane mesh transform planeTransform = Qt3DCore.QTransform() planeTransform.setScale(1.3) planeTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1.0, 0.0, 0.0), 45.0)) planeTransform.setTranslation(QVector3D(0.0, -4.0, 0.0)) planeMaterial = Qt3DExtras.QPhongMaterial() planeMaterial.setDiffuse(QColor('#a69929')) # Plane self.m_planeEntity = Qt3DCore.QEntity(rootEntity) self.m_planeEntity.addComponent(planeMesh) self.m_planeEntity.addComponent(planeMaterial) self.m_planeEntity.addComponent(planeTransform) # Sphere shape data sphereMesh = Qt3DExtras.QSphereMesh() sphereMesh.setRings(20) sphereMesh.setSlices(20) sphereMesh.setRadius(2) # Sphere mesh transform sphereTransform = Qt3DCore.QTransform() sphereTransform.setScale(1.3) sphereTransform.setTranslation(QVector3D(-5.0, -4.0, 0.0)) sphereMaterial = Qt3DExtras.QPhongMaterial() sphereMaterial.setDiffuse(QColor('#a69929')) # Sphere m_sphereEntity = Qt3DCore.QEntity(rootEntity) m_sphereEntity.addComponent(sphereMesh) m_sphereEntity.addComponent(sphereMaterial) m_sphereEntity.addComponent(sphereTransform)