【演算法】-003 三次貝塞爾曲線的交點
阿新 • • 發佈:2018-11-05
【演算法】-003 三次貝塞爾曲線的交點
最近在工作中遇到一個問題,想通過計算兩條三次貝塞爾曲線的交點位置。嘗試了列舉法之後覺得計算速度太慢,於是來找其他演算法。
文章目錄
1、 列舉法求貝塞爾曲線交點
在方法中,首先通過確定的步長,計算第一條曲線上的N個點。再計算第二條曲線上的M個點。然後,查詢這N和M個點的最近的點,將距離最小的點作為交點。
在實際應用中,如果計算點數比價少,還是可以接受的。但計算點一多,將導致程式卡頓嚴重。(N=200,M=200)。
2、 一元三次方程求解
三次貝塞爾曲線是關於t的三次函式,兩條貝塞爾曲線的交點等價於求兩條三次曲線的交點,轉換為一元三次方程求解問題。
在解的過程中,我選擇使用MATLAB的roots
函式。使用該函式可以方便的進行一元高次方程的求解。
為了解決MATLAB與別的語言的相互呼叫的關係,我將求解函式的功能使用MATLAB編寫成應用程式,通過配置檔案讀取配置,然後通過UDP接收待解方程的係數矩陣,求解,最後將結果轉換成字串輸出,通過UDP傳送出去。
clc;
clear;
close all;
% 讀取配置檔案資訊
configFilePath='./usl.txt'
configFile = fopen(configFilePath); % 開啟配置檔案
localIP = fgetl(configFile); % 本地IP
localPort = str2num(fgetl(configFile));% 本地埠
remoteIP = fgetl(configFile);% 遠端IP
remotePort = str2num(fgetl(configFile));%遠端埠
fclose(configFile);% 關閉配置檔案
% 建立使用的UDP socket
udpSock = udp(remoteIP,remotePort,'LocalPort' ,localPort);
set(udpSock,'TimeOut',30);
set(udpSock,'InputBufferSize',8192);
fopen(udpSock);% 開啟UDP socket
srvInfo=sprintf('Server is running at port %s:%d\n',localIP,localPort)
fwrite(udpSock,srvInfo); % 向遠端傳送伺服器上線資訊
str=[];
str1 = [];
while(1)
data = str2num(fscanf(udpSock)); %從UDP中讀取資料
if(~isempty(data)) % 讀取到資料,防止是超時返回
if data(1) == 0
% 收到退出訊息
srvInfo=sprintf('Recv exit signal\n')
fwrite(udpSock,srvInfo);
break;
else
% 求解方程組
tStart = tic;
[res ]= roots(data(2:end));
tStop = toc(tStart)
[x y] = size(res);
for i = 1:x
str1 = sprintf('%d = %f+%.5fi : ',i,real(res(i)),imag(res(i)));
str=[str,str1];
if i == x
str1 = sprintf('\n');
str=[str,str1];
end
end
% 向遠端輸出方程解資訊
fwrite(udpSock,str);
str
str = [];
str1=[];
end
else
srvInfo=sprintf('Server is running at port %s:%d\n',localIP,localPort)
fwrite(udpSock,srvInfo); % 向遠端傳送伺服器上線資訊
end
end
% 通知伺服器即將退出
srvInfo=sprintf('Server is going to die!\n')
fwrite(udpSock,srvInfo);
% 關閉伺服器
fclose(udpSock);
delete(udpSock);