参考自:http://zhidao.baidu.com/question/146717333
LineIntersect.h
//
// LineIntersect.h
// HungryBear
//
// Created by Bruce Yang on 12-3-12.
// Copyright (c) 2012年 EricGameStudio. All rights reserved.
//
#import <cstdio>
#import "Box2D.h"
#define zero(x) (((x)>0?(x):-(x))<b2_epsilon)
@interface LineIntersect : NSObject
#pragma mark-
#pragma mark 适用于 b2Vec2 的版本~
// 判两线段相交,包括端点和部分重合
+(int) intersect_in:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2;
// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!)
+(b2Vec2) intersection:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2;
#pragma mark-
#pragma mark 适用于 CGPoint 的版本~
+(int) intersect_in2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2;
// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!)
+(CGPoint) intersection2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2;
#pragma mark-
#pragma mark 验证上述几个方法的移植是否存在什么问题~
+(void) validateAlgorithm;
@end
LineIntersect.mm
//
// LineIntersect.mm
// HungryBear
//
// Created by Bruce Yang on 12-3-12.
// Copyright (c) 2012年 EricGameStudio. All rights reserved.
//
#import "LineIntersect.h"
@implementation LineIntersect
// 计算交叉乘积 (P1-P0)x(P2-P0)
+(double) xmult:(b2Vec2)p1 p2:(b2Vec2)p2 p3:(b2Vec2)p0 {
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
// 判点是否在线段上,包括端点
+(int) dot_online_in:(b2Vec2)p l1:(b2Vec2)l1 l2:(b2Vec2)l2 {
return zero([self xmult:p p2:l1 p3:l2]) &&
(l1.x-p.x)*(l2.x-p.x) < b2_epsilon &&
(l1.y-p.y)*(l2.y-p.y) < b2_epsilon;
}
// 判两点在线段同侧,点在线段上返回0
+(int) same_side:(b2Vec2)p1 p2:(b2Vec2)p2 l1:(b2Vec2)l1 l2:(b2Vec2)l2 {
return [self xmult:l1 p2:p1 p3:l2] * [self xmult:l1 p2:p2 p3:l2] > b2_epsilon;
}
// 判两直线平行
+(int) parallel:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2 {
return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));
}
// 判三点共线
+(int) dots_inline:(b2Vec2)p1 p2:(b2Vec2)p2 p3:(b2Vec2)p3 {
return zero([self xmult:p1 p2:p2 p3:p3]);
}
// 判两线段相交,包括端点和部分重合
+(int) intersect_in:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2 {
if (![self dots_inline:u1 p2:u2 p3:v1] || ![self dots_inline:u1 p2:u2 p3:v2]) {
return ![self same_side:u1 p2:u2 l1:v1 l2:v2] && ![self same_side:v1 p2:v2 l1:u1 l2:u2];
} else {
return [self dot_online_in:u1 l1:v1 l2:v2] ||
[self dot_online_in:u2 l1:v1 l2:v2] ||
[self dot_online_in:v1 l1:u1 l2:u2] ||
[self dot_online_in:v2 l1:u1 l2:u2];
}
}
// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!)
+(b2Vec2) intersection:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2 {
b2Vec2 ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
#pragma mark-
#pragma mark 适用于 CGPoint 的版本~
// 计算交叉乘积 (P1-P0)x(P2-P0)
+(double) xmult2:(CGPoint)p1 p2:(CGPoint)p2 p3:(CGPoint)p0 {
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
// 判点是否在线段上,包括端点
+(int) dot_online_in2:(CGPoint)p l1:(CGPoint)l1 l2:(CGPoint)l2 {
return zero([self xmult2:p p2:l1 p3:l2]) &&
(l1.x-p.x)*(l2.x-p.x) < b2_epsilon &&
(l1.y-p.y)*(l2.y-p.y) < b2_epsilon;
}
// 判两点在线段同侧,点在线段上返回0
+(int) same_side2:(CGPoint)p1 p2:(CGPoint)p2 l1:(CGPoint)l1 l2:(CGPoint)l2 {
return [self xmult2:l1 p2:p1 p3:l2] * [self xmult2:l1 p2:p2 p3:l2] > b2_epsilon;
}
// 判两直线平行
+(int) parallel2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2 {
return zero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));
}
// 判三点共线
+(int) dots_inline2:(CGPoint)p1 p2:(CGPoint)p2 p3:(CGPoint)p3 {
return zero([self xmult2:p1 p2:p2 p3:p3]);
}
+(int) intersect_in2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2 {
if (![self dots_inline2:u1 p2:u2 p3:v1] || ![self dots_inline2:u1 p2:u2 p3:v2]) {
return ![self same_side2:u1 p2:u2 l1:v1 l2:v2] && ![self same_side2:v1 p2:v2 l1:u1 l2:u2];
} else {
return [self dot_online_in2:u1 l1:v1 l2:v2] ||
[self dot_online_in2:u2 l1:v1 l2:v2] ||
[self dot_online_in2:v1 l1:u1 l2:u2] ||
[self dot_online_in2:v2 l1:u1 l2:u2];
}
}
// 计算两线段交点,请判线段是否相交(同时还是要判断是否平行!)
+(CGPoint) intersection2:(CGPoint)u1 u2:(CGPoint)u2 v1:(CGPoint)v1 v2:(CGPoint)v2 {
CGPoint ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
#pragma mark-
#pragma mark 验证上述几个方法的移植是否存在什么问题~
+(void) validateIntersect:(b2Vec2)u1 u2:(b2Vec2)u2 v1:(b2Vec2)v1 v2:(b2Vec2)v2 {
b2Vec2 answer;
if ([self parallel:u1 u2:u2 v1:v1 v2:v2] || ![self intersect_in:u1 u2:u2 v1:v1 v2:v2]){
printf("无交点!\n");
} else {
answer = [self intersection:u1 u2:u2 v1:v1 v2:v2];
printf("交点为:(%lf,%lf)\n", answer.x, answer.y);
}
}
+(void) validateAlgorithm {
[LineIntersect validateIntersect:b2Vec2(0, 1) u2:b2Vec2(1, 0) v1:b2Vec2(0, 0) v2:b2Vec2(1, 1)];
[LineIntersect validateIntersect:b2Vec2(0, 10) u2:b2Vec2(10, 0) v1:b2Vec2(0, 0) v2:b2Vec2(10, 10)];
[LineIntersect validateIntersect:b2Vec2(-2, 0) u2:b2Vec2(2, 0) v1:b2Vec2(-1, 3) v2:b2Vec2(-1, -1)];
[LineIntersect validateIntersect:b2Vec2(-2, 0) u2:b2Vec2(2, 0) v1:b2Vec2(-1, 3) v2:b2Vec2(1, -2)];
}
@end
再提供一个判断两直线相交的方法,与上对比貌似更加高效一些~
/**
* 判断两条线段是否相交,参见如下链接:
* http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/
*/
+(bool) checkLineIntersection:(b2Vec2)p1 :(b2Vec2)p2 :(b2Vec2)p3 :(b2Vec2)p4 {
CGFloat denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);
// In this case the lines are parallel so we assume they don't intersect~
if(denominator == 0.0f) {
return false;
}
CGFloat ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator;
CGFloat ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator;
if(ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) {
return true;
}
return false;
}
分享到:
相关推荐
用于判断两条线段是否相交的可重用类,用objective-c书写,可直接放在项目里面使用之~
这儿的运行时系统扮演的角色类似于Objective-C语言的操作系统,Objective-C基于该系统来工作。本文档将具体介绍NSObject类以及Objective-C程序是如何和运行时系统交互的。特别地,本文档还给出来怎样在运行时动态地加
Objective-C语言的许多决策可以在编译和运行时执行。只要有可能,它是动态的。这意味着Objective-C语言不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。Runtime系统是一种用于Objective-C语言的操作系统...
《objective-c程序设计》通过大量的实例系统地介绍了objective-c语言的基本概念、语法规则、框架、类库及开发环境。读者在阅读《objective-c程序设计》后,可以掌握objective-c语言的基本内容,并进行实际的iphone/...
希望这个简单的Objective-C语言教程能够为你提供一个入门的起点。Objective-C是一种面向对象的编程语言,广泛应用于Mac OS和iOS开发。通过学习Objective-C的基本语法、类和对象、控制流程和方法等内容,你将能够编写...
用Objective-C语言实现了各种设计模式,收集各种例子,方便大家学习和普及设计模式。.zip用Objective-C语言实现了各种设计模式,收集各种例子,方便大家学习和普及设计模式。.zip用Objective-C语言实现了各种设计...
《Objective-C 程序设计(第4版)》作者假设读者没有面向对象程序语言或者C语言(Objective-C基础)编程经验,因此,初学者和有经验的程序员都可以使用这本《Objective-C 程序设计(第4版)》学习Objective-C。...
C语言主要知识点巩固(学习Objective-C 的前提),PPT格式。
中文名: Objective-C基础教程 作者: Mark Dalrymple Scott Knaster译者: 高朝勤 杨越 刘霞图书 分类: 软件 资源格式: PDF 版本: 扫描版 出版社: 人民邮电出版社 书号: ISBN: 9787115208774 发行时间: 2009...
Objective-C 是一种通用、面向对象的编程语言,广泛应用于 macOS 和 iOS 等苹果平台的开发中。它是 C 语言的超集,结合了 Smalltalk 式的消息传递机制和 C++ 的特性。Objective-C 是苹果公司采用的主要编程语言之一...
在windows系统下搭建Objective-C开发环境,由于公司要做iphone开发,个人学习objc(Objective-C)语法,所以在windows7下搭建了一个objc开发环境,现把自己整理的帮助文档拿来与大家分享,希望能对大家有所帮助。...
Objective-C是创建Mac OS应用和iPhone应用的主要语言,优雅的面向对象编程环境与C语言特性珠联璧合,造就了它的不俗表现。 本书全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例...
elcome to Learn Objective- C on the Mac! This book is designed to teach you the basics of the Objective- C language. Objective- C is a superset of C and is the language used by many (if not most) ...
这是一个基于Objective-C语言的基础案例集。旨在用于给初学者快速了解Objective-C语言的语法。.zip
Objective-C是扩展C的面向对象编程语言,也是iPhone开发用到的主要语言。本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中...
Objective-C高级编程 iOS与OS X多线程和内存管理.pdf
资源里面包含Objective-C 2.0程序设计 原书中文版第2版及代码,还包含Effective Objective-C 2.0英文版完整的电子书