I have this parametric equation of a 'flower':
x(t) = (r+cos(nlep*t))cos(t),
y(t) = (r+cos(nlep*t))sin(t)
where nlep is the numper of petals, r - radius. I want to create a trajectory that bounces (reflects maybe) inside this curve starting at (0,0). The problem I came across is that I can't seem to be able to determine whether a point belongs to a curve. I need that to calculate when to change direction. It seems not possible to exclude t
parameter. So I tried to sovle a system of nonlinear equations. However, I am not sure how to set the initial value of t
whenever I solve the system. Here is my code:
t = linspace(-10, 10, 100);
x = (r + cos(nlep*t)).*cos(t);
y = (r + cos(nlep*t)).*sin(t);
plot(x, y, 'g')
hold on
So for example I am going alone a horizontal line and want to determine points which belong to a curve:
p = linspace(min(x), max(x), 100);
for j=1:length(p)
f = @(t) ([((r + cos(nlep*t)).*cos(t))-p(j); ((r + cos(nlep*t)).*sin(t))-3]);
[t0, fval, info] = fsolve(f, t(j));
if info==1 # info is never 1
plot(p(j), 3, 'r')
endif
endfor
But nothing apart from the curve itself is plotted. What should be the way to do it? Could somebody please give a hint? Thanks in advance.
Your system doesn't typically have a solution - it's a system of two equations with just one unknown, t
. fsolve
can only minimize the norm of the two function results, but it can't make both zero for the same t
.
If I understood correctly, you want to find the intersections of the curve with a line, let's say
y = a * x + b
, with known values of a
and b
. Then, you have to solve one equation:
f = @(t) a * (r + cos(nlep*t)).*cos(t) + b - (r + cos(nlep*t)).*sin(t);
which is a * x + b - y
with x
and y
replaced by the curve parametric form. After you found the solution, t0
, the coordinates
are found by applying the parametric formulae, x0 = (r + cos(nlep*t0)) * cos(t0)
and y0 = (r + cos(nlep*t0)) * sin(t0)
- obviously, the solution point is part of the curve.
Here's the curve, line and solution plot in a particular case:
r = 1; nlep = 5;
t = linspace(-pi, pi, 100);
x = (r + cos(nlep*t)).*cos(t);
y = (r + cos(nlep*t)).*sin(t);
plot(x, y, 'g')
hold on
a = 1; b = 0.5; # y = x + 0.5
% plot the line
p = linspace(min(x), max(x), 100);
yp = a * p + b;
plot(p, yp, '-b')
% find and plot an intersection point
f = @(t) a * (r + cos(nlep*t)).*cos(t) + b - (r + cos(nlep*t)).*sin(t);
[t0, fval, info] = fsolve(f, t(j));
if info==1
x0 = (r + cos(nlep*t0))*cos(t0);
y0 = (r + cos(nlep*t0))*sin(t0);
disp([x0, y0]);
% plot the solution point
plot(x0, y0, '*r', 'MarkerSize', 10)
endif
hold off
The problem here is that this procedure can only find one solution. To find many/all solutions, one has to try with different initial values for t. Here's a possible version for the final part of the previous piece of code:
% find and plot all intersection points
x0 = [];
y0 = [];
f = @(t) a * (r + cos(nlep*t)).*cos(t) + b - (r + cos(nlep*t)).*sin(t);
for tinitial = linspace(-pi, pi, 20)
[t0, fval, info] = fsolve(f, tinitial);
if info==1
x0new = (r + cos(nlep*t0))*cos(t0);
y0new = (r + cos(nlep*t0))*sin(t0);
% check if the new solution wasn't already found
exists = false;
for i = 1:length(x0)
if(abs(x0(i)-x0new) + abs(y0(i)-y0new) < 1e-5)
exists = true;
break;
endif
endfor
if not(exists) % inefficient, but it happens only a few times.
x0 = [x0, x0new];
y0 = [y0, y0new];
endif
endif
endfor
disp(sprintf('%d solutions found', length(x0)))
% plot the solution points
plot(x0, y0, '*r', 'MarkerSize', 10)
hold off