# vtkTransformPolyDataFilter output a incorrect result

**URL:** https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366
**Category:** Support
**Created:** [January 3, 2023, 6:05am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366 "2023-01-03T06:05:16Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 3, 2023, 6:05am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/1 "2023-01-03T06:05:17Z")

</div>

I have a `polydata` and a `transformMatrix`. I compute two result:

1. transform the center point of `polydata` with `transformMatrix`.
2. transform the `polydata` with `transformMatrix`, and get center of the new poly data.

I find the two results are different:

```auto
1. (32.655436515808105, 101.52645111083984, -17.70375633239746)
2. (32.64958572387695, 101.52920913696289, -17.70375633239746)

```

It make me confuzed.

The code to reproduce my problem is:

```auto

import vtkmodules.all as vtk

reader = vtk.vtkSTLReader()
reader.SetFileName('./poly.stl')
reader.Update()

poly = reader.GetOutput()

polyCenter = poly.GetCenter()

m = [
    0.99999657608723425, 0.0026168327818937172, 0, -0.26556593613022272,
    -0.0026168327818937172, 0.99999657608723425, 0, 0.085801434493632200,
    0, 0, 1, 0,
    0, 0, 0, 1
]
matrix = vtk.vtkMatrix4x4()
matrix.DeepCopy(m)
transform = vtk.vtkTransform()
transform.SetMatrix(m)
transform.Update()

print(transform.TransformPoint(polyCenter))

filter = vtk.vtkTransformPolyDataFilter()
filter.SetInputData(poly)
filter.SetTransform(transform)
filter.Update()

newPoly = filter.GetOutput()
print(newPoly.GetCenter())

```

And the test data is:

[poly.stl](https://discourse.vtk.org/uploads/short-url/uSloJeRy7KtA91MYVYWI77Zin5T.stl) (44.8 KB)

My vtk is `9.2.4`

Any suggestion is appreciated~~~

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 3, 2023, 2:38pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/2 "2023-01-03T14:38:48Z")

</div>

The vtkSTLReader is single-precision, and this precision is carried through the transform filter. You can get more precision like this:

```python
filter.SetOutputPointsPrecision(vtk.vtkAlgorithm.DOUBLE_PRECISION)

```

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 3, 2023, 2:50pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/3 "2023-01-03T14:50:16Z")

</div>

@dgobbi Thanks for kindly reply.

> [@dgobbi](#):
>
> `filter.SetOutputPointsPrecision(vtk.vtkAlgorithm.DOUBLE_PRECISION)`

It don’t change the finally result. The modified code is:

```auto
filter = vtk.vtkTransformPolyDataFilter()
filter.SetInputData(poly)
filter.SetTransform(transform)
filter.SetOutputPointsPrecision(vtk.vtkAlgorithm.DOUBLE_PRECISION)
filter.Update()

```

And the printed information is:

```auto
(32.655436515808105, 101.52645111083984, -17.70375633239746)
(32.649586295755405, 101.52921088196327, -17.70375633239746)

```

The two center points are still not equal.

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 3, 2023, 3:04pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/4 "2023-01-03T15:04:05Z")

</div>

Ah, sorry. The cause of the difference is more fundamental than the precision of the points.

The method `GetCenter()` returns the center of the BoundingBox of the data. When you rotate the data, the bounding box changes.

Maybe you want the center-of-mass instead of the center of the bounding box?

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 4, 2023, 11:49am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/5 "2023-01-04T11:49:44Z")

</div>

> [@dgobbi](#):
>
> Maybe you want the center-of-mass instead of the center of the bounding box?

How to obtain the center of mass?

I think the following points should be the same, am I right?

1. rotate the polydata with the matrix, and obtain the center of new poly data.
2. generate a actor, and set the matrix as the user matrix. Then obtain the center of actor.

However, in my test, they are still not the same:

```auto
(32.655436515808105, 101.52645111083984, -17.70375633239746)
(32.64958572387695, 101.52920913696289, -17.70375633239746)

```

The code to reproduce my result is:

```auto

import vtkmodules.all as vtk

reader = vtk.vtkSTLReader()
reader.SetFileName('./poly.stl')
reader.Update()

poly = reader.GetOutput()

polyCenter = poly.GetCenter()

m = [
    0.99999657608723425, 0.0026168327818937172, 0, -0.26556593613022272,
    -0.0026168327818937172, 0.99999657608723425, 0, 0.085801434493632200,
    0, 0, 1, 0,
    0, 0, 0, 1
]
matrix = vtk.vtkMatrix4x4()
matrix.DeepCopy(m)

mapper1 = vtk.vtkPolyDataMapper()
mapper1.SetInputData(poly)
actor1 = vtk.vtkActor()
actor1.SetMapper(mapper1)
actor1.SetUserMatrix(matrix)
actor1.Modified()

print(actor1.GetCenter())

transform = vtk.vtkTransform()
transform.SetMatrix(m)
transform.Update()

filter = vtk.vtkTransformPolyDataFilter()
filter.SetInputData(poly)
filter.SetTransform(transform)
filter.Update()

newPoly = filter.GetOutput()
print(newPoly.GetCenter())

```

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 4, 2023, 3:33pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/6 "2023-01-04T15:33:06Z")

</div>

> [@zhang-qiang-github](#):
>
> How to obtain the center of mass?

The center of mass of the points can be computed with vtkCenterOfMass. But if you need the center of mass of the enclosed volume, I don’t think VTK provides any methods for that.

> [@](#):
>
> I think the following points should be the same, am I right?

The bounds of the actor are computed by rotating the bounds of the data and then computing a new bounding box with respect to world coordinates. My feeling is that it should give the same result, but I would have to examine the code and go through the math to be certain.

However, please note that GetCenter() is only meant to be a quick-and-dirty method to get the center of the dataset. That’s why it just uses the bounding box instead of doing a more sophisticated computation.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 4, 2023, 3:47pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/7 "2023-01-04T15:47:03Z")

</div>

> [@dgobbi](#):
>
> However, please note that GetCenter() is only meant to be a quick-and-dirty method to get the center of the dataset. That’s why it just uses the bounding box instead of doing a more sophisticated computation.

In fact, I find the `actor.SetUserMatrix()` is different from `newPoly=vtkTransformPolyDataFilter.GetOutput(); actor2=generateActor(newPoly)`. In order to debug this problem, I compute the center.

> [@dgobbi](#):
>
> My feeling is that it should give the same result, but I would have to examine the code and go through the math to be certain.

I am looking forward to your kindly reply ~~~~

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 4, 2023, 4:26pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/8 "2023-01-04T16:26:21Z")

</div>

> [@zhang-qiang-github](#):
>
> I am looking forward to your kindly reply ~~~~

Note that “I would have to” does not have the same meaning as “I will”.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 5, 2023, 3:06am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/9 "2023-01-05T03:06:53Z")

</div>

> [@dgobbi](#):
>
> Note that “I would have to” does not have the same meaning as “I will”.

I am apologized for this unsuitable reply. Sorry about it.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 5, 2023, 9:15am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/10 "2023-01-05T09:15:59Z")

</div>

> [@dgobbi](#):
>
> The bounds of the actor are computed by rotating the bounds of the data and then computing a new bounding box with respect to world coordinates. My feeling is that it should give the same result, but I would have to examine the code and go through the math to be certain.

I rethink about this process. I think the bounds of the actor may be not equal to the bounds of rotated polydata.

![image](https://discourse.vtk.org/uploads/default/original/2X/e/efe9c0040cdc76334bc04b3e66a666628e74213c.png)

Please have a look at the above figure. Suppose we have four points (black point), and it formed a square with 1 length of side.

1. Firstly, the red line indicates the coordinate system. In this situation, the length of bounds side should be \sqrt 2.
2. Then, the matrix rotate the first coordiante system (red line) to the second coordinate system (gren line). After the rotation, the bounds of the data is rotated, and the rotated bounds should has \sqrt 2 length of side, because rotation do not change the length. To calculate the new bounding box, the bounds length should be larger than \sqrt 2.
3. However, for the rotated poly data, the bounds length should be 1.

In a word, to calculate the bounds of actor, directly rotating the bounds should be an inaccurate method.

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 5, 2023, 3:00pm UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/11 "2023-01-05T15:00:57Z")

</div>

> [@zhang-qiang-github](#):
>
> In a word, to calculate the bounds of actor, directly rotating the bounds should be an inaccurate method.

But since the bounds are rectangular, the center should stay the same.

The main idea, though, is that `GetCenter()` is only meant to give an approximate result. That is why I recommend using a center-of-mass to test vtkTransformPolyDataFilter.

If you want to test the matrix of the actor, you cannot do this by computing the center of the data. This is because the transformation of the actor occurs on the GPU via OpenGL. To test the matrix of the actor, the best method is to render two actors and visually compare the results:

- for the first actor, use the actor’s matrix for the transformation
- for the second actor, use vtkTransformPolyDataFilter for the transformation

Use `actor.GetProperty().SetRepresentationToWireframe()` to make it easier to compare the results, and use a different color for each actor. In this way, you should be able to convince yourself that the transformation is accurate.

---

<div class="post-metadata">

### Author: ![zhang-qiang-github](https://discourse.vtk.org/user_avatar/discourse.vtk.org/zhang-qiang-github/32/2519_2.png) [@zhang-qiang-github](https://discourse.vtk.org/u/zhang-qiang-github)
#### Post date: [January 6, 2023, 9:38am UTC](https://discourse.vtk.org/t/vtktransformpolydatafilter-output-a-incorrect-result/10366/12 "2023-01-06T09:38:35Z")

</div>

I have tried it. The shown actors are the same, but the obtained centers are not the same.
