点在线段上? 应该是很常用的:已知点p(x,y)。线段的两个端点(x1,y1) (x2,y2).判断点是否在该线段上?有哪位仁兄可以给我现成源代码的?谢谢。:) 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如下步骤:1. 点p, 端点p1, p2;计算矢量 v = p2-p1; v 单位化2. 计算v的垂直向量, n.x = -v.y; n.y = v.x;3. 计算矢量 vd = p-p1;4. 计算投影 fProj = vd * n; 注意这是点乘5. 取 fProj 绝对值;如果绝对值小于 fTolerance(一个小量)那么就认为点p落于直线p1p2上。注意是直线而不是线段6. (p-p1) * (p-p2) 如果小于0,则点p落于线段之上,否则,点p落于线段之外。============================================================================提问题时标题要简明扼要地说明问题内容,切忌使用"急","求救"之类不能说明问题的标题http://www.betajin.com/alphasun/index.htm 给我发信息请附带原帖地址http://alphasun.18en.com/ http://shakingtoolkit.9126.com/DocWizard C++程序文档自动生成工具 | Wave OpenGL | HttpProxy | AjaxParser词法分析 已经经过调试,结果正确。#include <stdio.h>#include <math.h>void main(){ int x1, x2, y1, y2; int x, y; int d, d1, d2; x1 = x2 = 10; y1 = 0; y2 = 100; printf("请输入x, y"); scanf("%d %d", &x, &y); d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1)); d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2)); d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); if(d == (d1 + d2)) printf("点在直线上"); else printf("点不在直线上");} 如果改成float型或double型。那么需要像楼上说的,加入一个最小值if(d == (d1 + d2))改为if(abs((d - d1 - d2) < mini)) d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1)); d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2)); d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); if(d == (d1 + d2)) printf("点在直线上"); else printf("点不在直线上");这段代码在线段上也可以行得通?确认没错了么? (m_ipTraceX[i]-m_ipTraceX[0])+m_ipTraceY[0]; if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x) { //AfxMessageBox("ok1"); break;//此时点在其上 }凑热闹炮炮说的对。我用两点直线公式计算 没贴全:if((m_ipTraceX[i]-m_ipTraceX[0])==0)continue; iTemY=(float)(m_MidPoint.x-m_ipTraceX[0])*(m_ipTraceY[i]-m_ipTraceY[0])/ (m_ipTraceX[i]-m_ipTraceX[0])+m_ipTraceY[0]; if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x) { //AfxMessageBox("ok1"); break; } if(d == (d1 + d2))这样是算不对的 http://msdn.microsoft.com/library/en-us/dngdi/html/msdn_hittest2.asp?frame=trueMSDN提供的技术文档“Win32: Hit Testing Lines and Curves” // 线段而不是直线if (x<x1 && x<x2) return false;if (x>x1 && x>x2) return false;if (y<y1 && y<y2) return false;if (y>y1 && y>y2) return false;// 点重合if (x==x1 && y==y1) return true;if (x==x2 && y==y2) return true;const double point10_x = double(x )-double(x1);const double point10_y = double(y )-double(y1);const double point12_x = double(x2)-double(x1);const double point12_y = double(y2)-double(y1);if (0==point10_x || 0==point12_x)// 有竖直线 return 0==point10_x && 0==point12_x;// both 竖直线if (point10_y/point10_x == point12_y/point12_x) return true; // 斜率相同return false; 如果原来的点也是用double 保存的话最多是18浮点次加法、2次浮点乘法如果原来的点也是用long 保存的话最多是12次整数加法、6次浮点加法、2次浮点乘法 to syl08341(沈阳老零):try the followed codes on.x1 = 0;y1 = 0;x2 = 1;y2 = 2;x = 1;y = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));if(d == (d1 + d2)) MessageBox ("点在直线上");else MessageBox ("点不在直线上"); [上面那个例子不典型]x1 = 0;y1 = 0;x2 = 1;y2 = 4; // <= change y2 to be 4 (or more large number) x = 1;y = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));if(d == (d1 + d2)) MessageBox ("点在直线上");else MessageBox ("点不在直线上"); 我的程序在整数情况下肯定是可行的。对于浮点数或double型,我在第一个贴子后面就说了,见我的第二个贴子。/*如果改成float型或double型。那么需要像楼上说的,加入一个最小值if(d == (d1 + d2))改为if(abs((d - d1 - d2) < mini))*/ To Panr(光荣):谢谢你给我指出问题,不过我编写这个程序主要是提供一个思路。而且在程序后面已经有一个贴子说明了对于整数可行,对于浮点数的改法。 没错,思路是对的(其实我的代码也是应该加个误差值判断比较好 ^_^)其实我想说的是int d, d1, d2;to be double d, d1, d2; 求一本详细讲解HOOK的教材! [请问]关于模版类的问题 _beginthreadex启动的线程函数,是否在return之前加_endthreadex(0)? 翻页显示小问题 重载函数, 要想只把其中一个定义为虚函数, 是不可行的? 如何让OnPaint()按自己的愿意执行? 虚函数的问题!! ●●C语言里的幂运算符是什么?●● 如何在IE工具栏增加一个可以保持按下状态的按钮?(解决后给200分) WIN7 下加载自己的DLL 关于新版WIN32 CORE SDK 的一个 新API int __cdecl _resetstkoflw (void); 在MFC中关于文件操作(请教)
1. 点p, 端点p1, p2;计算矢量 v = p2-p1; v 单位化
2. 计算v的垂直向量,
n.x = -v.y;
n.y = v.x;
3. 计算矢量 vd = p-p1;
4. 计算投影 fProj = vd * n; 注意这是点乘
5. 取 fProj 绝对值;如果绝对值小于 fTolerance(一个小量)那么就认为点p落于直线p1p2上。注意是直线而不是线段
6. (p-p1) * (p-p2) 如果小于0,则点p落于线段之上,否则,点p落于线段之外。
============================================================================
提问题时标题要简明扼要地说明问题内容,切忌使用"急","求救"之类不能说明问题的标题
http://www.betajin.com/alphasun/index.htm 给我发信息请附带原帖地址
http://alphasun.18en.com/ http://shakingtoolkit.9126.com/
DocWizard C++程序文档自动生成工具 | Wave OpenGL | HttpProxy | AjaxParser词法分析
#include <stdio.h>
#include <math.h>void main()
{
int x1, x2, y1, y2;
int x, y;
int d, d1, d2;
x1 = x2 = 10;
y1 = 0;
y2 = 100;
printf("请输入x, y");
scanf("%d %d", &x, &y);
d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
if(d == (d1 + d2))
printf("点在直线上");
else
printf("点不在直线上");}
那么需要像楼上说的,加入一个最小值
if(d == (d1 + d2))
改为if(abs((d - d1 - d2) < mini))
d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
if(d == (d1 + d2))
printf("点在直线上");
else
printf("点不在直线上");
这段代码在线段上也可以行得通?确认没错了么?
if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x)
{
//AfxMessageBox("ok1");
break;//此时点在其上
}
凑热闹
炮炮说的对。我用两点直线公式计算
if((m_ipTraceX[i]-m_ipTraceX[0])==0)continue;
iTemY=(float)(m_MidPoint.x-m_ipTraceX[0])*(m_ipTraceY[i]-m_ipTraceY[0])/
(m_ipTraceX[i]-m_ipTraceX[0])+m_ipTraceY[0];
if(iTemY>=m_MidPoint.y-0.9&&iTemY<m_MidPoint.y+0.9&&m_ipTraceX[i]>m_MidPoint.x)
{
//AfxMessageBox("ok1");
break;
}
这样是算不对的
if (x<x1 && x<x2) return false;
if (x>x1 && x>x2) return false;
if (y<y1 && y<y2) return false;
if (y>y1 && y>y2) return false;
// 点重合
if (x==x1 && y==y1) return true;
if (x==x2 && y==y2) return true;const double point10_x = double(x )-double(x1);
const double point10_y = double(y )-double(y1);
const double point12_x = double(x2)-double(x1);
const double point12_y = double(y2)-double(y1);
if (0==point10_x || 0==point12_x)// 有竖直线
return 0==point10_x && 0==point12_x;// both 竖直线if (point10_y/point10_x == point12_y/point12_x)
return true; // 斜率相同
return false;
最多是18浮点次加法、2次浮点乘法如果原来的点也是用long 保存的话
最多是12次整数加法、6次浮点加法、2次浮点乘法
try the followed codes on.x1 = 0;y1 = 0;
x2 = 1;y2 = 2;
x = 1;y = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
if(d == (d1 + d2))
MessageBox ("点在直线上");
else
MessageBox ("点不在直线上");
x2 = 1;y2 = 4; // <= change y2 to be 4 (or more large number)
x = 1;y = 1;d1 = sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
d2 = sqrt((x-x2)*(x-x2) + (y-y2)*(y-y2));
d = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
if(d == (d1 + d2))
MessageBox ("点在直线上");
else
MessageBox ("点不在直线上");
对于浮点数或double型,我在第一个贴子后面就说了,
见我的第二个贴子。
/*
如果改成float型或double型。
那么需要像楼上说的,加入一个最小值
if(d == (d1 + d2))
改为if(abs((d - d1 - d2) < mini))
*/
而且在程序后面已经有一个贴子说明了对于整数可行,对于浮点数的改法。
int d, d1, d2;
to be
double d, d1, d2;