How to find tangent line of curve
57 次查看(过去 30 天)
显示 更早的评论
Hi guys, I'm new to matlab and I was trying to create a code that generates a graph with the tangent line of temperature by time. The data is a file with the temperature values and the transfer function. If anyone can help me that would be great.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1197568/image.jpeg)
I would have to generate a graph similar to this one:
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1197638/image.png)
% FOPDT (First order lag plus time delay)
load Equipe2;
y=yy; % temperature values y(t)
plot(y)
0 个评论
回答(2 个)
Image Analyst
2022-11-18
编辑:Image Analyst
2022-11-18
Do you have any data? What I'd do is to scan your data vector fitting the values within a certain window width to a quadratic. From the coefficients of the quadratic you can get the slope at the point at the center of the sliding window. Then knowing the slope you can use the point-slope formula for a line, and the desired length of the line to get the endpoints of a line segment tangent to your curve at that point. Upload a vector of your data values in a .mat or text file if you need more help.
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
[EDIT] Seems like you're having trouble, so here is a demo:
fontSize = 12
x = linspace(0, 12, 1000);
deltax = x(2) - x(1)
period = 3;
y = sin(2 * pi * x / period);
plot(x, y, 'b-', 'LineWidth', 4);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
windowWidth = 51; % An odd number
halfWindowWidth = floor(windowWidth/2)
for k = halfWindowWidth + 1 : 66 : numel(x) - halfWindowWidth
thisSectionX = x(k-halfWindowWidth : k + halfWindowWidth);
thisSectionY = y(k-halfWindowWidth : k + halfWindowWidth);
% Fit to a quadratic or cubic. y = c(1) * x^2 + c(2) * x + c(3)
coefficients = polyfit(thisSectionX, thisSectionY, 2);
xCenter = thisSectionX(halfWindowWidth + 1);
yCenter = thisSectionY(halfWindowWidth + 1);
slope = 2 * coefficients(1) * xCenter + coefficients(2);
% (y - yCenter) = (x - xCenter) * slope.
% y = (x - xCenter) * slope + yCenter.
segmentLength = 2;
% Get the endpoints of the tangent line segment.
x1 = xCenter - halfWindowWidth * deltax;
x2 = xCenter + halfWindowWidth * deltax;
y1 = (x1 - xCenter) * slope + yCenter;
y2 = (x2 - xCenter) * slope + yCenter;
hold on;
% Plot line segment in red.
plot([x1, x2], [y1, y2], 'r.-', 'LineWidth', 2, 'MarkerSize', 20);
% Plot center point of line segment at a cyan dot.
plot(xCenter, yCenter, 'c.', 'MarkerSize', 20);
end
1 个评论
Image Analyst
2022-11-18
编辑:Image Analyst
2022-11-18
Using your data:
fontSize = 20;
s = load('Equipe2.mat')
y = s.yy;
x = linspace(0, 20, length(y));
deltax = x(2) - x(1)
plot(x, y, 'b-', 'LineWidth', 4);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
windowWidth = 251; % An odd number
halfWindowWidth = floor(windowWidth/2)
% Find the index where x = 7
k = find(x >= 7, 1, 'first');
thisSectionX = x(k-halfWindowWidth : k + halfWindowWidth);
thisSectionY = y(k-halfWindowWidth : k + halfWindowWidth);
% Fit to a quadratic or cubic. y = c(1) * x^2 + c(2) * x + c(3)
coefficients = polyfit(thisSectionX, thisSectionY, 2);
xCenter = thisSectionX(halfWindowWidth + 1);
yCenter = thisSectionY(halfWindowWidth + 1);
slope = 2 * coefficients(1) * xCenter + coefficients(2);
% (y - yCenter) = (x - xCenter) * slope.
% y = (x - xCenter) * slope + yCenter.
segmentLength = 2;
% Get the endpoints of the tangent line segment.
x1 = xCenter - halfWindowWidth * deltax;
x2 = xCenter + halfWindowWidth * deltax;
y1 = (x1 - xCenter) * slope + yCenter;
y2 = (x2 - xCenter) * slope + yCenter;
% Plot line segment in red.
hold on;
plot([x1, x2], [y1, y2], 'r.-', 'LineWidth', 2, 'MarkerSize', 20);
% Plot center point of line segment at a cyan dot.
plot(xCenter, yCenter, 'c.', 'MarkerSize', 20);
But the data does not look like what your desired data should look like. I think you posted different data.
You might also like to fit it to an exponential, or sigmoid. See attached demos.
Star Strider
2022-11-18
That plot actually looks familiar!
See: How to draw a tangent line on a curve for one approach. (That result used the inflection point of the curve to draw the tangent, so the code is slightly diffenent than the code here.)
I chose a ‘yy’ value of 50 here simply to demonstrate the code. Change the value of ‘select_yy’ to choose a different point. (There are no inflection points here that I can see, although I did not analyse the data carefully to see if one exists.) There is also no associated time vector, so I created one.
Try this —
LD = load(websave('Equipe2','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1197593/Equipe2.mat'));
yy = LD.yy;
Fs = 1; % Sampling Frequency
L = numel(yy);
t = linspace(0, L-1, L).'/Fs; % Time Vector
select_yy = 50; % Delect 'yy' Value At Which To Draw Tangent
idxr = find(diff(sign(yy-select_yy)))+(-1:1); % Index Range
t_yy50 = interp1(yy(idxr), t(idxr), 50) % Associated Time Value
dyydt = gradient(yy) ./ gradient(t); % Numerical Derivative
dyydt50 = interp1(t, dyydt, t_yy50) % Numerical Derivative At Associated Time
y_intcpt = select_yy - dyydt50*t_yy50 % Line Y-Intercept
figure
plot(t, yy, 'DisplayName','Data')
yl = ylim;
hold on
plot(t_yy50, select_yy, '.r', 'DisplayName','Tangent Point')
plot(t, dyydt50*t+y_intcpt, '-r', 'DisplayName','Tangent Line')
hold off
ylim(yl)
grid
legend('Location','best')
Make appropriate changes to get the desired result.
.
2 个评论
Image Analyst
2022-11-18
His plot went from 0 to 20 so I created the x axis like this:
x = linspace(0, 20, length(y));
Star Strider
2022-11-18
That was a different problem. (I remember it, because my code in the Answer I quoted generated that same plot.) I have no idea what the time vector is here because that was not stated. There just needs to be one.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Construction 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!