给定p1, p2, p3, p4四个点,p1,p2为一条线段,p3,p4为一条线段,检测其是否有交点。

可分为三种情况:

1. L2与x轴平行

2. L2与y轴平行

3. L2与坐标轴不平行。

(L1与坐标轴平行,类似处理)

基本思路,求出交点坐标,并检测其是否在两个线段内即可。

检测代码:

     public static float min(float x, float y) { return x<y? x: y; }
public static float max(float x, float y) { return x>y? x: y; } public static boolean isSegmentOverlap(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4){
if(p3.x == p4.x){
float x = p3.x;
float y = p1.y + (p3.x-p1.x)*(p2.y-p1.y)/(p2.x-p1.x);
//System.out.println(y);
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>=min(p3.x, p4.x) && x<=max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){
return true;
}
}
else if(p3.y == p4.y){
float x = p1.x + (p3.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y);
float y = p3.y;
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>=min(p3.y, p4.y) && y<=max(p3.y, p4.y) ){
return true;
}
}
else if(p1.x==p2.x || p1.y==p2.y){
return isSegmentOverlap(p3, p4, p1, p2);
}
else{
float k1 = (p2.y-p1.y)/(p2.x-p1.x);
float k2 = (p4.y-p3.y)/(p4.x-p3.x);
float x = (k2*p3.x-k1*p1.x+p1.y-p3.y)/(k2-k1);
float y = k1*(x-p1.x) + p1.y;
//System.out.println( k1 + "," + k2 + "," + x + "," + y );
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){
return true;
}
} return false;
}

实例代码:

 package com.fxb.Gam003;

 import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputListener; public class Lib054_SegmentOverlap extends ApplicationAdapter{ ShapeRenderer rend; Vector2 p1 = new Vector2(300, 100);
Vector2 p2 = new Vector2(500, 200);
Vector2 p3 = new Vector2(300, 200);
Vector2 p4 = new Vector2(400, 300); Rectangle rect = new Rectangle( 100, 100, 200, 200 ); @Override
public void create() {
// TODO Auto-generated method stub
super.create(); rend = new ShapeRenderer();
Gdx.input.setInputProcessor(adapter);
} public static float min(float x, float y) { return x<y? x: y; }
public static float max(float x, float y) { return x>y? x: y; } public static boolean isSegmentOverlap(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4){
if(p3.x == p4.x){
float x = p3.x;
float y = p1.y + (p3.x-p1.x)*(p2.y-p1.y)/(p2.x-p1.x);
//System.out.println(y);
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>=min(p3.x, p4.x) && x<=max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){
return true;
}
}
else if(p3.y == p4.y){
float x = p1.x + (p3.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y);
float y = p3.y;
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>=min(p3.y, p4.y) && y<=max(p3.y, p4.y) ){
return true;
}
}
else if(p1.x==p2.x || p1.y==p2.y){
return isSegmentOverlap(p3, p4, p1, p2);
}
else{
float k1 = (p2.y-p1.y)/(p2.x-p1.x);
float k2 = (p4.y-p3.y)/(p4.x-p3.x);
float x = (k2*p3.x-k1*p1.x+p1.y-p3.y)/(k2-k1);
float y = k1*(x-p1.x) + p1.y;
//System.out.println( k1 + "," + k2 + "," + x + "," + y );
if( x>min(p1.x, p2.x) && x<max(p1.x, p2.x) && y>min(p1.y, p2.y) && y<max(p1.y, p2.y) &&
x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){
return true;
}
} return false;
} public static boolean isSegRectOverlap(Vector2 p1, Vector2 p2, Rectangle rect){
float x = rect.x, y = rect.y, w = rect.width, h = rect.height;
Vector2 rp1 = new Vector2(x, y);
Vector2 rp2 = new Vector2(x+w, y);
Vector2 rp3 = new Vector2(x+w, y+h);
Vector2 rp4 = new Vector2(x, y+h);
//return isSegmentOverlap(p1, p2, rp1, rp2) || isSegmentOverlap(p1, p2, rp2, rp3) ||
// isSegmentOverlap(p1, p2, rp3, rp4) || isSegmentOverlap(p1, p2, rp4, rp1); if( rect.contains(p1) || rect.contains(p2) ){
return true;
} return isSegmentOverlap(p1, p2, rp1, rp2) || isSegmentOverlap(p1, p2, rp2, rp3) ||
isSegmentOverlap(p1, p2, rp3, rp4) || isSegmentOverlap(p1, p2, rp4, rp1);
} @Override
public void render() {
// TODO Auto-generated method stub
super.render();
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); rend.begin(ShapeType.Line); if(isSegmentOverlap(p1, p2, p3, p4)){
rend.setColor(Color.RED);
}
else{
rend.setColor(Color.BLUE);
}
rend.line(p1, p2);
rend.line(p3, p4); // if(isSegRectOverlap(p1, p2, rect)){
// rend.setColor(Color.RED);
// }
// else{
// rend.setColor(Color.BLUE);
// }
// rend.line(p1, p2);
// rend.rect(rect.x, rect.y, rect.width, rect.height); rend.end(); } @Override
public void dispose() {
// TODO Auto-generated method stub
super.dispose();
} InputAdapter adapter = new InputAdapter(){
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
p1.set(screenX, 480-screenY);
return super.touchDown(screenX, screenY, pointer, button);
} @Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
p2.set(screenX, 480-screenY);
return super.touchDragged(screenX, screenY, pointer);
} @Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
p2.set(screenX, 480-screenY);
return super.touchUp(screenX, screenY, pointer, button);
} }; }

运行结果:

 

显示两种状态,相交红色,不相交蓝色。

libgdx学习记录27——线段与线段相交检测的更多相关文章

  1. libgdx学习记录2——文字显示BitmapFont

    libgdx对中文支持不是太好,主要通过Hireo和ttf字库两种方式实现.本文简单介绍最基本的bitmapfont的用法. 代码如下: package com.fxb.newtest; import ...

  2. libgdx学习记录3——动画Animation

    libgdx动画采用Animation实现,即通过帧动画实现. 代码如下: package com.fxb.newtest; import com.badlogic.gdx.ApplicationAd ...

  3. libgdx学习记录26——Polygon多边形碰撞检测

    libgdx中Math封装了Polygon这个类,它是由多个定点进行描述实现的,在进行物体间的碰撞时,物体轮廓有时候是不规则的,这时候可以用一个多边形勾勒出其大概的轮廓,对其进行模拟. Polygon ...

  4. libgdx学习记录25——Rectangle与Circle是否重叠

    Rect与Circle重叠有三种情况: 1. Rect至少有一个角在Circle里面 2. Circle与Rect的左边或右边相交,或者Circle在Rect内 3. Circle与Rect的顶边或底 ...

  5. libgdx学习记录22——3d物体创建

    libgdx是一个强大的游戏框架,不仅支持2d部分,同时还支持3d部分. libgdx的3d部分投影主要通过PerspectiveCamera实现. 物体的显示过程: 1. 创建远景相机,角度一般设为 ...

  6. libgdx学习记录20——多线程MultiThread资源处理

    在libgdx中,一般的逻辑流程都在rende()函数中执行,这个函数是由opengl的渲染线程调用的,一般的图形显示和逻辑处理都在这个线程中. 一般情形下,在这个线程中处理就行了.但是当某些逻辑处理 ...

  7. libgdx学习记录19——图片动态打包PixmapPacker

    libgdx中,opengl 1.x要求图片长宽必须为2的整次幂,一般有如下解决方法 1. 将opengl 1.x改为opengl 2.0.(libgdx 1.0版本后不支持1.x,当然不存在这个问题 ...

  8. libgdx学习记录18——Box2d物理引擎

    libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创 ...

  9. libgdx学习记录17——照相机Camera

    照相机在libgdx中的地位举足轻重,贯穿于整个游戏开发过程的始终.一般我们都通过Stage封装而间接使用Camera,同时我们也可以单独使用Camera以完成背景的移动.元素的放大.旋转等操作. C ...

随机推荐

  1. Kotlin入门(16)容器的遍历方式

    Kotlin号称全面兼容Java,于是乎Java的容器类仍可在Kotlin中正常使用,包括大家熟悉的队列ArrayList.映射HashMap等等.不过Kotlin作为一门全新的语言,肯定还是要有自己 ...

  2. Kotlin入门(17)等式判断的情况

    话说等式可是编程语言最基本的表达式之一,不管哪种高级语言,无一例外都采用双等号“==”判断两个变量是否相等:就算是复杂的对象,在Java中也可通过equals函数判断两个实例是否相等.按理说这些能够满 ...

  3. python中关于类隐藏属性的三种处理方法

    关于隐藏属性 引子: 当类的属性或者类实例对象的属性隐藏的时候必须通过存取器方法来获取和设置这些隐藏的属性. 例如: def get_name(self,name):     #存取器方法 self. ...

  4. springcloud 入门 9 (消息总线)

    Spring cloud bus: Spring cloud bus通过轻量消息代理连接各个分布的节点.这会用在广播状态的变化(例如配置变化)或者其他的消息指令.Spring bus的一个核心思想是通 ...

  5. springcloud 入门 8 (config配置中心)

    Spring Cloud Config: 配置中心为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件,它就是Spring Cloud Config. 在分布式系统中,由于服务数量巨多, ...

  6. 将你的 Virtual dom 渲染成 Canvas

    项目概述 一个基于Vue的virtual dom插件库,按照Vue render 函数的写法,直接将Vue生成的Vnode渲染到canvas中.支持常规的滚动操作和一些基础的元素事件绑定. githu ...

  7. WebSocket实现简单的在线聊天

    SuperWebSocket在WebService中的应用 最开始使用是寄托在IIS中,发布之后测试时半个小时就会断开,所以改为WindowsService 1. 新建Windows服务项目[Test ...

  8. [20180327]行迁移与ITL浪费.txt

    [20180327]行迁移与ITL浪费.txt --//生产系统遇到的一个问题,增加一个字段到表结构,修改数据字典,导致出现行迁移,而更加严重的是没有修改pctfree值,--//以后的业务操作,依旧 ...

  9. 洗礼灵魂,修炼python(12)--python关键词,包

    关键词 1.什么是关键词: 就是系统已经定义好的一些关键词语法,可以直接使用,很明显的就是在IDE里这些关键词会高亮显示的就是 2.有哪些关键词: 前面我们一直在说关键词,内置函数,到底有哪些关键词对 ...

  10. python第九天----今天来晚了!

    作业 1. HAproxy配置文件操作1. 根据用户输入输出对应的backend下的server信息2. 可添加backend 和sever信息3. 可修改backend 和sever信息4. 可删除 ...