libgdx学习记录27——线段与线段相交检测
给定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——线段与线段相交检测的更多相关文章
- libgdx学习记录2——文字显示BitmapFont
libgdx对中文支持不是太好,主要通过Hireo和ttf字库两种方式实现.本文简单介绍最基本的bitmapfont的用法. 代码如下: package com.fxb.newtest; import ...
- libgdx学习记录3——动画Animation
libgdx动画采用Animation实现,即通过帧动画实现. 代码如下: package com.fxb.newtest; import com.badlogic.gdx.ApplicationAd ...
- libgdx学习记录26——Polygon多边形碰撞检测
libgdx中Math封装了Polygon这个类,它是由多个定点进行描述实现的,在进行物体间的碰撞时,物体轮廓有时候是不规则的,这时候可以用一个多边形勾勒出其大概的轮廓,对其进行模拟. Polygon ...
- libgdx学习记录25——Rectangle与Circle是否重叠
Rect与Circle重叠有三种情况: 1. Rect至少有一个角在Circle里面 2. Circle与Rect的左边或右边相交,或者Circle在Rect内 3. Circle与Rect的顶边或底 ...
- libgdx学习记录22——3d物体创建
libgdx是一个强大的游戏框架,不仅支持2d部分,同时还支持3d部分. libgdx的3d部分投影主要通过PerspectiveCamera实现. 物体的显示过程: 1. 创建远景相机,角度一般设为 ...
- libgdx学习记录20——多线程MultiThread资源处理
在libgdx中,一般的逻辑流程都在rende()函数中执行,这个函数是由opengl的渲染线程调用的,一般的图形显示和逻辑处理都在这个线程中. 一般情形下,在这个线程中处理就行了.但是当某些逻辑处理 ...
- libgdx学习记录19——图片动态打包PixmapPacker
libgdx中,opengl 1.x要求图片长宽必须为2的整次幂,一般有如下解决方法 1. 将opengl 1.x改为opengl 2.0.(libgdx 1.0版本后不支持1.x,当然不存在这个问题 ...
- libgdx学习记录18——Box2d物理引擎
libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创 ...
- libgdx学习记录17——照相机Camera
照相机在libgdx中的地位举足轻重,贯穿于整个游戏开发过程的始终.一般我们都通过Stage封装而间接使用Camera,同时我们也可以单独使用Camera以完成背景的移动.元素的放大.旋转等操作. C ...
随机推荐
- char/varchar/nvarchar的区别
原文:https://blog.csdn.net/w516162189/article/details/78914035 我们在设计数据库的时候,需要根据需求场景选择合适的字段类型,对数据的执行效率有 ...
- REPLACE函数的使用方法
Replace函数的含义~ 用新字符串替换旧字符串,而且替换的位置和数量都是指定的. replace函数的语法格式 =Replace(old_text,start_num,num_chars,new_ ...
- Windows结构化异常处理浅析
近期一直被一个问题所困扰,就是写出来的程序老是出现无故崩溃,有的地方自己知道可能有问题,但是有的地方又根本没办法知道有什么问题.更苦逼的事情是,我们的程序是需要7x24服务客户,虽然不需要实时精准零差 ...
- fedora添加ntfs文件系统支持
ntfs支持(安装后不能打开,重启) 如果没有换源先看一下换源. 查找库中是否有ntfs-3g. [root@bogon zhujikuan]# yum search ntfs 上次元数据过期检查:0 ...
- 关于UIPageViewController那些事
一.前言 这些天有新生问及UIPageViewController这个视图控制器,自己原来没有用过,所以就看了一下相关的知识,就写了下来,分享一下经验. 主要的关于这个控制器的内容就从例子中去解说了. ...
- 这不是我想要的ABAP开发者
原文在此: These Aren’t the Developers You’re Looking for 在吃饼干的过程中偶然看到这篇文章,立刻被UC化的标题吸引到了. 全文读完,感觉作者还是有点刻薄 ...
- Appium1.9.1 部署及结果检验
1.官网下载最新的 appium 2.点击 Download Appium 3.选择适用于自己操作系统的版本,我的是 windows版本,就选择如下红圈起的 4.点击安装,一直点 下一步 直到提示安装 ...
- BugBugBugBugBugBugBugBugBugBugBugBugBugBugBug
单元测试
- Python3.6安装及引入Requests库
本博客可能没有那么规范,环境之类的配置.只是让你直接开始编程写python. 至于各种配置网络上有多种方法. 本文仅代表我的观点的一种方法. 电脑环境:win10 64位 第一步:下载python. ...
- File类_常见的方法(获取目录中指定规则的内容)
首先定义过滤器 import java.io.File; import java.io.FilenameFilter; public class FileByJava implements Filen ...