Uniformize two discrete curves to measure minimal distance.

3 Ansichten (letzte 30 Tage)
Hello,
I have two discrete curves, they each consist of two vertical arrays for x and for y.
Now I want to move the red curve in the picture to the right by a factor f to achieve a minimum distance between the two curves. The problem is that the coordinate points of the two curves are not uniform, so they both have different steps in x and y direction. The steps are not even consistent in each curve.
My idea was now to make the koordinates uniform like a grid and then I could calculate the horizontal and the vertical distance between the curves (the minimum distance would be even better) and add the missing increment to the x value of the red curve.
I managed to uniformize the x-axis with the function interp1, but I couldn't manage to uniformize the y-axis aswell which would make the vertical comparison possible but the horizontal would still be difficult. Another problem is that the red curve now doesn't reach the bottom anymore because the interpolation point isn't on the same spot like the y=0 point, as can be seen in the bottom graph. This is also an important requirement.
I also searched for other functions like https://de.mathworks.com/help/matlab/ref/graph.distances.html for example, but it requieres a graph as input and I'm not familiar with that data type.
The coordinates of the two curves are the following:
x1=[0;0.3756;1.5134;3.2905;5.4696;7.8739;10.4061;13.0115;15.6615;18.3430;21.0478;23.7702;26.5063;29.2534;32.0094;34.7731;37.5433;40.3192;43.0999;45.8851;48.6741;51.4667;54.2625;57.0613;59.8628;62.6669;65.4733;68.2818;71.0924;73.9049;76.7193;79.5353;82.3530;85.1723;87.9930;90.8150;93.6384;96.4630;99.2887;102.1155;104.9433;107.7721;110.6017;113.4321;116.2632;119.0950;121.9274;124.7604;127.5937;130.4274;133.2614;136.0957;138.9300;141.7644;144.5987;147.4326;150.2661;153.0990;155.9311;158.7622;161.5920;164.4203;167.2469;170.0715;172.8937;175.7132;178.5297;181.3427;184.1519;186.9571;189.7578;192.5535;195.3433;198.1260;200.9007;203.6661;206.4214;209.1654;211.8973;214.6170;217.3250;220.0225;222.7118;225.3949;228.0745;230.7527;233.4314;236.1122;238.7961;241.4836;244.1749;246.8697;249.5678;252.2689;254.9735;257.6824;260.3970;263.1188;265.8490;268.5887;271.3384;274.0988];
y1=[0;2.8009;5.3860;7.5857;9.3934;10.8914;12.1634;13.2789;14.2840;15.2020;16.0487;16.8370;17.5770;18.2752;18.9369;19.5659;20.1654;20.7383;21.2869;21.8127;22.3175;22.8023;23.2681;23.7157;24.1460;24.5595;24.9568;25.3385;25.7047;26.0558;26.3921;26.7136;27.0206;27.3130;27.5911;27.8548;28.1043;28.3395;28.5606;28.7674;28.9599;29.1382;29.3022;29.4518;29.5869;29.7074;29.8131;29.9038;29.9793;30.0393;30.0833;30.1108;30.1211;30.1131;30.0859;30.0385;29.9699;29.8793;29.7659;29.6292;29.4689;29.2845;29.0750;28.8396;28.5773;28.2875;27.9694;27.6224;27.2462;26.8405;26.4047;25.9373;25.4356;24.8971;24.3192;23.6992;23.0347;22.3248;21.5698;20.7719;19.9351;19.0652;18.1698;17.2564;16.3325;15.4047;14.4783;13.5580;12.6467;11.7463;10.8571;9.9787;9.1103;8.2517;7.4038;6.5698;5.7545;4.9637;4.2027;3.4764;2.7886;2.1457];
x2=[55,3050;55,3056;55,3093;55,3194;55,3392;55,3717;55,4203;55,4882;55,5787;55,6953;55,8413;56,0207;56,2374;56,4958;56,8009;57,1584;57,5751;58,0595;58,6222;59,2774;60,0453;60,9556;62,0582;63,4478;65,3654;70,2818]
y2=[0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25]
I would appreciate any kind of help, of course different approaches than mine are also very welcome.
Also I use Matlab R2020a with all toolboxes.
  2 Kommentare
KSSV
KSSV am 1 Jun. 2020
If you want to move any curve to the right by r, add r to x coordinate values.
David Schlegel
David Schlegel am 1 Jun. 2020
Bearbeitet: David Schlegel am 1 Jun. 2020
Sure that would be the last step, but first I have to evaluate by how much to move it to the right to achieve a minimum distance between the curves. The position in the grafic is already an estimate by the intersection of the y coordinates of both curves, it isn't an exact intersection because of the discrete nature of the curves I stated before.
Now when I have another red curve it may look like this:
And obviously then the value to move it to the right is different than in the first example to achieve the minimum distance. So you got it exactly right, the question is how to evaluate the amout r by which to move the red curve to the right?

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

KSSV
KSSV am 1 Jun. 2020
How about this?
clc; clear all ;
x1=[0;0.3756;1.5134;3.2905;5.4696;7.8739;10.4061;13.0115;15.6615;18.3430;21.0478;23.7702;26.5063;29.2534;32.0094;34.7731;37.5433;40.3192;43.0999;45.8851;48.6741;51.4667;54.2625;57.0613;59.8628;62.6669;65.4733;68.2818;71.0924;73.9049;76.7193;79.5353;82.3530;85.1723;87.9930;90.8150;93.6384;96.4630;99.2887;102.1155;104.9433;107.7721;110.6017;113.4321;116.2632;119.0950;121.9274;124.7604;127.5937;130.4274;133.2614;136.0957;138.9300;141.7644;144.5987;147.4326;150.2661;153.0990;155.9311;158.7622;161.5920;164.4203;167.2469;170.0715;172.8937;175.7132;178.5297;181.3427;184.1519;186.9571;189.7578;192.5535;195.3433;198.1260;200.9007;203.6661;206.4214;209.1654;211.8973;214.6170;217.3250;220.0225;222.7118;225.3949;228.0745;230.7527;233.4314;236.1122;238.7961;241.4836;244.1749;246.8697;249.5678;252.2689;254.9735;257.6824;260.3970;263.1188;265.8490;268.5887;271.3384;274.0988];
y1=[0;2.8009;5.3860;7.5857;9.3934;10.8914;12.1634;13.2789;14.2840;15.2020;16.0487;16.8370;17.5770;18.2752;18.9369;19.5659;20.1654;20.7383;21.2869;21.8127;22.3175;22.8023;23.2681;23.7157;24.1460;24.5595;24.9568;25.3385;25.7047;26.0558;26.3921;26.7136;27.0206;27.3130;27.5911;27.8548;28.1043;28.3395;28.5606;28.7674;28.9599;29.1382;29.3022;29.4518;29.5869;29.7074;29.8131;29.9038;29.9793;30.0393;30.0833;30.1108;30.1211;30.1131;30.0859;30.0385;29.9699;29.8793;29.7659;29.6292;29.4689;29.2845;29.0750;28.8396;28.5773;28.2875;27.9694;27.6224;27.2462;26.8405;26.4047;25.9373;25.4356;24.8971;24.3192;23.6992;23.0347;22.3248;21.5698;20.7719;19.9351;19.0652;18.1698;17.2564;16.3325;15.4047;14.4783;13.5580;12.6467;11.7463;10.8571;9.9787;9.1103;8.2517;7.4038;6.5698;5.7545;4.9637;4.2027;3.4764;2.7886;2.1457];
x2=[55,3050;55,3056;55,3093;55,3194;55,3392;55,3717;55,4203;55,4882;55,5787;55,6953;55,8413;56,0207;56,2374;56,4958;56,8009;57,1584;57,5751;58,0595;58,6222;59,2774;60,0453;60,9556;62,0582;63,4478;65,3654;70,2818] ;
y2=[0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25] ;
% Limit the values to 80
idx1 = x1 <= 80 ;
idx2 = x2 <= 80 ;
x1 = x1(idx1) ; y1 = y1(idx1) ;
x2 = x2(idx2) ; y2 = y2(idx2) ;
% Make (x1,y1) and (x2,y2) to same size
n = 500 ;
x1new = linspace(min(x1),max(x1),n) ;
y1new = interp1(x1,y1,x1new) ;
x1 = x1new ; y1 = y1new ;
% Get the minimum distance from x2(end), y2(end)
d = sqrt((x2(end)-x1).^2+(y2(end)-y1).^2) ;
[val,idx] = min(d) ;
% point on (x1,y1)
plot(x1,y1,'r',x2,y2,'b')
hold on
plot(x2(end),y2(end),'*r')
plot(x1(idx),y1(idx),'*r')
title(sprintf("minimum distance = %f",val))
  4 Kommentare
KSSV
KSSV am 1 Jun. 2020
clc; clear all ;
x1=[0;0.3756;1.5134;3.2905;5.4696;7.8739;10.4061;13.0115;15.6615;18.3430;21.0478;23.7702;26.5063;29.2534;32.0094;34.7731;37.5433;40.3192;43.0999;45.8851;48.6741;51.4667;54.2625;57.0613;59.8628;62.6669;65.4733;68.2818;71.0924;73.9049;76.7193;79.5353;82.3530;85.1723;87.9930;90.8150;93.6384;96.4630;99.2887;102.1155;104.9433;107.7721;110.6017;113.4321;116.2632;119.0950;121.9274;124.7604;127.5937;130.4274;133.2614;136.0957;138.9300;141.7644;144.5987;147.4326;150.2661;153.0990;155.9311;158.7622;161.5920;164.4203;167.2469;170.0715;172.8937;175.7132;178.5297;181.3427;184.1519;186.9571;189.7578;192.5535;195.3433;198.1260;200.9007;203.6661;206.4214;209.1654;211.8973;214.6170;217.3250;220.0225;222.7118;225.3949;228.0745;230.7527;233.4314;236.1122;238.7961;241.4836;244.1749;246.8697;249.5678;252.2689;254.9735;257.6824;260.3970;263.1188;265.8490;268.5887;271.3384;274.0988];
y1=[0;2.8009;5.3860;7.5857;9.3934;10.8914;12.1634;13.2789;14.2840;15.2020;16.0487;16.8370;17.5770;18.2752;18.9369;19.5659;20.1654;20.7383;21.2869;21.8127;22.3175;22.8023;23.2681;23.7157;24.1460;24.5595;24.9568;25.3385;25.7047;26.0558;26.3921;26.7136;27.0206;27.3130;27.5911;27.8548;28.1043;28.3395;28.5606;28.7674;28.9599;29.1382;29.3022;29.4518;29.5869;29.7074;29.8131;29.9038;29.9793;30.0393;30.0833;30.1108;30.1211;30.1131;30.0859;30.0385;29.9699;29.8793;29.7659;29.6292;29.4689;29.2845;29.0750;28.8396;28.5773;28.2875;27.9694;27.6224;27.2462;26.8405;26.4047;25.9373;25.4356;24.8971;24.3192;23.6992;23.0347;22.3248;21.5698;20.7719;19.9351;19.0652;18.1698;17.2564;16.3325;15.4047;14.4783;13.5580;12.6467;11.7463;10.8571;9.9787;9.1103;8.2517;7.4038;6.5698;5.7545;4.9637;4.2027;3.4764;2.7886;2.1457];
x2=[3.000;3.0033;3.0267;3.0902;3.2145;3.4224;3.7413;4.2101;4.8961;5.9611;8.9907];
y2=[0;1;2;3;4;5;6;7;8;9;10];
% Make (x1,y1) and (x2,y2) to same size
n = 1000 ;
x1new = linspace(min(x1),max(x1),n) ;
y1new = interp1(x1,y1,x1new) ;
x1 = x1new ; y1 = y1new ;
% Get the minimum distance from x2(end), y2(end)
d = sqrt((x2(end)-x1).^2+(y2(end)-y1).^2) ;
[val,idx] = min(d) ;
% point on (x1,y1)
plot(x1,y1,'r',x2,y2,'b')
hold on
plot(x2(end),y2(end),'*r')
plot(x1(idx),y1(idx),'*r')
title(sprintf("minimum distance = %f",val))
xlim([0 20])
David Schlegel
David Schlegel am 1 Jun. 2020
Actually I solved it with the function knnsearch now, thanks alot!
The code I use now looks like this:
x1=[0;0.3756;1.5134;3.2905;5.4696;7.8739;10.4061;13.0115;15.6615;18.3430;21.0478;23.7702;26.5063;29.2534;32.0094;34.7731;37.5433;40.3192;43.0999;45.8851;48.6741;51.4667;54.2625;57.0613;59.8628;62.6669;65.4733;68.2818;71.0924;73.9049;76.7193;79.5353;82.3530;85.1723;87.9930;90.8150;93.6384;96.4630;99.2887;102.1155;104.9433;107.7721;110.6017;113.4321;116.2632;119.0950;121.9274;124.7604;127.5937;130.4274;133.2614;136.0957;138.9300;141.7644;144.5987;147.4326;150.2661;153.0990;155.9311;158.7622;161.5920;164.4203;167.2469;170.0715;172.8937;175.7132;178.5297;181.3427;184.1519;186.9571;189.7578;192.5535;195.3433;198.1260;200.9007;203.6661;206.4214;209.1654;211.8973;214.6170;217.3250;220.0225;222.7118;225.3949;228.0745;230.7527;233.4314;236.1122;238.7961;241.4836;244.1749;246.8697;249.5678;252.2689;254.9735;257.6824;260.3970;263.1188;265.8490;268.5887;271.3384;274.0988];
y1=[0;2.8009;5.3860;7.5857;9.3934;10.8914;12.1634;13.2789;14.2840;15.2020;16.0487;16.8370;17.5770;18.2752;18.9369;19.5659;20.1654;20.7383;21.2869;21.8127;22.3175;22.8023;23.2681;23.7157;24.1460;24.5595;24.9568;25.3385;25.7047;26.0558;26.3921;26.7136;27.0206;27.3130;27.5911;27.8548;28.1043;28.3395;28.5606;28.7674;28.9599;29.1382;29.3022;29.4518;29.5869;29.7074;29.8131;29.9038;29.9793;30.0393;30.0833;30.1108;30.1211;30.1131;30.0859;30.0385;29.9699;29.8793;29.7659;29.6292;29.4689;29.2845;29.0750;28.8396;28.5773;28.2875;27.9694;27.6224;27.2462;26.8405;26.4047;25.9373;25.4356;24.8971;24.3192;23.6992;23.0347;22.3248;21.5698;20.7719;19.9351;19.0652;18.1698;17.2564;16.3325;15.4047;14.4783;13.5580;12.6467;11.7463;10.8571;9.9787;9.1103;8.2517;7.4038;6.5698;5.7545;4.9637;4.2027;3.4764;2.7886;2.1457];
Matrix1=[x1 y1];
%Define minimum distance
t=3;
while dist<t
x2=x2+0.1;
Matrix2=[x2 y2];
[Idx,D] = knnsearch(Matrix1,Matrix2);
dist=min(D)
end

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Interpolation finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by