1.类图结构
2.代码实现
2.1 Identity
void vtkTransform::Identity()
{
this->Concatenation->Identity();
// support for the legacy hack in InternalUpdate
if (this->Matrix->GetMTime() > this->MatrixUpdateMTime)
{
this->Matrix->Identity();
}
this->Modified();
}
2.1.1 vtkTransformConcatenation::Identity()
void vtkTransformConcatenation::Identity()
{
// forget the Pre- and PostMatrix
this->PreMatrix = nullptr;
this->PostMatrix = nullptr;
this->PreMatrixTransform = nullptr;
this->PostMatrixTransform = nullptr;
// delete all the transforms
if (this->NumberOfTransforms > 0)
{
for (int i = 0; i < this->NumberOfTransforms; i++)
{
vtkTransformPair* tuple = &this->TransformList[i];
if (tuple->ForwardTransform)
{
tuple->ForwardTransform->Delete();
tuple->ForwardTransform = nullptr;
}
if (tuple->InverseTransform)
{
tuple->InverseTransform->Delete();
tuple->InverseTransform = nullptr;
}
}
}
this->NumberOfTransforms = 0;
this->NumberOfPreTransforms = 0;
}
2.1.2 this->Matrix->Identity()
vtkMatrix4x4::Identity()
/**
* Set equal to Identity matrix
*/
void Identity()
{
vtkMatrix4x4::Identity(*this->Element);
this->Modified();
}
2.1.3 this->Modified()
void vtkObject::Modified()
{
this->MTime.Modified();
this->InvokeEvent(vtkCommand::ModifiedEvent, nullptr);
}
2.2 Translate
void Translate(double x, double y, double z) { this->Concatenation->Translate(x, y, z); }
2.2.1 vtkTransformConcatenation::Translate()
void vtkTransformConcatenation::Translate(double x, double y, double z)
{
if (x == 0.0 && y == 0.0 && z == 0.0)
{
return;
}
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
matrix[0][3] = x;
matrix[1][3] = y;
matrix[2][3] = z;
this->Concatenate(*matrix);
}
2.2.2 vtkTransformConcatenation::Concatenate(const double elements[16])
void vtkTransformConcatenation::Concatenate(const double elements[16])
{
// concatenate the matrix with either the Pre- or PostMatrix
if (this->PreMultiplyFlag)
{
if (this->PreMatrix == nullptr)
{
// add the matrix to the concatenation
vtkSimpleTransform* mtrans = vtkSimpleTransform::New();
this->Concatenate(mtrans);
mtrans->Delete();
this->PreMatrixTransform = mtrans;
this->PreMatrix = mtrans->GetMatrix();
}
vtkMatrix4x4::Multiply4x4(*this->PreMatrix->Element, elements, *this->PreMatrix->Element);
this->PreMatrix->Modified();
this->PreMatrixTransform->Modified();
}
else
{
if (this->PostMatrix == nullptr)
{
// add the matrix to the concatenation
vtkSimpleTransform* mtrans = vtkSimpleTransform::New();
this->Concatenate(mtrans);
mtrans->Delete();
this->PostMatrixTransform = mtrans;
this->PostMatrix = mtrans->GetMatrix();
}
vtkMatrix4x4::Multiply4x4(elements, *this->PostMatrix->Element, *this->PostMatrix->Element);
this->PostMatrix->Modified();
this->PostMatrixTransform->Modified();
}
}
2.2.3 vtkMatrix4x4::Multiply4x4()
inline void vtkMatrix4x4::Multiply4x4(const double a[16], const double b[16], double c[16])
{
double tmp[16];
for (int i = 0; i < 16; i += 4)
{
for (int j = 0; j < 4; j++)
{
tmp[i + j] =
a[i + 0] * b[j + 0] + a[i + 1] * b[j + 4] + a[i + 2] * b[j + 8] + a[i + 3] * b[j + 12];
}
}
for (int k = 0; k < 16; k++)
{
c[k] = tmp[k];
}
}
2.3 RotateWXYZ
创建一个旋转矩阵,并根据预乘或后乘语义将其与当前变换连接起来。
- 角度以度为单位,(x,y,z)指定旋转将围绕的轴。
/**
* Create a rotation matrix and concatenate it with the current
* transformation according to PreMultiply or PostMultiply semantics.
* The angle is in degrees, and (x,y,z) specifies the axis that the
* rotation will be performed around.
*/
void RotateWXYZ(double angle, double x, double y, double z)
{
this->Concatenation->Rotate(angle, x, y, z);
}
2.3.1 vtkTransformConcatenation::Rotate()
void vtkTransformConcatenation::Rotate(double angle, double x, double y, double z)
{
if (angle == 0.0 || (x == 0.0 && y == 0.0 && z == 0.0))
{
return;
}
// convert to radians
angle = vtkMath::RadiansFromDegrees(angle);
// make a normalized quaternion
double w = cos(0.5 * angle);
double f = sin(0.5 * angle) / sqrt(x * x + y * y + z * z);
x *= f;
y *= f;
z *= f;
// convert the quaternion to a matrix
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
double ww = w * w;
double wx = w * x;
double wy = w * y;
double wz = w * z;
double xx = x * x;
double yy = y * y;
double zz = z * z;
double xy = x * y;
double xz = x * z;
double yz = y * z;
double s = ww - xx - yy - zz;
matrix[0][0] = xx * 2 + s;
matrix[1][0] = (xy + wz) * 2;
matrix[2][0] = (xz - wy) * 2;
matrix[0][1] = (xy - wz) * 2;
matrix[1][1] = yy * 2 + s;
matrix[2][1] = (yz + wx) * 2;
matrix[0][2] = (xz + wy) * 2;
matrix[1][2] = (yz - wx) * 2;
matrix[2][2] = zz * 2 + s;
this->Concatenate(*matrix);
}
this->Concatenate(matrix) 代码见2.2.2 vtkTransformConcatenation::Concatenate(const double elements[16])。
2.3.2 vtkMatrix4x4::Identity(double elements[16])
void vtkMatrix4x4::Identity(double elements[16])
{
elements[0] = elements[5] = elements[10] = elements[15] = 1.0;
elements[1] = elements[2] = elements[3] = elements[4] = elements[6] = elements[7] = elements[8] =
elements[9] = elements[11] = elements[12] = elements[13] = elements[14] = 0.0;
}
2.3.3 vtkMath::RadiansFromDegrees(double x)
inline double vtkMath::RadiansFromDegrees(double x)
{
return x * 0.017453292519943295;
}
2.4 Scale
/**
* Create a scale matrix (i.e. set the diagonal elements to x, y, z)
* and concatenate it with the current transformation according to
* PreMultiply or PostMultiply semantics.
*/
void Scale(double x, double y, double z) { this->Concatenation->Scale(x, y, z); }
2.4.1 vtkTransformConcatenation::Scale
void vtkTransformConcatenation::Scale(double x, double y, double z)
{
if (x == 1.0 && y == 1.0 && z == 1.0)
{
return;
}
double matrix[4][4];
vtkMatrix4x4::Identity(*matrix);
matrix[0][0] = x;
matrix[1][1] = y;
matrix[2][2] = z;
this->Concatenate(*matrix);
}
this->Concatenate(matrix) 代码见2.2.2 vtkTransformConcatenation::Concatenate(const double elements[16])。
2.5 TransformPoints
vtkTransform : public vtkLinearTransform
TransformPoints是父类vtkLinearTransform的方法,所以调用vtkLinearTransform::TransformPoints。
void vtkLinearTransform::TransformPoints(vtkPoints* inPts, vtkPoints* outPts)
{
vtkIdType n = inPts->GetNumberOfPoints();
vtkIdType m = outPts->GetNumberOfPoints();
double(*matrix)[4] = this->Matrix->Element;
this->Update();
// operate directly on the memory to avoid GetPoint()/SetPoint() calls.
vtkDataArray* inArray = inPts->GetData();
vtkDataArray* outArray = outPts->GetData();
int inType = inArray->GetDataType();
int outType = outArray->GetDataType();
void* inPtr = inArray->GetVoidPointer(0);
void* outPtr = outArray->WriteVoidPointer(3 * m, 3 * n);
if (inType == VTK_FLOAT && outType == VTK_FLOAT)
{
vtkLinearTransformPoints(matrix, static_cast<float*>(inPtr), static_cast<float*>(outPtr), n);
}
else if (inType == VTK_FLOAT && outType == VTK_DOUBLE)
{
vtkLinearTransformPoints(matrix, static_cast<float*>(inPtr), static_cast<double*>(outPtr), n);
}
else if (inType == VTK_DOUBLE && outType == VTK_FLOAT)
{
vtkLinearTransformPoints(matrix, static_cast<double*>(inPtr), static_cast<float*>(outPtr), n);
}
else if (inType == VTK_DOUBLE && outType == VTK_DOUBLE)
{
vtkLinearTransformPoints(matrix, static_cast<double*>(inPtr), static_cast<double*>(outPtr), n);
}
else
{
double point[3];
for (vtkIdType i = 0; i < n; i++)
{
inPts->GetPoint(i, point);
vtkLinearTransformPoint(matrix, point, point);
outPts->SetPoint(m + i, point);
}
}
}
template <class T1, class T2, class T3>
inline void vtkLinearTransformPoints(T1 matrix[4][4], T2* in, T3* out, vtkIdType n)
{
// Switch based on the number of points to transform: serial processing is
// faster for a smaller number of transformations.
if (n >= VTK_SMP_THRESHOLD)
{
vtkSMPTools::For(0, n, [&](vtkIdType ptId, vtkIdType endPtId) {
T2* pin = in + 3 * ptId;
T3* pout = out + 3 * ptId;
for (; ptId < endPtId; ++ptId)
{
vtkLinearTransformPoint(matrix, pin, pout);
pin += 3;
pout += 3;
}
});
}
else
{
for (vtkIdType i = 0; i < n; i++)
{
vtkLinearTransformPoint(matrix, in, out);
in += 3;
out += 3;
}
}
}
template <class T1, class T2, class T3>
inline void vtkLinearTransformPoint(T1 matrix[4][4], T2 in[3], T3 out[3])
{
T3 x = static_cast<T3>(
matrix[0][0] * in[0] + matrix[0][1] * in[1] + matrix[0][2] * in[2] + matrix[0][3]);
T3 y = static_cast<T3>(
matrix[1][0] * in[0] + matrix[1][1] * in[1] + matrix[1][2] * in[2] + matrix[1][3]);
T3 z = static_cast<T3>(
matrix[2][0] * in[0] + matrix[2][1] * in[1] + matrix[2][2] * in[2] + matrix[2][3]);
out[0] = x;
out[1] = y;
out[2] = z;
}
2.6 vtkTransformConcatenation与vtkTransform中矩阵如何关联起来的?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容