zoukankan      html  css  js  c++  java
  • 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 }

    运行结果:

     

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

  • 相关阅读:
    475. Heaters
    69. Sqrt(x)
    83. Remove Duplicates from Sorted List Java solutions
    206. Reverse Linked List java solutions
    100. Same Tree Java Solutions
    1. Two Sum Java Solutions
    9. Palindrome Number Java Solutions
    112. Path Sum Java Solutin
    190. Reverse Bits Java Solutin
    202. Happy Number Java Solutin
  • 原文地址:https://www.cnblogs.com/MiniHouse/p/4044252.html
Copyright © 2011-2022 走看看