I have 2 points in X,Y + Rotation and I need to calculate a bezier spline (a collection of quadratic beziers) that connects these 2 points smoothly. (see pic) The point represents a unit in a game which can only rotate slowly. So to get from point A to B, it has to take a long path. The attached picture shows quite an exaggeratedly curvy path, but you get the idea.
What formulas can I use to calculate such a bezier spline?
Just saw that I misunderstood your question. Couldn't you use a single cubic hermite splines instead since you have a start and end point and two directions (tangents)? Are there any additional constraints?
To calculate the start and end tangents just use the start and end direction and scale them with the distance between the start and end points (and additionally some other constant factor like 0.5 depending on how curvy you want the path to be).:
p0 = startpoint;
p1 = endpoint;
float scale = distance(p0, p1);
m0 = Vec2(cos(startangle), sin(startangle)) * scale;
m1 = Vec2(cos(endangle), sin(endangle)) * scale;
I use this system to interpolate camera paths in a game I'm working on and it works great.
As you probably know, there are infinite solutions, even if we assume 2 control points.
I found Smoothing Algorithm Using Bézier Curves, which answers your question (see equations of Bx(t) and By(t) in the beginning):
Bx(t) = (1-t)3 P1x + 3 (1-t)2 t P2x + 3 (1-t) t2 P3x + t3 P4x
By(t) = (1-t)3 P1y + 3 (1-t)2 t P2y + 3 (1-t) t2 P3y + t3 P4y
P1 and P4 are your endpoints, and P2 and P3 are the control points, which you're free to choose along the desired angles. If your control point is at a distance r along an angle θ from point (x, y), the coordinates of the point are:
x' = x - r sin(θ)
y' = y - r cos(θ)
(according to the co-ordinate system you've used—I think I got the signs right). The only free parameter is r, which you can choose as you want. You probably want to use
r = α dist(P1, P4)
with α < 1.
I don't remember where I got it, but I have been using this:
Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
float u = 1 - t;
float tt = t*t;
float uu = u*u;
float uuu = uu * u;
float ttt = tt * t;
Vector2 p = uuu * p0; //first term
p += 3 * uu * t * p1; //second term
p += 3 * u * tt * p2; //third term
p += ttt * p3; //fourth term
return p;
}
where t is ratio along path between start and end points.
Related
I am trying to find the launch angle and launch heading to hit a specific point at the end of the trajectory. However the challenge is that the shooter is translating along the field. Therefore there is a momentum that influences the trajectory and curves it into the 3rd dimension. Again, I need to calculate the launch angle compared to the horizon and the launch heading to counter the momentum.
Although it is not a programing question let me explain it to you. To work out a projectile motion in 2D, we usually break the velocity vector into two components vx and vz and launch angle θxz. To work it out in 3D you'll just need to do the same things in 3D i.e. you'll need to resolve the velocity vector into three components vx, vy and vz along with launch angles in two direction θxz and θyz and also an angle θxy. After that, you can apply your normal equations of motion to get a proper solution. Now, the problem remains to get the velocity. That can be done by considering a frame of reference and relative velocity vectors. Do these two things and you'll get your answer in my opinion.
I am assuming that the shooter moves according to some trajectory equations
x(t) = [x[0](t), x[1](t), 0]
in the horizontal plane (that is why x[3](t) = 0 because the trajectory is always on the plane x[1], x[2]).
At time t_0 the shooter is at the point x_0 = x(t_0) and has velocity
v_0 = v(t_0) = dx/dt(t_0) = [v_0[0], v_0[1], 0]
I assume you know the magnitude of the velocity w > 0 with which the bullet is shot at time t_0 and you are looking for a directing unit vector
u = [u[0], u[1], u[2]]
1 = u[0]^2 + u[1]^2 + u[2]^2
that will guarantee that the shot will hit the stationary (I hope) target located at point
x_1 = [x_1[0], x_1[1], x_1[2]]
So the shot is fired at time t_0 from point x_0, the latter moving with speed v_0 and the magnitude of the fired bullet is w. Therefore the initial velocity of the bullet with respect to a coordinate system attached to the ground is v_0 + w*u, where u is the unknown unit vector. The vectorized differential equations of motion are
dx/dt = v
dv/dt = - g * e_3
where e_3 = [0, 0, 1] and g = 9.8. The solution of these equations, that starts from x_0 with velocity v_0 + w*u at time t_0 follows the trajectory described by the vectorized equations
x(t) = x_0 + (t - t_0) * (v_0 + w*u) - g*(t - t_0)^2 * e_3
So, there is a yet unknown moment of time t_1 at which the bullet hits the target x_1, i.e.
x_1 = x(t_1) which yields
x_1 = x_0 + (t_1 - t_0) * (v_0 + w*u) - g*(t_1 - t_0)^2 * e_3
Denote by
x_10 = x_1 - x_0 (known) i.e.
for (int i=0; i<3; i++){x_12[i] = x_1[i] - x_0[i]}
t_10 = t_1 - t_0 (unknown)
Then you get
x_10 = t_10 * (v_0 + w*u) - g * (t_10)^2 * e_3
If you rewrite the vectorized equation of the bullet hitting the target componentwise, you get the following system of four quadratic equations for the unknown variables t_10, u[0], u[1], u[2]:
x_10[0] = t_10 * ( v_0[0] + w*u[0] )
x_10[1] = t_10 * ( v_0[1] + w*u[1] )
x_10[2] = t_10 * w * u[1] - (t_10)^2 * g / 2
1 = u[0]^2 + u[1]^2 + u[2]^2
If you express the variables u[0], u[1], u[2] in terms of t_12 from the first three equations, you get
u[0] = x_10[0]/(w*t_10) - v[0]/w
u[1] = x_10[1]/(w*t_10) - v[1]/w
u[2] = ( x_10[2] + (t_10)^2 * g / 2 )/(w*t_10)
1 = u[0]^2 + u[1]^2 + u[2]^2
then you can plug the expressions for u[0], u[1], u[2] in terms of t_12 into the last equation and you get, after multiplying both sides by (t_10)^2, a degree four polynomial equation in the variable t_12. After you solve it, you will find one positive root and you can plug it back in the first three equations to calculate the coordinates of the unit vector u.
Hi I have geometrical problem which is driving me crazy. I want to determine the location of one vertex in a "Isosceles Right Triangle" (alpha = 45°; beta = 45°; gamma = 90°).
E.g. in this illustration:
I have a,b,c,h and the location of A and B (and of cause the angle). The only thing thats missing is C in x,y terms. Can someone support me on this?
Here is code that works only for the 45°-45°-90° triangle--it would need to be modified for other triangles.
Note that all you need are the coordinates of A and B. c is then the distance between those two points, h is c/2, and both a and b are c/sqrt(2). This Python code returns a 2-tuple (Cx, Cy) giving the coordinates of C, assuming you want C to be oriented counterclockwise from the vector AB. If you want clockwise, replace the plus sign with a minus sign in the calculation that defines inclinationAC. This uses only basic trigonometry, showing each step--there are other methods, as Ed Heal says in his comment, but this should be more easily understood by most people.
from math import sqrt, hypot, pi, cos, sin, atan2
def corner_right_isoceles(Ax, Ay, Bx, By):
"""Return the coordinates of the right-angle corner of a right
isosceles triangle if the other two vertices are the points
(Ax, Ay) and (Bx, By). The returned corner is counterclockwise
from the vector AB.
"""
c = hypot(By - Ay, Bx - Ax)
b = c / sqrt(2)
inclinationAB = atan2(By - Ay, Bx - Ax)
inclinationAC = inclinationAB + pi / 4
Cx = Ax + b * cos(inclinationAC)
Cy = Ay + b * sin(inclinationAC)
return Cx, Cy
Here is another version, which is a bit simpler and with that also much more efficient to calculate. The idea is that h is exactly half of c in this triangle:
dx = Bx - Ax
dy = By - Ay
Cx = Ax + 0.5 * (dx - dy)
Cy = Ay + 0.5 * (dy + dx)
Hello again first part is working like a charm, thank you everyone.
But I've another question...
As I've no interface, is there a way to do the same thing with out not knowing the radius of the circle?
Should have refresh the page CodeMonkey solution is exactly what I was looking for...
Thank you again.
============================
First I'm not a developer, I'm a simple woodworker that left school far too early...
I'm trying to make one of my tool to work with an autonomous robot.
I made them communicate by reading a lot of tutorials.
But I have one problem I cant figure out.
Robot expect position of the tool as (X,Y) but tool's output is (A,B,C)
A is the distance from tool to north
B distance to east
C distance at 120 degree clockwise from east axe
the border is a circle, radius may change, and may or may not be something I know.
I've been on that for 1 month, and I can't find a way to transform those value into the position.
I made a test with 3 nails on a circle I draw on wood, and if I have the distance there is only one position possible, so I guess its possible.
But how?
Also, if someone as an answer I'd love pseudo code not code so I can practice.
If there is a tool to make a drawing I can use to make it clearer can you point it out to me?
Thank you.
hope it helps :
X, Y are coordinate from center, Da,Db, Dc are known.
Trying to make it more clear (sorry its so clear in my head).
X,Y are the coordinate of the point where is the tool (P).
Center is at 0,0
A is the point where vertical line cut the circle from P, with Da distance P to A;
B is the point where horizontal line cuts the circle fom P, with Db distance P to B.
C is the point where the line at 120 clockwise from horizontal cuts the circle from P, with Dc distance P to C.
Output from tool is an array of int (unit mm): A=123, B=114, C=89
Those are the only informations I have
thanks for all the ideas I'll try them at home later,
Hope it works :)
Basic geometry. I decided to give up having the circle at the origin. We don't know the center of the circle yet. What you do have, is three points on that circle. Let's try having the tool's position, given as P, as the new (0,0). This thus resolves to finding a circle given three points: (0, Da); (Db,0), and back off at 120° at Dc distance.
Pseudocode:
Calculate a line from A to B: we'll call it AB. Find AB's halfway point. Calculate a line perpendicular to AB, through that midpoint (e.g. the cross product of AB and a unit Z axis finds the perpendicular vector).
Calculate a line from B to C (or C to A works just as well): we'll call it BC. Find BC's halfway point. Calculate a line perpendicular to BC, through that midpoint.
Calculate where these two lines cross. This will be the origin of your circle.
Since P is at (0,0), the negative of your circle's origin will be your tool's coordinates relative to the circle's origin. You should be able to calculate anything you need relative to that, now.
Midpoint between two points: X=(X1+X2)/2. Y=(Y1+Y2)/2.
The circle's radius can be calculated using, e.g. point A and the circle's origin: R=sqrt(sqr((Ax-CirX)+sqr(Ay-CirY))
Distance from the edge: circle's radius - tool's distance from the circle's center via Pythagorean Theorem again.
Assume you know X and Y. R is the radius of the circle.
|(X, Y + Da)| = R
|(X + Db, Y)| = R
|(X - cos(pi/3) * Dc, Y - cos(pi/6) * Dc)| = R
Assuming we don't know the radius R. We can still say
|(X, Y + Da)|^2 = |(X + Db, Y)|^2
=> X^2 + (Y+Da)^2 = (X+Db)^2 + Y^2
=> 2YDa + Da^2 = 2XDb + Db^2 (I)
and denoting cos(pi/3)*Dc as c1 and cos(pi/6)*Dc as c2:
|(X, Y + Da)|^2 = |(X - c1, Y - c2)|^2
=> X^2 + Y^2 + 2YDa + Da^2 = X^2 - 2Xc1 + c1^2 + Y^2 - 2Yc2 + c2^2
=> 2YDa + Da^2 = - 2Xc1 + c1^2 - 2Yc2 + c2^2
=> Y = (-2Xc1 + c1^2 + c2^2 - Da^2) / 2(c2+Da) (II)
Putting (II) back in the equation (I) we get:
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da / (c2+Da) + Da^2 = 2XDb + Db^2
=> (-2Xc1 + c1^2 + c2^2 - Da^2) Da + Da^2 * (c2+Da) = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> (-2Xc1 + c1^2 + c2^2) Da + Da^2 * c2 = 2XDb(c2+Da) + Db^2 * (c2+Da)
=> X = ((c1^2 + c2^2) Da + Da^2 * c2 - Db^2 * (c2+Da)) / (2Dbc2 + 2Db*Da + 2Dac1) (III)
Knowing X you can get Y by calculating (II).
You can also make some simplifications, e.g. c1^2 + c2^2 = Dc^2
Putting this into Python (almost Pseudocode):
import math
def GetXYR(Da, Db, Dc):
c1 = math.cos(math.pi/3) * Dc
c2 = math.cos(math.pi/6) * Dc
X = ((c1**2 + c2**2) * Da + Da**2 * c2 - Db * Db * (c2 + Da)) / (2 * Db * c2 + 2 * Db * Da + 2 * Da * c1)
Y = (-2*X*c1 + c1**2 + c2**2 - Da**2) / (2*(c2+Da))
R = math.sqrt(X**2 + (Y+Da)**2)
R2 = math.sqrt(Y**2 + (X+Db)**2)
R3 = math.sqrt((X - math.cos(math.pi/3) * Dc)**2 + (Y - math.cos(math.pi/6) * Dc)**2)
return (X, Y, R, R2, R3)
(X, Y, R, R2, R3) = GetXYR(123.0, 114.0, 89.0)
print((X, Y, R, R2, R3))
I get the result (X, Y, R, R2, R3) = (-8.129166703588021, -16.205081335032794, 107.1038654949096, 107.10386549490958, 107.1038654949096)
Which seems reasonable if both Da and Db are longer than Dc, then both coordinates are probably negative.
I calculated the Radius from three equations to cross check whether my calculation makes sense. It seems to fulfill all three equations we set up in the beginning.
Your problem is know a "circumscribed circle". You have a triangle define by 3 distances at given angles from your robot position, then you can construct the circumscribed circle from these three points (see Circumscribed circle from Wikipedia - section "Other properties"). So you know the diameter (if needed).
It is also known that the meeting point of perpendicular bisector of triangle sides is the center of the circumscribed circle.
Let's a=Da, b=Db. The we can write a system for points A and B at the circumference:
(x+b)^2 + y^2 = r^2
(y+a)^2 + x^2 = r^2
After transformations we have quadratic equation
y^2 * (4*b^2+4*a^2) + y * (4*a^3+4*a*b^2) + b^4-4*b^2*r^2+a^4+2*a^2*b^2 = 0
or
AA * y^2 + BB * y + CC = 0
where coefficients are
AA = (4*b^2+4*a^2)
BB = (4*a^3+4*a*b^2)
CC = b^4-4*b^2*r^2+a^4+2*a^2*b^2
So calculate AA, BB, CC coefficients, find solutions y1,y2 of quadratic eqiation, then get corresponding x1, x2 values using
x = (a^2 - b^2 + 2 * a * y) / (2 * b)
and choose real solution pair (where coordinate is inside the circle)
Quick checking:
a=1,b=1,r=1 gives coordinates 0,0, as expected (and false 1,-1 outside the circle)
a=3,b=4,r=5 gives coordinates (rough) 0.65, 1.96 at the picture, distances are about 3 and 4.
Delphi code (does not check all possible errors) outputs x: 0.5981 y: 1.9641
var
a, b, r, a2, b2: Double;
aa, bb, cc, dis, y1, y2, x1, x2: Double;
begin
a := 3;
b := 4;
r := 5;
a2 := a * a;
b2:= b * b;
aa := 4 * (b2 + a2);
bb := 4 * a * (a2 + b2);
cc := b2 * b2 - 4 * b2 * r * r + a2 * a2 + 2 * a2 * b2;
dis := bb * bb - 4 * aa * cc;
if Dis < 0 then begin
ShowMessage('no solutions');
Exit;
end;
y1 := (- bb - Sqrt(Dis)) / (2 * aa);
y2 := (- bb + Sqrt(Dis)) / (2 * aa);
x1 := (a2 - b2 + 2 * a * y1) / (2 * b);
x2 := (a2 - b2 + 2 * a * y2) / (2 * b);
if x1 * x1 + y1 * y1 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x1, y1]))
else
if x2 * x2 + y2 * y2 <= r * r then
Memo1.Lines.Add(Format('x: %6.4f y: %6.4f', [x2, y2]));
From your diagram you have point P that you need it's X & Y coordinate. So we need to find Px and Py or (Px,Py). We know that Ax = Px and By = Py. We can use these for substitution if needed. We know that C & P create a line and all lines have slope in the form of y = mx + b. Where the slope is m and the y intercept is b. We don't know m or b at this point but they can be found. We know that the angle of between two vectors where the vectors are CP and PB gives an angle of 120°, but this does not put the angle in standard position since this is a CW rotation. When working with circles and trig functions along with linear equations of slope within them it is best to work in standard form. So if this line of y = mx + b where the points C & P belong to it the angle above the horizontal line that is parallel to the horizontal axis that is made by the points P & B will be 180° - 120° = 60° We also know that the cos angle between two vectors is also equal to the dot product of those vectors divided by the product of their magnitudes.
We don't have exact numbers yet but we can construct a formula: Since theta = 60° above the horizontal in the standard position we know that the slope m is also the tangent of that angle; so the slope of this line is tan(60°). So let's go back to our linear equation y = tan(60°)x + b. Since b is the y intercept we need to find what x is when y is equal to 0. Since we still have three undefined variables y, x, and b we can use the points on this line to help us here. We know that the points C & P are on this line. So this vector of y = tan(60°)x + b is constructed from (Px, Py) - (Cx, Cy). The vector is then (Px-Cx, Py-Cy) that has an angle of 60° above the horizontal that is parallel to the horizontal axis. We need to use another form of the linear equation that involves the points and the slope this time which happens to be y - y1 = m(x - x1) so this then becomes y - Py = tan(60°)(x - Px) well I did say earlier that we could substitute so let's go ahead and do that: y - By = tan(60°)(x - Ax) then y - By = tan(60°)x - tan(60°)Ax. And this becomes known if you know the actual coordinate points of A & B. The only thing here is that you have to convert your angle of 120° to standard form. It all depends on what your known and unknowns are. So if you need P and you have both A & B are known from your diagram the work is easy because the points you need for P will be P(Ax,By). And since you already said that you know Da, Db & Dc with their lengths then its just a matter of apply the correct trig functions with the proper angle and or using the Pythagorean Theorem to find the length of another leg of the triangle. It shouldn't be all that hard to find what P(x,y) is from the other points. You can use the trig functions, linear equations, the Pythagorean theorem, vector calculations etc. If you can find the equation of the line that points C & P knowing that P has A's x value and has B's y value and having the slope of that line that is defined by the tangent above the horizontal which is 180° - phi where phi is the angle you are giving that is CW rotation and theta would be the angle in standard position or above the horizontal you have a general form of y - By = tan(180° - phi)(x - Ax) and from this equation you can find any point on that line.
There are other methods such as using the existing points and the vectors that they create between each other and then generate an equilateral triangle using those points and then from that equilateral if you can generate one, you can use the perpendicular bisectors of that triangle to find the centroid of that triangle. That is another method that can be done. The only thing you may have to consider is the linear translation of the line from the origin. Thus you will have a shift in the line of (Ax - origin, By - origin) and to find one set the other to 0 and vise versa. There are many different methods to find it.
I just showed you several mathematical techniques that can help you to find a general equation based on your known(s) and unknown(s). It just a matter of recognizing which equations work in which scenario. Once you recognize the correct equations for the givens; the rest is fairly easy. I hope this helps you.
EDIT
I did forget to mention one thing; and that is the line of CP has a point on the edge of the circle defined by (cos(60°), sin(60°)) in the 1st quadrant. In the third quadrant you will have a point on this line and the circle defined by (-cos(60°), -sin(60°)) provided that this line goes through the origin (0,0) where there is no y nor x intercepts and if this is the case then the point on the circle at either end and the origin will be the radius of that circle.
EDIT: THIS IS NOT A DUPLICATE, please read the description of the problem
Just to be clear, these line segments does not have an end point. They start at a point and goes to infinity based on a direction vector. I've found solutions for finite line segments, but they do not apply in this particular case (I think).
So, the title is basically my entire question - I've got
point p1
point p2
direction vector n1 (a normalized vector)
direction vector n2 (a normalized vector)
The first line segment starts at p1 and points towards n1
The second line segment starts at p2 and points towards n2
I need two answers:
If they intersects and
What is the point of intersection
I've found these two answers, but I'm so bad at math that I could not adapt them to fit my problem, but it could help you guys, I hope.
How do you detect where two line segments intersect?
and
Given two points and two vectors, find point of intersection
Thanks a lot!
Edit: (BTW, I'm working at 2D Space, so you don't have to worry about the z axis, thanks)
So, I've used the info provided by this post:
Determining if two rays intersect
And the info provided by a friend to solve this problem.
The first post stated that, given two points (p1 and p2) and two direction vectors (n1 and n2), the following formula applies:
bool DoesRaysIntersects(Point p1, Point p2, Point n1, Point n2)
{
float u = (p1.y * n2.x + n2.y * p2.x - p2.y * n2.x - n2.y * p1.x) / (n1.x * n2.y - n1.y * n2.x);
float v = (p1.x + n1.x * u - p2.x) / n.x;
return u > 0 && v > 0;
}
if both u and v are greater than 0, it's because the two rays collide.
If they collide, we can use the equation of the line to provide the point of collision. I don't know if this is the best way to achieve it, but it worked for me:
First, we need the slope of each of the lines. With their slopes, we can calculate the y-intercept of each line. And with this two datas, we can calculate the point of collision:
Point GetPointOfIntersection(Point p1, Point p2, Point n1, Point n2)
{
Point p1End = p1 + n1; // another point in line p1->n1
Point p2End = p2 + n2; // another point in line p2->n2
float m1 = (p1End.y - p1.y) / (p1End.x - p1.x); // slope of line p1->n1
float m2 = (p2End.y - p2.y) / (p2End.x - p2.x); // slope of line p2->n2
float b1 = p1.y - m1 * p1.x; // y-intercept of line p1->n1
float b2 = p2.y - m2 * p2.x; // y-intercept of line p2->n2
float px = (b2 - b1) / (m1 - m2); // collision x
float py = m1 * px + b1; // collision y
return new Point(px, py); // return statement
}
Thanks everyone!
I've been doing a lot of research on the topic and found a couple of post that where helpful but I just can't get this right.
I am developing a very simple structural analysis app. In this app I need to display a graph showing the internal stress of the beam. The graph is obtained by the formula:
y = (100 * X / 2) * (L - X)
where L is the known length of the beam (lets say its 1 for simplicity). And X is a value between 0 and the Length of be beam. So the final formula would be:
y = (100 * X / 2) * (1 - x) where 0 < X < 1.
Assuming my start and end points are P0 = (0,0) and P2 = (1,0). How can I obtain P2 (control point)?? I have been searching in the Wikipedia page but I am unsure how to obtain the control point from the quadratic bezier curve formula:
B(t) = (1 - t)^2 * P0 + 2*(1 - t)*t * P1 + t^2 * P2
I'm sure it must be such an easy problem to fix… Can anyone help me out?
P.S.: I also found this, How to find the mathematical function defining a bezier curve, which seems to explain how to do the opposite of what I am trying to achieve. I just can't figure out how to turn it around.
We want the quadratic curve defined by y to match the quadratic Bezier curve
defined by B(t).
Among the many points that must match is the peak which occurs at x =
0.5. When x = 0.5,
y = (100 * x / 2) * (1 - x)
100 1 25
y = ---- * --- = ---- = 12.5
4 2 2
Therefore, let's arrange for B(0.5) = (0.5, 12.5):
B(t) = (1-t)^2*(0,0) + 2*(1-t)*t*(Px, Py) + t^2*(1,0)
(0.5, 12.5) = B(0.5) = (0,0) + 2*(0.5)*(0.5)*(Px, Py) + (0.25)*(1,0)
0.5 = 0.5 * Px + 0.25
12.5 = 0.5 * Py
Solving for Px and Py, we get
(Px, Py) = (0.5, 25)
And here is visual confirmation (in Python) that we've found the right point:
# test.py
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 1, 100)
y = (100*x/2)*(1-x)
t = np.linspace(0, 1, 100)
P0 = np.array([0,0])
P1 = np.array([0.5,25])
P2 = np.array([1,0])
B = ((1-t)**2)[:,np.newaxis]*P0 + 2*((1-t)*t)[:,np.newaxis]*P1 + (t**2)[:,np.newaxis]*P2
plt.plot(x, y)
plt.plot(B[:,0], B[:,1])
plt.show()
Running python test.py, we see the two curves overlap:
How did I know to choose t = 0.5 as the parameter value when B(t) reaches its maximum height?
Well, it was mainly based on intuition, but here is a more formal way to prove it:
The y-component of B'(t) equals 0 when B(t) reaches its maximum height. So, taking the derivative of B(t), we see
0 = 2*(1-2t)*Py
t = 0.5 or Py = 0
If Py = 0 then B(t) is a horizontal line from (0,0) to (1,0). Rejecting this degenerate case, we see B(t) reaches its maximum height when t = 0.5.
Your quadratic bezier curve formula has a typo in the middle term. It should be:
B(t) = (1 - t)^2 * P0 + 2 * (1 - t) * t * P1 + t^2 * P2
This means you should take the P1=(1,50) that #unutbu found and divide the coordinates in half to get P1=(.5,25). (This won't matter if you're plotting the parametric equation on your own, but if you want something like LaTeX's \qbezier(0,0)(.5,25)(1,0), then you'll need the corrected point.)
The P1 control point is defined so that the tangent lines at P0 and P2 intersect at P1. Which means that if (P1)x=(P2)x, the graph should be vertical on its righthand side (which you don't want).
In response to your comment, if you have a quadratic y=f(x), then it is symmetrical about its axis (almost tautologically). So the maximum/minimum will occur at the average of the roots (as well as the control point).