<p>Edit: changed the answer according to new images and clarification.</p>

<pre><code>for every control point p(k, n)
   p'(k, n) = ( p(k, n) - p(k) ) * d * l(k) + p(k, n)
</code></pre>

<p>where <code>k</code> is the row index and <code>n</code> is the column index of control point. <code>l</code> is the elevation factor and is equal to {-1, -1/3, 1/3, 1}. <code>p(k)</code> is the center of the k'th row.</p>

<p><strong>Rationale:</strong></p>

<p>From the new images, red and blue lines are drawn from the center of the line (p(k) which is basically (k, 0)) to that point. On the first line, all control points, including the ones on the graph (red lines) are moved to the same point on that line. p(k, n) - p(k) gives the vector which moves a point from p(k) to p(k, n) which now should be applied to the other way, moving the point to the desired location. On your graphs, d = 1 so that all first line points would be moved to the center. You can easily solve the equation to verify this. <code>d * l(0)</code> is -1, so it would be <code>-p(k, n) + p(k) + p(k, n)</code> which would give p(k).</p>

<p>On the second line, your blue line is again from point to the center, but this time it stopped before reaching it. I cannot tell if it really is cut from 1/3 but that would be a good starting point. So the same formula still applies. l is -1/3 d is 1, so the point would be moved in 1/3 of the way. 3rd is the same as the second but it now moves outwards, thus l is 1/3.</p>

<p>On the final line, all control points are moved out from the center point of that line. This is quite clear since your lines meet up at that center.</p>

<p>The only problem this formula can have is assumption of 1/3, other than that I do not see the reason why it should fail. </p>

<p><strong>Note:</strong> I used row, column while indexing, thus if you are using x, y you should switch their locations.</p>

CC BY-SA 3.0
2016-07-19T15:02:23.283Z
It prserves vertical lines, that is true. But I am working wit Bézier surface (16 points in a plane) and I believe it must be doable just by moving these 16 points, without computing points on bézier curves etc. Here you can see, how Bézier surface works: http://philipandrews.org/sandbox/BezierSurface/bin/BezierSurface.swf
Ivan Kuckir
CC BY-SA 3.0
2016-07-19T15:22:10.283Z
I think I found solution to that problem if I understood is correctly. You are asking how to deform bezier surface A to bezier surface B or C to D with d parameter being 0.8, is it correct?
Cem Kalyoncu
CC BY-SA 3.0
2016-07-19T15:32:48.593Z
Well it seems that is not the exact formula but quite close. I will ponder on this a little more. Formula is correct at least for on-the-curve-points.
Cem Kalyoncu
CC BY-SA 3.0
2016-07-19T15:33:24.697Z
You are getting closer :) But for the second example, the Y coordinate changes, too.  As I mentioned, all points move along the lines, so it is enough to find the new position for d = 1 for each point, then I can interpolate linearly.
Ivan Kuckir
CC BY-SA 3.0
2016-07-19T15:46:00.767Z
I have added another picture, it may help you.
Ivan Kuckir
CC BY-SA 3.0
2016-07-20T07:55:41.473Z
Oh, you basically solved it, as soon as I got time I will formulate it for you.
Cem Kalyoncu
CC BY-SA 3.0
2016-07-20T09:22:11.523Z
Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/42753/discussion-between-ivan-kuckir-and-cem-kalyoncu).
Ivan Kuckir
CC BY-SA 3.0
2016-07-20T22:55:30.110Z
To your new formlas: so p(k) is always zero? You suggest moving along X the  same distance, as moving along Y, it can not work. You also suggest treating control points the same way, as corner points, which is wrong. It seems like you are just throwing at me what comes into your head. I doubt you can come up with the right formula without acutally implementing it and "seeing the thing".
Ivan Kuckir
CC BY-SA 3.0
2016-07-19T14:42:16.460Z
2016-07-21T06:11:39.750Z
2016-07-21T06:11:39.750Z
Cem Kalyoncu
<p>I am trying to simulate the image warp effect, that is used in Adobe Photoshop.</p>

<p>The rectangular image is warped according to a cubic Bézier surface (in 2D, all Z components are 0). Having any Bézier surface, <strong>vertical distortion</strong> $d \in[0,1]$ can be applied to it.</p>

<p><strong>Left</strong>: input bézier surface, $d=0$, <strong>Right</strong>: output surface,  $d=0.8$</p>

<p><a href="https://i.sstatic.net/VHlGk.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/VHlGk.png" alt="enter image description here"></a>
<a href="https://i.sstatic.net/WyOAa.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/WyOAa.png" alt="enter image description here"></a></p>

<p>Do you have any idea, what is done to the Bézier surface (16 points), when converting from the version on the left to the output on the right?</p>

<transformations><geometry><computational-geometry><bezier-curve>
Apply distortion to Bézier surface
Ivan Kuckir
# Apply distortion to Bézier surface

(Asked by: username_0 on 2016-07-18)

I am trying to simulate the image warp effect, that is used in Adobe Photoshop.

The rectangular image is warped according to a cubic Bézier surface (in 2D, all Z components are 0). Having any Bézier surface, **vertical distortion** $d \in[0,1]$ can be applied to it.

**Left**: input bézier surface, $d=0$, **Right**: output surface, $d=0.8$

[![enter image description here](https://i.sstatic.net/VHlGk.png)](https://i.sstatic.net/VHlGk.png)
[![enter image description here](https://i.sstatic.net/WyOAa.png)](https://i.sstatic.net/WyOAa.png)

Do you have any idea, what is done to the Bézier surface (16 points), when converting from the version on the left to the output on the right?

**Tags:** transformations, geometry, computational-geometry, bezier-curve


---

## 1 answers

### Answer by username_1 on 2016-07-19. Score: 5 | Accepted answer

Edit: changed the answer according to new images and clarification.

```
for every control point p(k, n)
   p'(k, n) = ( p(k, n) - p(k) ) * d * l(k) + p(k, n)

```

where `k` is the row index and `n` is the column index of control point. `l` is the elevation factor and is equal to {-1, -1/3, 1/3, 1}. `p(k)` is the center of the k'th row.

**Rationale:**

From the new images, red and blue lines are drawn from the center of the line (p(k) which is basically (k, 0)) to that point. On the first line, all control points, including the ones on the graph (red lines) are moved to the same point on that line. p(k, n) - p(k) gives the vector which moves a point from p(k) to p(k, n) which now should be applied to the other way, moving the point to the desired location. On your graphs, d = 1 so that all first line points would be moved to the center. You can easily solve the equation to verify this. `d * l(0)` is -1, so it would be `-p(k, n) + p(k) + p(k, n)` which would give p(k).

On the second line, your blue line is again from point to the center, but this time it stopped before reaching it. I cannot tell if it really is cut from 1/3 but that would be a good starting point. So the same formula still applies. l is -1/3 d is 1, so the point would be moved in 1/3 of the way. 3rd is the same as the second but it now moves outwards, thus l is 1/3.

On the final line, all control points are moved out from the center point of that line. This is quite clear since your lines meet up at that center.

The only problem this formula can have is assumption of 1/3, other than that I do not see the reason why it should fail.

**Note:** I used row, column while indexing, thus if you are using x, y you should switch their locations.

> **Comments:**
> **username_0**: It prserves vertical lines, that is true. But I am working wit Bézier surface (16 points in a plane) and I believe it must be doable just by moving these 16 points, without computing points on bézier curves etc. Here you can see, how Bézier surface works: http://philipandrews.org/sandbox/BezierSurface/bin/BezierSurface.swf  
> **username_1**: I think I found solution to that problem if I understood is correctly. You are asking how to deform bezier surface A to bezier surface B or C to D with d parameter being 0.8, is it correct?  
> **username_1**: Well it seems that is not the exact formula but quite close. I will ponder on this a little more. Formula is correct at least for on-the-curve-points.  
> **username_0**: You are getting closer :) But for the second example, the Y coordinate changes, too.  As I mentioned, all points move along the lines, so it is enough to find the new position for d = 1 for each point, then I can interpolate linearly.  
> **username_0**: I have added another picture, it may help you.  
> **username_1**: Oh, you basically solved it, as soon as I got time I will formulate it for you.  
> **username_0**: Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/42753/discussion-between-username_0-username_0-and-username_1).  
> **username_0**: To your new formlas: so p(k) is always zero? You suggest moving along X the  same distance, as moving along Y, it can not work. You also suggest treating control points the same way, as corner points, which is wrong. It seems like you are just throwing at me what comes into your head. I doubt you can come up with the right formula without acutally implementing it and "seeing the thing".  

---

