已知两条曲线上的点坐标(xi,yi),求二者交点。只需对曲线上线段进行遍历求线段交点即可,效果如下

下面是c++代码实现

头文件 CalLineCrossPt.h

#include "stdafx.h"
#include <vector>
using namespace std;typedef struct tagPosition
{double  x;double  y;tagPosition(double _x,double _y) { x=_x; y=_y;}tagPosition() {};bool operator==(const tagPosition & pt) { return (x==pt.x && y==pt.y);}
}CPosition;CPosition IsLineCross(CPosition pt1,CPosition pt2,CPosition pt3,CPosition pt4);
void CalTwoLineCrossPoint(CPosition *_coord1,int _num1, CPosition *_coord2, int _num2,CPosition mincal,CPosition maxcal, vector<CPosition> &_crosspts);
void CalMulLinesCrossPoint(CPosition **_coord, int _numline, int *_numpt, vector<CPosition> &_crosspts);

实现文件 CalLineCrossPt.cpp

//================================================================
// 功能:    离散曲线求交点
//
// 作者:    jiangjp   1034378054@qq.com
// 单位:    China University of Geosciences (Wuhan)
// 日期:    2013/8/13
//================================================================#include "stdafx.h"
#include "CalLineCrossPt.h"void CalMulLinesCrossPoint(CPosition **_coord, int _numline, int *_numpt, vector<CPosition> &_crosspts)
{float xmin1,xmax1,xmin2,xmax2;    // 存储两条线所在矩形区域的两个端点(最大最小坐标)float ymin1,ymax1,ymin2,ymax2;CPosition mincal,maxcal;          // 存储两条线所在区域重叠形成的矩形区域两端点(最大最小坐标)CPosition *linemin=new CPosition[_numline];   // 开辟空间存储每条测线的x,y值最小点CPosition *linemax=new CPosition[_numline];   // 开辟空间存储每条测线的x,y值最大点vector<CPosition> tmpcrosspt;for(int i=0;i<_numline;i++){            // 查找每条线最大最小值linemin[i].x=_coord[i][0].x;linemin[i].y=_coord[i][0].y;linemax[i].x=_coord[i][0].x;linemax[i].y=_coord[i][0].y;for(int j=1;j<_numpt[i];j++){        if(_coord[i][j].x>linemax[i].x)  linemax[i].x=_coord[i][j].x;if(_coord[i][j].x<linemin[i].x)  linemin[i].x=_coord[i][j].x;if(_coord[i][j].y>linemax[i].y)  linemax[i].y=_coord[i][j].y;if(_coord[i][j].y<linemin[i].y)  linemin[i].y=_coord[i][j].y;   }}for(int i=0;i<_numline-1;i++){        // 对所有线两两循环   xmin1=linemin[i].x;               // 获取第一条线最大最小值点xmax1=linemax[i].x;ymin1=linemin[i].y;ymax1=linemax[i].y;for(int j=i+1;j<_numline;j++){ xmin2=linemin[j].x;           // 获取第二条线最大最小值点xmax2=linemax[j].x;ymin2=linemin[j].y;ymax2=linemax[j].y;if(xmin1>xmax2 || xmin2>xmax1 || ymin1>ymax2 || ymin2>ymax2)   // 如果两线所在区域重叠则不需要计算交点continue;else{mincal.x=xmin1>xmin2 ? xmin2 : xmin1;mincal.y=ymin1>ymin2 ? ymin2 : ymin1;maxcal.x=xmax1>xmax2 ? xmax1 : xmax2;maxcal.y=ymax1>ymax2 ? ymax1 : ymax2;}CalTwoLineCrossPoint(_coord[i],_numpt[i], _coord[j],_numpt[j],mincal, maxcal,tmpcrosspt);int numcrosspt=tmpcrosspt.size();for (int k=0;k<numcrosspt;k++){_crosspts.push_back(tmpcrosspt.at(k));}tmpcrosspt.clear();}}delete []linemin;delete []linemax;
}void CalTwoLineCrossPoint(CPosition *_coord1,int _num1, CPosition *_coord2, int _num2,CPosition mincal,CPosition maxcal, vector<CPosition> &_crosspts)         // 计算两条线交点
{     //  _coord1, _coord2分别为2条线坐标,_num1,_num2分别为2条线上点数目,mincal ,maxcal为两条线相交区域的矩形区域两个角点,_crosspts为所求的交点CPosition pos1,pos2,pos3,pos4;bool Found=false;for(int i=0;i<_num1-1;i++){        // 对条线相邻两点组成的线段依次求交点for(int j=0;j<_num2-1;j++){pos1=_coord1[i];           //  获取相邻点线段pos2=_coord1[i+1];pos3=_coord2[j];pos4=_coord2[j+1];// 判断所求线段是否在两测线相交区域内,如果在则进行求交点,否则不求if(pos1.x>=mincal.x && pos1.x<=maxcal.x && pos1.y>=mincal.y && pos1.y<=maxcal.y      && pos2.x>=mincal.x && pos2.x<=maxcal.x && pos2.y>=mincal.y && pos2.y<=maxcal.y&& pos3.x>=mincal.x && pos3.x<=maxcal.x && pos3.y>=mincal.y && pos3.y<=maxcal.y&& pos4.x>=mincal.x && pos4.x<=maxcal.x && pos4.y>=mincal.y && pos4.y<=maxcal.y ){CPosition cpt=IsLineCross(pos1,pos2,pos3,pos4);      //  对两线段求交点if(cpt.x!=-1 && cpt.y!=-1){_crosspts.push_back(cpt);}}}}
}CPosition IsLineCross(CPosition pt1,CPosition pt2,CPosition pt3,CPosition pt4)
{                         // 线段pt1pt2用1标记,线段pt3pt4用2标记,如k1,k2float xmin1=pt1.x>pt2.x ? pt2.x: pt1.x;float xmax1=pt1.x>pt2.x ? pt1.x: pt2.x;float ymin1=pt1.y>pt2.y ? pt2.y: pt1.y;float ymax1=pt1.y>pt2.y ? pt1.y: pt2.y;float xmin2=pt3.x>pt4.x ? pt4.x: pt3.x;float xmax2=pt3.x>pt4.x ? pt3.x: pt4.x;float ymin2=pt3.y>pt4.y ? pt4.y: pt3.y;float ymax2=pt3.y>pt4.y ? pt3.y: pt4.y;if(xmin1>xmax2 || xmin2>xmax1 || ymin1>ymax2 || ymin2>ymax2)return CPosition(-1,-1);if(pt1.x==pt2.x)      // 当线段1斜率不存在{if(pt3.x==pt4.x){  // 当线段2斜率不存在    return CPosition(-1,-1);   // 当交点不存在返回(-1,-1)点}else              // 当线段2斜率存在  {float k2=(pt4.y-pt3.y)/(pt4.x-pt3.x);   // 计算线段2斜率float x=pt1.x;float y=k2*(x-pt3.x)+pt3.y;         // 将线段1的点x坐标带入线段2float xmin2=pt3.x>pt4.x ? pt4.x : pt3.x;float xmax2=pt3.x>pt4.x ? pt3.x : pt4.x;float ymin1=pt1.y>pt2.y ? pt2.y :pt1.y;float ymax1=pt1.y>pt2.y ? pt1.y :pt2.y;if( x>=xmin2 && x<=xmax2 ){     // 不考虑交点在两线段端点if( y>=ymin1 && y<=ymax1 ){ // 如果所求y在线段1的范围之内则有交点return CPosition(x,y);    // 返回交点}else{return CPosition(-1,-1);}}else{return CPosition(-1,-1);}}}else   // 如果线段1斜率存在{ if(pt3.x==pt4.x){    // 如果线段2斜率不存在float k1=(pt2.y-pt1.y)/(pt2.x-pt1.x);float x=pt3.x;float y=k1*(x-pt1.x)+pt1.y;float xmin1=pt1.x>pt2.x ? pt2.x :pt1.x;float xmax1=pt1.x>pt2.x ? pt1.x :pt2.x;float ymin2=pt3.y>pt4.y ? pt4.y :pt3.y;float ymax2=pt3.y>pt4.y ? pt3.y :pt4.y;if( x>=xmin1 && x<=xmax1 ){  //如果交点位于线段端点视为没有交点if( y>=ymin2 && y<=ymax2 ){   return CPosition(x,y);}else{return CPosition(-1,-1);}}else{return CPosition(-1,-1);}}else   // 如果线段1和线段2斜率都存在{float k1=(pt2.y-pt1.y)/(pt2.x-pt1.x);   // 计算线段1和线段2的斜率float k2=(pt4.y-pt3.y)/(pt4.x-pt3.x);if(k1==k2)return CPosition(-1,-1);float x=((pt3.y-pt1.y+k1*pt1.x-k2*pt3.x))/(k1-k2);   // 计算两线段的交点float y=k1*(x-pt1.x)+pt1.y;float xmin1=pt1.x>pt2.x ? pt2.x : pt1.x;float xmax1=pt1.x>pt2.x ? pt1.x : pt2.x;float xmin2=pt3.x>pt4.x ? pt4.x : pt3.x;float xmax2=pt3.x>pt4.x ? pt3.x : pt4.x;if((x>=xmin1 && x<=xmax1) && (x>=xmin2 && x<=xmax2)){  // 判断线段交点是否在两线段x范围之内return CPosition(x,y);}else{return CPosition(-1,-1);}}}
}

主程序 main

// CurveCrossTest.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include <vector>
using namespace std;#include "CalLineCrossPt.h"int _tmain(int argc, _TCHAR* argv[])
{vector<CPosition> a;float line1_x[9]={1, 3, 4.5, 5.5, 6, 6,   8, 9,   10};float line1_y[9]={1, 3, 0,   0.5, 2, 2.7, 0, 1.5, 1.3};float line2_x[10]={0, 1, 1.3, 3,   4,   5.5, 7, 7, 8, 9};float line2_y[10]={1, 3, 3,   1.5, 1.9, 8,   0, 8, 3, 0};float line3_x[6]={1, 2, 3, 4, 5, 6};float line3_y[6]={6, 6, 6, 6, 6, 5.5};int line_num=3;int *numpt_line=new int[line_num];numpt_line[0]=9;numpt_line[1]=10;numpt_line[2]=6;CPosition **coord=new CPosition *[line_num];for (int i=0;i<line_num;i++){coord[i]=new CPosition[numpt_line[i]];}for (int j=0;j<numpt_line[0];j++){coord[0][j]=CPosition(line1_x[j],line1_y[j]);printf("line1: %f %f\n",coord[0][j].x,coord[0][j].y);}for (int j=0;j<numpt_line[1];j++){coord[1][j]=CPosition(line2_x[j],line2_y[j]);printf("line2: %f %f\n",coord[1][j].x,coord[1][j].y);}for (int j=0;j<numpt_line[2];j++){coord[2][j]=CPosition(line3_x[j],line3_y[j]);printf("line3: %f %f\n",coord[2][j].x,coord[2][j].y);}vector<CPosition> crosspts;CalMulLinesCrossPoint(coord, line_num, numpt_line, crosspts);int N=crosspts.size();FILE *fp_m = fopen("crosspt.txt", "wt");for (int i = 0; i < N; i++){fprintf(fp_m, "%lf %lf\n", crosspts.at(i).x,crosspts.at(i).y);}fclose(fp_m);return 0;
}

程序运行生成交点坐标文件crosspt.txt,可用matlab绘制图像如下

附matlab绘图代码

clear all;
clc;
close all;line1_x=[1, 3, 4.5, 5.5, 6, 6,   8, 9,   10];
line1_y=[1, 3, 0,   0.5, 2, 2.7, 0, 1.5, 1.3];line2_x=[0, 1, 1.3, 3,   4,   5.5, 7, 7, 8, 9];
line2_y=[1, 3, 3,   1.5, 1.9, 8,   0, 8, 3, 0];line3_x=[1, 2, 3, 4, 5, 6];
line3_y=[6, 6, 6, 6, 6, 5.5];crosspt=textread('crosspt.txt');
[numcrosspt,n]=size(crosspt);figure
h1=plot(line1_x,line1_y,'*-k'); hold on
h2=plot(line2_x,line2_y,'*-b');
h3=plot(line3_x,line3_y,'*-g');
h4=plot(crosspt(:,1),crosspt(:,2),'or','LineWidth',3);
legend([h1 h2 h3 h4],'Line1','Line2','Line3','CrossPoints');

任意离散点曲线求交点c++实现相关推荐

  1. matlab给定四点求交点,Matlab有关曲线求交点程序分享

    前几天本人遇到了一些难题,就是怎样求曲线的交点,不过现在找到了一些源程序,和与我遇到相同问题的朋友们分享一下! 转自<工程计算可视化与MATLAB实现>尚涛等编著 武汉大学出版社 两直线相 ...

  2. 求两条曲线的交点 matlab,matlab求两条曲线交点

    用Matlab 实现了 3 次样条曲线插值的算法.边界条件取为自然边界条件,即:... 二元一次函数曲线拟合的Matlab实现_IT/计算机_专业资料.第 27 卷 1... (x1)); y2=in ...

  3. 3次Bezier曲线求交

    算法描述: 将文件中点的坐标代入到三次Bezier曲线表达式,给定步长,在两条曲线上各取n个点,分别计算各点距离,若距离小于给定的精度值d_p则认为相交,若两个交点的x距离小于给定的精度值x_p则认为 ...

  4. opencv根据直线方程求交点坐标

    # 均值滤波 dst_jz = cv2.blur(dst2,(9,9)) cv2.imshow("dst_sb", dst_jz)# 高斯滤波 dst_gs = cv2.Gauss ...

  5. C语言的单链表求交点

    单链表求交点,问题如下: 使用o(1)的空间复杂度,求两个链表相交的时候的交点,这个思想就类似于使用o(1)的空间复杂度和o(n)的时间复杂度来求链表的第k个节点. 过程如下: 获取两个链表的长度 将 ...

  6. ]数据结构:单链表之判断两个链表是否相交及求交点(带环、不带环)

    1.判断两个链表是否相交,若相交,求交点.(假设链表不带环) 两个指针同时指向两个链表,分别依次往后遍历链表到最后一个节点,如指针的值相同(即节点地址相同),反之没有交点. int IsCross(N ...

  7. 两条直线求交点c语言,C§ 3.3.1两条直线的交点坐标(5页)-原创力文档

    § 3.1两条直线的交点坐标 学习目标 1.掌握判断两直线相交的方法:会求两直线交点坐标: 2.体会判断两直线相交中的数形结合思想. 学习过程 一.课前准备: (预习教材P112~ P114,找出疑 ...

  8. poj 1039 Pipe (判断 直线和 线段 是否相交 并 求交点)

    http://poj.org/problem?id=1039 题意:已知电缆是由一段段直的管道连接而成的,并知道这些管道的位置,问一束光从最左边射进来,你可以调节光入射的位置和角度,问最远能射到多远. ...

  9. 用Origin找两曲线的交点

    用Origin找两曲线的交点 Select Gadgets: Intersect... from the main menu to open the dialog. Go to the Options ...

最新文章

  1. 1900万印度人疯抢6万份工作,加班至死,这才是真正的就业崩溃!
  2. Croc Champ 2013 - Round 2 (Div. 2 Edition) 贪心+ 搜索+剪枝 + 数学
  3. caffe各层参数详解
  4. 分享一个关于生鲜电商的竞品分析报告
  5. 输入班级人数,根据人数,挨个输入成绩,求平均分,求最高分最低分
  6. 大整数相乘python fft_Python带你理解用于信号同步的CAZAC序列
  7. java游戏猿人时代_猿人时代增值版_JAVA游戏免费版下载_7723手机游戏[www.7723.cn]
  8. cad高程测绘图lisp_CAD地形图高程信息快速提取的技术与实现
  9. tair用ldb做分布式存储
  10. 训练3.21(C:Summer Dichotomy)
  11. chrome浏览器模拟慢网速环境
  12. 计算机论文结束语致谢,论文结束语和致谢
  13. VScode seting.json 配置 自用
  14. $().each() 与 $.each()区别
  15. 某计算机采用lcd显示器 玩大型游戏,[1]. 液晶显示器(LCD)作为计算机的一种图文输出设备,已逐渐普及,下列关于液晶显示器的叙述中错误的是_______。...
  16. JKNetworking完整文档
  17. 配置SNAT实现共享上网
  18. AB 测试中12个常见误区
  19. Python是个什么鬼?为什么建筑设计都要学它?
  20. 中英文打字专家 卡巴斯基杀毒软件

热门文章

  1. 通过高通平台简单总结的权限问题
  2. python 读取 url 图片并保存到本地
  3. NuGet学习笔记(转)
  4. 8Manage PM:通过项目管理信息系统做好进度管控
  5. H3C交换机镜像的几种方法
  6. vsto clickonce 发布setup.exe失败
  7. IAP_1_几种下载程序的方式
  8. C语言的stdio解释(4)
  9. 04 frameset-iframe【尚硅谷JavaWeb教程】
  10. 2014年中南大学研究生复试机试题(字符串、基础dp、最短路)