For a Bezier curve I know the P0,P1 and the
control point P2. (and I can calculate the Q0)
I want to find for a new curve, with Q1(t=0,25) == Q0(t=0,25),
P0==Q0(t=0.25) and P1==Q0(t=0.75),
the new control point P2.
I re-edit my initial post. I've added a picture.
In the picture the blue and red dots are my initial P0 and P1 points and the green dot is the initial control point P2.
Now, I want to find the new control point P2' if I now the purple points P1' and P2'.
In essence I want to draw 2 new curves,
a) from red point to first purple point and
b) from blue point to the second purple point
Any idea?
The question is a bit convoluted but I will give it a shot. To me it seems that OP wants the control points of the segment of the original curve from the parameter value t = 0.25 up to the parameter value t=0.75. This can be achieved using De Casteljau's algorithm twice. Since I haven't found a step-by-step version for quadratic curves on SO, I made one.
Step 0: Take your three control points (note that I name them in a more usual order but I use OP's colour scheme).
Step 1: Use De Casteljau's algorithm for t=0.25. This means that
P_01 = 0.25 * P_0 + (1 - 0.25) * P_1,
P_12 = 0.25 * P_1 + (1 - 0.25) * P_2 and
P_012 = 0.25 * P_01 + (1 - 0.25) * P_12.
Note the purple colour signifying that my P_012 corresponds to the left of OP's purple points.
Step 2: Rename things to simplify writing the second run of the algorithm.
Step 3: Use De Casteljau's algorithm for the second time. But be careful: the parameter value t=0.75 of the original curve corresponds to the parameter value t=2/3 of what is left from it. This means that
P'_01 = 2/3 * P'_0 + (1 - 2/3) * P'_1,
P'_12 = 2/3 * P'_1 + (1 - 2/3) * P'_2 and
P'_012 = 2/3 * P'_01 + (1 - 2/3) * P'_12.
Step 4: Rename things again and pick up the results:
P''_0 is the left of OP's purple points,
P''_1 is the green point OP is looking for and
P''_2 is the right of OP's purple points.
Related
What I have tried already: d = |v||PQ|sin("Theta")
Now, I need to determine what theta is, so I set up a position on a makeshift graph, the graph I made was on the xy plane only as the z plane complicates things needlessly for finding theta. So, I ended up with an acute angle, and if the angle is acute, then I have to find theta which according to dot product facts is greater than 0.
I do not have access to theta, so I used the same princples from cross dots. u * v = |u||v|cos("theta") but in this case, u and v are PQ and v. A vector is a vector, right?
so now I have theta = acos((v*PQ)/(|v||PQ))
with that I get (4sqrt(10))/15 = 32.5125173162 in degrees, so the angle is 32.5125173162 degrees.
So, now that I have theta, I plug it into my distance formula |v||PQ|sin(32.5125173162)
3*sqrt(10)*sin(32.5125173162) = 5.0990195136
or for the sake of simplicity, 5.1
I however want to know if this question is correct.
If it is NOT correct, what can I do to correct it? At what points did I use incorrect information?
This is not a question with a definitive answer in the back of the book, its a question on the side of a page that said: "try this!"
There are a couple of problems with this question.
From the context it looks like you mean for both v and PQ to be vectors. The "distance" between two vectors is an awkward (not well defined) question because vectors are not position bound.
You are using the cross product formula and I have no idea why:
|AxB| = |A||B|Sin(theta)
I think what you are actually trying to do is calculate the distance between the terminal points of the vectors, (2, 1, 2) and (1, 0, 3). Just use the Pythagorean Theorem (extended to 3D) for this.
d = sqrt( (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 )
d = sqrt( (2 - 1)^2 + (1 - 2)^2 + (2 - 3)^2 )
d = sqrt( 1^2 + (-1)^2 + (-1)^2 )
d = sqrt(3)
Edit:
If what you need really is the magnitude of the cross product, |AxB| then just find the cross product (using the determinant) and then calculate the magnitude of the result. There is no need for the formula you were using.
Hi so I have a problem from my differential equations class that I am having difficulty solving with the improved Euler's method:
The logistic equation for the population (in thousands) of a certain species is given by dP/dt = 2P-2P^2. With t being time variable in years
Given P(0) = .5, with step size h = .2 (so .2 of t), find population at 1 year.
I used the normal Euler's method and got 634 but am not sure how to implement the modified Euler's method on the given differential equation.
The improved Euler method or explicit midpoint method has two stages
Stage one is an Euler step with half the step size
Stage two is the full step with the slope from the point from step one.
So if dP/dt = Q(P) then
k1 = Q(P0)
k2 = Q(P0 + h/2 * k1)
P1 = P0 + h * k2
or
Phalf = P0+h/2*Q(P0)
P1 = P0 + h*Q(Phalf)
Given a convex 3d polygon (convex hull) How can I determine the correct direction for normal surface/vertex vectors? As the polygon is convex, by correct I mean outward facing (away from the centroid).
def surface_normal(centroid, p1, p2, p3):
a = p2-p1
b = p3-p1
n = np.cross(a,b)
if **test including centroid?** :
return n
else:
return -n # change direction
I actually need the normal vertex vectors as I am exporting as a .obj file, but I am assuming that I would need to calculate the surface vectors before hand and combine them.
This solution should work under the assumption of a convex hull in 3d. You calculate the normal as shown in the question. You can normalize the normal vector with
n /= np.linalg.norm(n) # which should be sqrt(n[0]**2 + n[1]**2 + n[2]**2)
You can then calculate the center point of your input triangle:
pmid = (p1 + p2 + p3) / 3
After that you calculate the distance of the triangle-center to your surface centroid. This is
dist_centroid = np.linalg.norm(pmid - centroid)
The you can calculate the distance of your triangle_center + your normal with the length of the distance to the centroid.
dist_with_normal = np.linalg.norm(pmid + n * dist_centroid - centroid)
If this distance is larger than dist_centroid, then your normal is facing outwards. If it is smaller, it is pointing inwards. If you have a perfect sphere and point towards the centroid, it should almost be zero. This may not be the case for your general surface, but the convexity of the surface should make sure, that this is enough to check for its direction.
if(dist_centroid < dist_with_normal):
n *= -1
Another, nicer option is to use a scalar product.
pmid = (p1 + p2 + p3) / 3
if(np.dot(pmid - centroid, n) < 0):
n *= -1
This checks if your normal and the vector from the mid of your triangle to the centroid have the same direction. If that is not so, change the direction.
"How to find a third point given both (2 points on a line) and (distance from third point to first point)?"
Language: Visual Basic (2012)
The third point is on the same line as the second, and may be either closer to the first point or it may be closer to the second. This is a function that will handle both (from arrays of data).
Strangely I cannot seem to grasp the distance part of this question. Over reading many other questions on finding points from other points, I am unable to find anything clear enough for me to be able to reverse engineer to include a parameter for distance.
I need to be able to use distance to find a point. The function I am writing is basically a much more advanced form of:
Function GetThirdPoint(CenterPoint As Point, SecondPoint As Point, Range As Integer)
Return [Equations here] 'Return third point
End Function
Let's first point coordinates are P1=(x1,y1), second point P2=(x2,y2).
Then length of P1P2 vector is (use Math.Hypot function if available)
Len = Sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
Normalized (unit-length) direction vector is
dx = (x2-x1) / Len
dy = (y2-y1) / Len
P3 coordinates for case when P1P3 and P1P2 vectors have the same direction:
x3 = x1 + Distance * dx
y3 = y1 + Distance * dy
for opposite direction:
x3 = x1 - Distance * dx
y3 = y1 - Distance * dy
The general equation of a line is:
A*x + B*y + G = 0 where A, B must not be both equal to 0. (1)
You can find A, B, G easily because you know two points of the line (point one and two). The distance is:
D = sqrt( (x1 - x3)(x1 - x3) + (y1 - y3)(y1 - y3) ) (2)
Third point is on the line so from (1):
A*x3 + B*y3 + G = 0 (3)
From (2) and (3), you can find the solution. Because (2) is second degree you will find two solutions.
I have successfully drawn a Quad2D or Bezier curve in java. I have the equation for the same. But I need to determine whether a particular point(x,y) lies on the curve or not. I tried using Quad2D.contains and a few GeneralPath APIs, I could not get the result accurately.
Can someone help to find out the solution to this?
I think you've meant QuadCurve2D class, which is quadratic Bezier curve.
There seems to be no ready-made method for that, and the problem comes to the distance from the point to the Bezier curve.
Let's P0 will be your point, P1 is a start point, P2 - a control point and P3 is an end point of your curve.
Then point on the curve will be given by
P = B(t)
There is such t, for which distance between P and P0 will be minimal.
F(t) = (B(t)_x - P0_x)^2 + (B(t)_y - P0_y)^2 -> min
If distance is 0 or less than certain error, then P0 is on the curve.
t can be found with Netwon's iterative method by minimizing cost function
t_n = t_n-1 + F'(t) / F''(t)
where F' is first derivative of cost function and F'' is its second derivative.
F'(t) = 2 * (B(t)_x - P0_x) * B'(t)_x + 2 * (B(t)_y - P0_y) * B'(t)_y
F''(t) = 2 * B'(t)_x * B'(t)_x + 2 * (B(t)_x - P0_x) * B''(t)_x +
2 * B'(t)_y * B'(t)_y + 2 * (B(t)_y - P0_x) * B''(t)_y
First derivative of quadratic Bezier curve B'(t) is a line segment with a start point (P2 - P1) and end point (P3 - P2). Second derivative B''(t) is a point P3 - 2 * P2 + P1.
Plugging everything together will give a formula to t for which F(t) is minimal.