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 ...
随机推荐
- 51Testing专访史亮:测试人员在国外
不久前,我接受了51Testing的访问,讨论了软件测试的一些问题.以下是全文. 1.史亮老师,作为我们51Testing的老朋友,能和我们说说您最近在忙些什么吗? 自2011年起,我加入Micros ...
- SpringMVC处理请求
HttpServletBean HttpServletBean主要参与了创建工作,并没有涉及请求的处理. FrameworkServlet FrameworkServlet的service方法里添加了 ...
- Scrum敏捷开发沉思录
计算机科学的诞生,是世人为了用数字手段解决实际生活中的问题.随着时代的发展,技术的进步,人们对于现实世界中的问题理解越来越深刻,描述也越来越抽象,于是对计算机软件的需求也越来越高,越来越复杂,变化也越 ...
- 洗礼灵魂,修炼python(48)--巩固篇—模块
模块 其实前面都说过的,不过还是系统的再说一次,相信学到这,大部分都被搞忘了吧,所以再提一下,也为后面的博文做铺垫 1.什么是模块 在程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越 ...
- 洗礼灵魂,修炼python(23)--自定义函数(4)—闭包进阶问题—>报错UnboundLocalError: local variable 'x' referenced before assignment
闭包(lexical closure) 什么是闭包前面已经说过了,但是由于遗留问题,所以单独作为一个章节详解讲解下 不多说,看例子: def funx(x): def funy(y): return ...
- 校园网下对VMware网络的配置
1.参考:https://jingyan.baidu.com/article/8275fc8675c22646a03cf6b8.html 2.因为校园网的每一次连接都是自动获得IP地址的,所以虚拟机要 ...
- Oracle 单引号 双引号 转义符 分隔符
概述 单引号用来标记字符串 双引号用来标记识别对象名 以下使用会比较绕: 字符串中出现单引号.双引号: 表或字段等对象的别名(alias)中出单引号.双引号: 单引号.双引号与空格一起使用: 双引号 ...
- 探索哪个进程使磁盘I/O升高
如果生产环境中磁盘使用率突然升高,却不知道因为哪个应用程序导致的,这个时候我们可以使用pidstat命令来查看,比如 Linux .el7.x86_64 (ip.ec2.internal) _x86_ ...
- shell基本语法记录
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个 ...
- asp.net core 如何集成kindeditor并实现图片上传功能
准备工作 1.visual studio 2015 update3开发环境 2.net core 1.0.1 及以上版本 目录 新建asp.net core web项目 下载kindeditor ...