[Math] Finding two Bézier control points given three points

bezier-curve

My apologies if this is asked in the wrong spot, I believe that this problem has a fairly simple solution… but it is beyond me. Given three points (A,B,C) drawn at random, how do you figure out the middle point's (B) control points (B1?, B2?) for a Bézier curve? The image below will help illustrate what I am looking for. The best way I can describe it (not knowing the lingo that is) would be needing the tangent of the angle formed.

diagram

I have the incorrect control points (B1, B2) coordinates calculated now as 1/6 the distance of the line length. But they would have to be higher (in this example) to give a proper Bézier curve. How can I calculate those coordinates (B1?, B2?) given that I have the coordinates for all the other points labeled below? Hopefully this is as simple as I imagine!

Here is how I calculate the incorrect (B1, B2) control points:

B1x = Bx - ((Bx - Ax)/6)
B1y = By - ((By - Ay)/6)

B2x = Cx + ((Bx - Cx)/6)
B2y = Cy + ((By - Cy)/6)

Thank you SO much in advance!

[Edit: Example points]

In an attempt to track/test my work I am posting example coordinates for the points (only roughly matching the diagram above).

A: (6, 12)
B: (13, 5)
C: (17, 10)

Given those points, I got:

  • $\Delta\vec a$ = (-7, 7)
  • $\Delta\vec c$ = (4, 5)
  • $n(\Delta \vec a)$ = (0.707106781, 0.707106781) – incorrect?
  • $n(\Delta \vec c)$ = (0.780868809, 0.624695048) – incorrect?
  • $\vec m$ = (0.745128018, 0.666921463) – incorrect?

Per your example, for the first coordinate of the first point I had the equation:

$$
14.22939851=b_{11}=13+\frac{\sqrt{7^2+7^2}}60.745128018\
$$

I stopped here because I felt as if I had gone off track.

[Edit 2:]

I now have everything working! But there seems to be an issue with certain angels having incorrect control points:

bad-control-points

B has correct control points (as do most points drawn) but C's control points are off… it appears to be an issue with signs, like when certain vectors are negative. There are no absolute values in my equations… but you mention a $\vec x'=\vec x/|\vec x|$ in your example… might that be the issue?

Perhaps messing around within my sandbox will help to see the problem? I can also post the code (which is available as the source-code of that page). Click at least three points here

Best Answer

As you're probably aware, you can put the control points wherever you like, so this answer isn't about where the control points should go, but about how to put them where you want them. If I understand correctly, you want them to be at the same distance from $B$ as the red and green $B_1$ and $B_2$, but not on the lines $AB$ and $BC$, but on a line perpendicular to the bisector of $\angle ABC$.

So you need a vector pointing along that bisector. Several operations will require normalizing vectors, so I'll denote by $n(\vec x)=\vec x/|\vec x|$ the unit vector along $\vec x$; in coordinates, this would be

$$x_1'=\frac{x_1}{\sqrt{x_1^2+x_2^2}}\;,$$ $$x_2'=\frac{x_2}{\sqrt{x_1^2+x_2^2}}\;.$$

If we denote by $\vec a, \vec b, \vec c$ the vectors for points $A$, $B$ and $C$, respectively, and the differences $\vec a - \vec b$ and $\vec c - \vec b$ by $\Delta\vec a$ and $\Delta\vec c$, respectively, then the vector $\vec m=n(n(\Delta \vec a)+n(\Delta \vec c))$ is a unit vector along the bisector of $\angle ABC$.

Now comes the tricky part. It's easy to get just any vector perpendicular to $\vec m$, but if I understand correctly you want to go different lengths to the two sides, corresponding to $1/6$ of the length of the corresponding line segment, so you have to get the signs right. You can do this by projecting $\vec m$ out of $\Delta \vec a$ and $\Delta \vec c$, respectively:

$$\vec m_{a}=n(\Delta\vec a-(\Delta\vec a\cdot\vec m)\vec m)\;,$$ $$\vec m_{c}=n(\Delta\vec c-(\Delta\vec c\cdot\vec m)\vec m)\;.$$

Then you just have to add the desired multiples of these vectors to $\vec b$:

$$\vec b_1 = \vec b + \frac{|\Delta\vec a|}6 \vec m_a\;,$$ $$\vec b_2 = \vec b + \frac{|\Delta\vec c|}6 \vec m_c\;.$$

[Edit in response to the comment:]

I'm not sure whether I fully understand what you're asking for since I don't know what "initial formula" refers to (and the comment is partly ungrammatical), but I gather that you're more comfortable with coordinate notation than with vector notation, so I'll write all the equations out in coordinate notation; I hope that will enable you to implement them.

I'd already done this for the normalization operation; so here again for completeness: The operation $n(\vec x)$ applied to the vector $\vec x$ with coordinates $(x_1,x_2)$ results in a unit vector $\vec x'=\vec x/|\vec x|$ with coordinates $(x_1',x_2')$ given by

$$x_1'=\frac{x_1}{\sqrt{x_1^2+x_2^2}}\;,$$ $$x_2'=\frac{x_2}{\sqrt{x_1^2+x_2^2}}\;.$$

The coordinates $(\Delta a_1,\Delta a_2)$ of the vector $\Delta\vec a$ are given by $\Delta a_1=a_1-b_1$ and $\Delta a_2=a_2-b_2$, respectively, and likewise $\Delta c_1=c_1-b_1$ and $\Delta c_2=c_2-b_2$ for the coordinates $(\Delta c_1,\Delta c_2)$ of the vector $\Delta\vec c$.

The scalar product $\vec x\cdot\vec s$ of vectors $\vec x$ and $\vec s$ with coordinates $(x_1,x_2)$ and $(s_1,s_2)$, respectively, is $x_1s_1+x_2s_2$, so e.g. the coordinates of $\Delta\vec a-(\Delta\vec a\cdot\vec m)\vec m$ are $\Delta a_1-(\Delta a_1 m_1+\Delta a_2m_2)m_1$ and $\Delta a_2-(\Delta a_1 m_1+\Delta a_2m_2)m_2$. The norm (length) $|\vec x|$ of a vector $\vec x$ with coordinates $(x_1,x_2)$ is given by $\sqrt{x_1^2+x_2^2}$, so the first coordinate of the first of the last two equations is

$$b_{11}=b_1+\frac{\sqrt{\Delta a_1^2+\Delta a_2^2}}6m_{a1}\;.$$

I hope that's roughly what you were looking for.