首页 > 代码库 > libgdx学习记录27——线段与线段相交检测
libgdx学习记录27——线段与线段相交检测
给定p1, p2, p3, p4四个点,p1,p2为一条线段,p3,p4为一条线段,检测其是否有交点。
可分为三种情况:
1. L2与x轴平行
2. L2与y轴平行
3. L2与坐标轴不平行。
(L1与坐标轴平行,类似处理)
基本思路,求出交点坐标,并检测其是否在两个线段内即可。
检测代码:
1 public static float min(float x, float y) { return x<y? x: y; } 2 public static float max(float x, float y) { return x>y? x: y; } 3 4 public static boolean isSegmentOverlap(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4){ 5 if(p3.x == p4.x){ 6 float x = p3.x; 7 float y = p1.y + (p3.x-p1.x)*(p2.y-p1.y)/(p2.x-p1.x); 8 //System.out.println(y); 9 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) && 10 x>=min(p3.x, p4.x) && x<=max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){11 return true;12 }13 }14 else if(p3.y == p4.y){15 float x = p1.x + (p3.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y);16 float y = p3.y; 17 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) && 18 x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>=min(p3.y, p4.y) && y<=max(p3.y, p4.y) ){19 return true;20 }21 }22 else if(p1.x==p2.x || p1.y==p2.y){23 return isSegmentOverlap(p3, p4, p1, p2);24 }25 else{26 float k1 = (p2.y-p1.y)/(p2.x-p1.x);27 float k2 = (p4.y-p3.y)/(p4.x-p3.x);28 float x = (k2*p3.x-k1*p1.x+p1.y-p3.y)/(k2-k1);29 float y = k1*(x-p1.x) + p1.y; 30 //System.out.println( k1 + "," + k2 + "," + x + "," + y ); 31 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) && 32 x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){33 return true;34 } 35 }36 37 return false;38 }
实例代码:
1 package com.fxb.Gam003; 2 3 import com.badlogic.gdx.ApplicationAdapter; 4 import com.badlogic.gdx.Gdx; 5 import com.badlogic.gdx.InputAdapter; 6 import com.badlogic.gdx.graphics.Color; 7 import com.badlogic.gdx.graphics.GL10; 8 import com.badlogic.gdx.graphics.glutils.ShapeRenderer; 9 import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; 10 import com.badlogic.gdx.math.Rectangle; 11 import com.badlogic.gdx.math.Vector2; 12 import com.badlogic.gdx.scenes.scene2d.InputListener; 13 14 15 public class Lib054_SegmentOverlap extends ApplicationAdapter{ 16 17 ShapeRenderer rend; 18 19 Vector2 p1 = new Vector2(300, 100); 20 Vector2 p2 = new Vector2(500, 200); 21 Vector2 p3 = new Vector2(300, 200); 22 Vector2 p4 = new Vector2(400, 300); 23 24 Rectangle rect = new Rectangle( 100, 100, 200, 200 ); 25 26 @Override 27 public void create() { 28 // TODO Auto-generated method stub 29 super.create(); 30 31 rend = new ShapeRenderer(); 32 Gdx.input.setInputProcessor(adapter); 33 } 34 35 36 public static float min(float x, float y) { return x<y? x: y; } 37 public static float max(float x, float y) { return x>y? x: y; } 38 39 public static boolean isSegmentOverlap(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4){ 40 if(p3.x == p4.x){ 41 float x = p3.x; 42 float y = p1.y + (p3.x-p1.x)*(p2.y-p1.y)/(p2.x-p1.x); 43 //System.out.println(y); 44 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) && 45 x>=min(p3.x, p4.x) && x<=max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){ 46 return true; 47 } 48 } 49 else if(p3.y == p4.y){ 50 float x = p1.x + (p3.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y); 51 float y = p3.y; 52 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) && 53 x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>=min(p3.y, p4.y) && y<=max(p3.y, p4.y) ){ 54 return true; 55 } 56 } 57 else if(p1.x==p2.x || p1.y==p2.y){ 58 return isSegmentOverlap(p3, p4, p1, p2); 59 } 60 else{ 61 float k1 = (p2.y-p1.y)/(p2.x-p1.x); 62 float k2 = (p4.y-p3.y)/(p4.x-p3.x); 63 float x = (k2*p3.x-k1*p1.x+p1.y-p3.y)/(k2-k1); 64 float y = k1*(x-p1.x) + p1.y; 65 //System.out.println( k1 + "," + k2 + "," + x + "," + y ); 66 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) && 67 x>min(p3.x, p4.x) && x<max(p3.x, p4.x) && y>min(p3.y, p4.y) && y<max(p3.y, p4.y) ){ 68 return true; 69 } 70 } 71 72 return false; 73 } 74 75 76 public static boolean isSegRectOverlap(Vector2 p1, Vector2 p2, Rectangle rect){ 77 float x = rect.x, y = rect.y, w = rect.width, h = rect.height; 78 Vector2 rp1 = new Vector2(x, y); 79 Vector2 rp2 = new Vector2(x+w, y); 80 Vector2 rp3 = new Vector2(x+w, y+h); 81 Vector2 rp4 = new Vector2(x, y+h); 82 //return isSegmentOverlap(p1, p2, rp1, rp2) || isSegmentOverlap(p1, p2, rp2, rp3) || 83 // isSegmentOverlap(p1, p2, rp3, rp4) || isSegmentOverlap(p1, p2, rp4, rp1); 84 85 if( rect.contains(p1) || rect.contains(p2) ){ 86 return true; 87 } 88 89 return isSegmentOverlap(p1, p2, rp1, rp2) || isSegmentOverlap(p1, p2, rp2, rp3) || 90 isSegmentOverlap(p1, p2, rp3, rp4) || isSegmentOverlap(p1, p2, rp4, rp1); 91 } 92 93 94 95 @Override 96 public void render() { 97 // TODO Auto-generated method stub 98 super.render(); 99 Gdx.gl.glClearColor(1, 1, 1, 1);100 Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);101 102 rend.begin(ShapeType.Line);103 104 if(isSegmentOverlap(p1, p2, p3, p4)){ 105 rend.setColor(Color.RED);106 }107 else{108 rend.setColor(Color.BLUE);109 }110 rend.line(p1, p2);111 rend.line(p3, p4);112 113 114 // if(isSegRectOverlap(p1, p2, rect)){115 // rend.setColor(Color.RED);116 // }117 // else{118 // rend.setColor(Color.BLUE);119 // } 120 // rend.line(p1, p2);121 // rend.rect(rect.x, rect.y, rect.width, rect.height);122 123 124 rend.end();125 126 }127 128 @Override129 public void dispose() {130 // TODO Auto-generated method stub131 super.dispose();132 }133 134 135 InputAdapter adapter = new InputAdapter(){136 @Override137 public boolean touchDown(int screenX, int screenY, int pointer, int button) { 138 p1.set(screenX, 480-screenY); 139 return super.touchDown(screenX, screenY, pointer, button);140 }141 142 143 @Override144 public boolean touchDragged(int screenX, int screenY, int pointer) {145 p2.set(screenX, 480-screenY);146 return super.touchDragged(screenX, screenY, pointer);147 }148 149 150 @Override151 public boolean touchUp(int screenX, int screenY, int pointer, int button) {152 p2.set(screenX, 480-screenY);153 return super.touchUp(screenX, screenY, pointer, button);154 }155 156 157 158 };159 160 }
运行结果:
显示两种状态,相交红色,不相交蓝色。
libgdx学习记录27——线段与线段相交检测
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。