【算法】-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);