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 ...
随机推荐
- OneAPM大讲堂 | 基于图像质量分析的摄像头监控系统的实现
今天咱们要介绍的技术很简单,请看场景: 你在家里安装了几个摄像头想监视你家喵星人的一举一动,然而,就在喵星人准备对你的新包发动攻击的时候,图像突然模糊了.毕竟图像模糊了以后你就没法截图回家和喵当面对质 ...
- Windows服务器搭建Redis
1.下载安装Redis https://github.com/MicrosoftArchive/redis/releases 可以下载安装版(.msi)也可以下载解压版(.zip). 我直接下载的安装 ...
- 获取目录文件.bat
@echo off & setlocal EnableDelayedExpansion for /f "delims=" %%i in ('"dir /a/s/b ...
- ES 使用小结
ES 是 Elastic Search 的缩写,可以理解为一个支持分布式部署的软件. 部署了以后可以当数据库用,虽然官方不建议这样做,但我们是这样干的. 它解决了很多场景下的查询需求,发版速度飞快,用 ...
- Linux 小知识翻译 - 「内核(kernel)」
上次介绍了Linus Torvalds, 这次介绍他开发的「内核」. 经常听人提到「Linux kernel」,但如果被问到「kernel究竟是什么?」的话,会出乎意料的觉得难以回答. 那么,kern ...
- CSS命名方式=》BEM
时间:2016-11-04 20:04:53 原文地址:https://github.com/zhongxia245/blog/issues/48 一.背景 挺早就听说过BEM了,也大概的知道怎么用, ...
- 17秋 软件工程 第二次作业 sudoku
2017年秋季 软件工程 作业2:个人项目 sudoku Github Project Github Project at Wasdns/sudoku. PSP Table PSP2.1 Person ...
- for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); },0); };答案:4 4 4。
看面试题时,发现了一道较为经典的面试题,代码如下 for(var i=1;i<=3;i++){ setTimeout(function(){ console.log(i); },0); }; / ...
- 关于new
JS通过new关键字,可以调用相关的 构造方法 生成一个 对象 ,function ---> object
- c++のmap的遍历
一.定义如:map < int, CString > 或者 map < int, 结构体名>的元素遍历 map < int, CString > map; ...