给定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. github版本控制相关

    Git版本控制: 安装Github http://blog.csdn.net/huangyuan_xuan/article/details/49125597 Git本地版本控制 http://blog ...

  2. python第二十九天-----继续学习第三模块——前几天旅行去了

    subprocess模块 import subprocess subprocess.getstatusoutput('dir')#接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结 ...

  3. 统计分页一些sql

    USE [QPTreasureDB] GO /****** Object: StoredProcedure [dbo].[GameStatistics] Script Date: 2018/8/16 ...

  4. python中json序列化的东东

    之所以写这个因为自己总是弄混了,容易弄错,记下来有事没事看看   序列化是指把变量从内存中变成可存储或传输的过程称之为序列化用(使用dump或者dumps),把变量内容从序列化的对象重新读到 内存里称 ...

  5. 启用crontab

    1.登录到root用户. 2.在root下输入:crontab -e 3.可能会提示你: no crontab for root - using an empty one 然后会叫你“Select a ...

  6. 布局:高度已知,布局一个三栏布局,左栏和右栏宽度为200px,中间自适应

    需求:高度已知为200px,写出三栏布局,左栏和右栏各位200px,中间自适应,如下图所示: 方法一:float浮动布局 原理是:定义三个区块,需要注意的是中间的区块放在右边区块的下面,统一设置高度为 ...

  7. (10)Python函数

  8. 课外知识----easy BCD

    可以用来作系统之间的切换 使用方法略

  9. 【js】 ==与===区别

    1.对于string,number等基础类型,==和===是有区别的 1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等 2)同类型比较,直接进 ...

  10. 理解 JavaScript 中的 for…of 循环

    什么是 for…of 循环 for...of 语句创建一个循环来迭代可迭代的对象.在 ES6 中引入的 for...of 循环,以替代 for...in 和 forEach() ,并支持新的迭代协议. ...