c#实现的一些几何算法(二)
来源:互联网 发布:淘宝店怎么看订单 编辑:程序博客网 时间:2024/06/04 23:36
续一
//关于线的一些算法
public class GeometricClass
{
/* 判断点与线段的关系,用途很广泛
本函数是根据下面的公式写的,P是点C到线段AB所在直线的垂足
AC dot AB
r = ---------
||AB||^2
(Cx-Ax)(Bx-Ax) + (Cy-Ay)(By-Ay)
= -------------------------------
L^2
r has the following meaning:
r=0 P = A
r=1 P = B
r<0 P is on the backward extension of AB
r>1 P is on the forward extension of AB
0<r<1 P is interior to AB
*/
public static double RelationOfPointAndLine(SpatialPoint p, SpatialLine l)
{
SpatialLine tl = new SpatialLine();
tl.startPoint = l.startPoint;
tl.endPoint = p;
return dotmultiply(tl.endPoint, l.endPoint, l.startPoint) / (CalculateFlatDistance(l.startPoint, l.endPoint) * CalculateFlatDistance(l.startPoint, l.endPoint));
}
// 根据已知两点坐标,求过这两点的直线解析方程: a*x+b*y+c = 0 (a >= 0)
public static SpatialLine Makeline(SpatialPoint p1, SpatialPoint p2)
{
SpatialLine tl = new SpatialLine();
int sign = 1;
tl.a = p2.y - p1.y;
if (tl.a < 0)
{
sign = -1;
tl.a = sign * tl.a;
}
tl.b = sign * (p1.x - p2.x);
tl.c = sign * (p1.y * p2.x - p1.x * p2.y);
return tl;
}
// 根据直线解析方程返回直线的斜率k,水平线返回 0,竖直线返回 1e200
public static double SlopeOfLine(SpatialLine l)
{
if (Math.Abs(l.a) < INF)
return 0;
if (Math.Abs(l.b) < INF)
return double.MaxValue;
return -(l.a / l.b);
}
// 返回直线的倾斜角alpha ( 0 - pi)
public static double alphaOfLine(SpatialLine l)
{
if (Math.Abs(l.a) < INF)
return 0;
if (Math.Abs(l.b) < INF)
return PI / 2;
double k = SlopeOfLine(l);
if (k > 0)
return Math.Atan(k);
else
return PI + Math.Atan(k);
}
// 求点C到线段AB所在直线的垂足 P
public static SpatialPoint PerpendicularOnLine(SpatialPoint p, SpatialLine l)
{
double r = RelationOfPointAndLine(p, l);
SpatialPoint tp = new SpatialPoint();
tp.x = l.startPoint.x + r * (l.endPoint.x - l.startPoint.x);
tp.y = l.startPoint.y + r * (l.endPoint.y - l.startPoint.y);
return tp;
}
// 求点p到线段l所在直线的距离,请注意本函数与上个函数的区别
public static double DistanceInPointToLine(SpatialPoint p, SpatialLine l)
{
return Math.Abs(multiply(p, l.endPoint, l.startPoint)) / CalculateFlatDistance(l.startPoint, l.endPoint);
}
// 返回线段l1与l2之间的夹角 单位:弧度 范围(-pi,pi)
public static double AngleOfTwoLine(SpatialLine l1, SpatialLine l2)
{
SpatialPoint o, s, e;
o = new SpatialPoint();
s = new SpatialPoint();
e = new SpatialPoint();
o.x = o.y = 0;
s.x = l1.endPoint.x - l1.startPoint.x;
s.y = l1.endPoint.y - l1.startPoint.y;
e.x = l2.endPoint.x - l2.startPoint.x;
e.y = l2.endPoint.y - l2.startPoint.y;
return AngleOfThreePoint(o, s, e);
}
// 如果线段u和v相交(包括相交在端点处)时,返回true
//判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。
//判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。
public static bool IsIntersect(SpatialLine u, SpatialLine v)
{
return ((Math.Max(u.startPoint.x, u.endPoint.x) >= Math.Min(v.startPoint.x, v.endPoint.x)) && //排斥实验
(Math.Max(v.startPoint.x, v.endPoint.x) >= Math.Min(u.startPoint.x, u.endPoint.x)) &&
(Math.Max(u.startPoint.y, u.endPoint.y) >= Math.Min(v.startPoint.y, v.endPoint.y)) &&
(Math.Max(v.startPoint.y, v.endPoint.y) >= Math.Min(u.startPoint.y, u.endPoint.y)) &&
(multiply(v.startPoint, u.endPoint, u.startPoint) * multiply(u.endPoint, v.endPoint, u.startPoint) >= 0) && //跨立实验
(multiply(u.startPoint, v.endPoint, v.startPoint) * multiply(v.endPoint, u.endPoint, v.startPoint) >= 0));
}
// (线段u和v相交)&&(交点不是双方的端点) 时返回true
public static bool IsIntersect_A(SpatialLine u, SpatialLine v)
{
return ((IsIntersect(u, v)) &&
(!PointIsOnLine(u, v.startPoint)) &&
(!PointIsOnLine(u, v.endPoint)) &&
(!PointIsOnLine(v, u.endPoint)) &&
(!PointIsOnLine(v, u.startPoint)));
}
// 线段v所在直线与线段u相交时返回true;方法:判断线段u是否跨立线段v
public static bool intersect_l(SpatialLine u, SpatialLine v)
{
return multiply(u.startPoint, v.endPoint, v.startPoint) * multiply(v.endPoint, u.endPoint, v.startPoint) >= 0;
}
// 如果两条直线 l1(a1*x+b1*y+c1 = 0), l2(a2*x+b2*y+c2 = 0)相交,返回true,且返回交点p
public static bool LineIntersect(SpatialLine l1, SpatialLine l2, out SpatialPoint intersectPoint) // 是 L1,L2
{
double d = l1.a * l2.b - l2.a * l1.b;
intersectPoint = new SpatialPoint();
if (Math.Abs(d) < EP) // 不相交
return false;
intersectPoint.x = (l2.c * l1.b - l1.c * l2.b) / d;
intersectPoint.y = (l2.a * l1.c - l1.a * l2.c) / d;
intersectPoint.h = 0;
return true;
}
// 如果线段l1和l2相交,返回true且交点由(intersectPoint)返回,否则返回false
public static bool LineSegmentIntersection(SpatialLine l1, SpatialLine l2, out SpatialPoint intersectPoint)
{
SpatialLine ll1, ll2;
intersectPoint = new SpatialPoint();
ll1 = Makeline(l1.startPoint, l1.endPoint);
ll2 = Makeline(l2.startPoint, l2.endPoint);
if (LineIntersect(ll1, ll2, out intersectPoint))
return PointIsOnLine(l1, intersectPoint) && PointIsOnLine(l2, intersectPoint);
else
return false;
}
}
- c#实现的一些几何算法(二)
- c#实现的一些几何算法(一)
- c#实现的一些几何算法(三)
- 模式识别几何分类算法实现(二)
- 8种主要排序算法的C#实现 (二)
- 一些几何算法
- C#的一些算法
- 【翻译】计算机几何基础算法(二)
- 算法系列之九:计算几何与图形学有关的几种常用算法(二)
- 算法系列之九:计算几何与图形学有关的几种常用算法(二)
- 算法系列之九:计算几何与图形学有关的几种常用算法(二) .
- 算法系列之九:计算几何与图形学有关的几种常用算法(二)
- 一些常规形几何形状的绘制和效果填充(二)
- 模式识别几何分类算法实现(一)
- 关于计算几何一些算法
- 一些三维计算几何算法
- C#和Java实现互通的RSA&DES加解密算法(二)
- 计算几何与图形学有关的几种常用算法(二)
- 简述HTML控件与Web服务器控件的区别
- 量化成功的项目
- C++面向对象的常考知识点
- 利用AJAX和ASP.NET实现简单聊天室
- Google常用的高效使用方法
- c#实现的一些几何算法(二)
- BrewMP 中国论坛,全面建成
- 日志级别的选择:Debug、Info、Warn、Error还是Fatal
- 作业
- c#实现的一些几何算法(三)
- CSS 中 Display 的一些特殊属性
- 使用memcached缓存 替代solr中的LRUCache缓存
- ext3.0 树控件处理
- SQL SERVER 2008 压缩备份