# Giving a moving point a chance to change path every step?

2 views (last 30 days)
Jack Rimmer on 30 Jan 2021
Answered: Steven Lord on 1 Feb 2021
Here is the current code I have working, but simply put it will randomise 4 coordinates, b, c, d and e, and then animate drawing a line connecting each of them in a given number of steps.
b1 = randi([0 7e5])
b2 = randi([0 7e5])
c1 = randi([0 7e5])
c2 = randi([0 7e5])
d1 = randi([0 7e5])
d2 = randi([0 7e5])
e1 = randi([0 7e5])
e2 = randi([0 7e5])
a = [0,0];
b = [b1,b2];
c = [c1,c2];
d = [d1,d2];
e = [e1,e2];
% straight line function from a to b
func1 = @(x)a(2) + (a(2)-b(2))/(a(1)-b(1))*(x-a(1));
% straight line function from b to c
func2 = @(x)b(2) + (b(2)-c(2))/(b(1)-c(1))*(x-b(1));
% straight line function from c to d
func3 = @(x)c(2) + (c(2)-d(2))/(c(1)-d(1))*(x-c(1));
% straight line function from d to e
func4 = @(x)d(2) + (d(2)-e(2))/(d(1)-e(1))*(x-d(1));
% determine the x values
x1 = linspace(a(1),b(1),20);
x2 = linspace(b(1),c(1),20);
x3 = linspace(c(1),d(1),20);
x4 = linspace(d(1),e(1),20);
% determine the y values
y1 = func1(x1);
y2 = func2(x2);
y3 = func3(x3);
y4 = func4(x4);
% create the figure
figure;
% get a handle to a plot graphics object
hPlot = plot(NaN,NaN,'ro');
% set the axes limits
% iterate through each point on line
for k=1:length(y1)
% update the plot graphics object with the next position
set(hPlot,'XData',x1(k),'YData',y1(k));
% set dotted line
hold on
plot([x1(1), x1(k)], [y1(1), y1(k)], '--k')
xlim([min(0) max(8e5)]);
ylim([min(0) max(8e5)]);
hold off
% pause for 0.1 seconds
pause(0.1);
end
for k=1:length(y2)
% update the plot graphics object with the next position
set(hPlot,'XData',x2(k),'YData',y2(k));
% set dotted line
hold on
plot([x2(1), x2(k)], [y2(1), y2(k)], '--k')
xlim([min(0) max(8e5)]);
ylim([min(0) max(8e5)]);
hold off
% pause for 0.1 seconds
pause(0.1);
end
for k=1:length(y3)
% update the plot graphics object with the next position
set(hPlot,'XData',x3(k),'YData',y3(k));
% set dotted line
hold on
plot([x3(1), x3(k)], [y3(1), y3(k)], '--k')
xlim([min(0) max(8e5)]);
ylim([min(0) max(8e5)]);
hold off
% pause for 0.1 seconds
pause(0.1);
end
for k=1:length(y4)
% update the plot graphics object with the next position
set(hPlot,'XData',x4(k),'YData',y4(k));
% set dotted line
hold on
plot([x4(1), x4(k)], [y4(1), y4(k)], '--k')
xlim([min(0) max(8e5)]);
ylim([min(0) max(8e5)]);
hold off
% pause for 0.1 seconds
pause(0.1);
end
I'm looking for a way which will allow me to input a target value, say 8e5, and the line will start plotting to that point in a given number steps and each step there is a percentage chance that a new target will be generated and the point will change direction and start moving to the new target which would then repeat a given number of times.
Is this possible?
Thanks

Paul Hoffrichter on 1 Feb 2021
Edited: Paul Hoffrichter on 1 Feb 2021
Not sure exactly what you want, but possibly this is getting close. The refactoring should make it easier to modify.
% set randomizer for repeatability; comment out if repeatability not wanted
rng(12345);
%% Inputs:
tgt = 8e5;
changeTgtPercent = 12; % percent (2-100%)
numberTimesToRepeat = 20;
%% create the figure
figure;
hPlot = plot(NaN,NaN,'ro'); % get a handle to a plot graphics object
% set the axes limits
xlim([min(0) max(tgt)]);
ylim([min(0) max(tgt)]);
title(['Change Tgt: ' num2str(changeTgtPercent) '%']);
%% determine the x and y values
pt1 = [0,0];
[xx, yy, lastPt] = selectPath(pt1);
[lastPt, tgt] = movePoint(hPlot, xx, yy, changeTgtPercent, tgt);
while numberTimesToRepeat > 0
[xx, yy, lastPt] = selectPath(lastPt); % determine the x and y values
[lastPt, tgt] = movePoint(hPlot, xx, yy, changeTgtPercent, tgt);
numberTimesToRepeat = numberTimesToRepeat - 1;
end % END Wwhile
%% select a path for the next line
function [xx,yy, lastPt] = selectPath(pt1)
lastPt = [randi([0 7e5]), randi([0 7e5])]; % not sure if you still want this
% determine the xx and yy
xx = linspace(pt1(1),lastPt(1), 20);
func2 = @(x) lastPt(2) + (lastPt(2)-pt1(2))/(lastPt(1)-pt1(1))*(x-lastPt(1)); % straight line to lastPt
yy = func2(xx);
end
%% Draw the moving points
function [lastPoint, newTgt] = movePoint(hpl, xx, yy, changeTgtPercent, tgt)
numPts = length(yy);
rndVal = randi([2 100]);
if rndVal <= min( changeTgtPercent, numPts )
numPts = rndVal;
newTgt = randi([6.5e5 7e5]); % change the target here
else
numPts = length(yy);
newTgt = tgt;
end
for k=1:numPts
% update the plot graphics object with the next position
set(hpl,'XData',xx(k),'YData',yy(k));
% set dotted line
hold on
plot([xx(1), xx(k)], [yy(1), yy(k)], '--k')
hold off
pause(0.02);
end
lastPoint = [xx(k), yy(k)];
end
Paul Hoffrichter on 1 Feb 2021
What you are doing with find is just counting chars.
>> find abcxyz
ans =
1 2 3 4 5 6
You should just run the script directly. You should not try to call selectPath from the command line.
Since you copied the text to MATLAB without making changes, then either your version is broken, or you are not running the program correctly. In either case, by contacting MathWorks, you should be able to resolve the problem.
https://www.mathworks.com/support/contact_us.html?s_tid=hp_ff_s_support

Paul Hoffrichter on 1 Feb 2021
You should just run the script directly. You should not try to call selectPath from the command line.
Jack Rimmer on 1 Feb 2021
Yep that did the trick, thanks a lot for all your help!

Steven Lord on 1 Feb 2021
Rather than creating a large number of small line segments, you may want to look at either the animatedline function (and the addpoints function associated with the lines returned by animatedline) or maybe the comet function.

R2020b

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!