• 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     @Override
    129     public void dispose() {
    130         // TODO Auto-generated method stub
    131         super.dispose();
    132     }
    133     
    134     
    135     InputAdapter adapter = new InputAdapter(){
    136         @Override
    137         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         @Override
    144         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         @Override
    151         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 }

    运行结果:

     

    显示两种状态,相交红色,不相交蓝色。

  • 相关阅读:
    C语言II博客作业04
    C语言II博客作业03
    C语言II博客作业02
    C语言II博客作业01
    学期总结
    C语言I博客作业09
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
    C语言I博客作业05
  • 原文地址:https://www.cnblogs.com/MiniHouse/p/4044252.html
Copyright © 2020-2023  润新知