Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android/Java how to check if a Rectangle and a line segment intersect without line2d [closed]

in my game for Android I need to check for intersection between a rectangle and a line segment. I cannot use line2d as android does not support that. I have looked at similar questions dealing with lines and tried to modify them and failed. I also realize this Q/A which is basically what I want, however I have failed. For an example here is my code for a Line class that includes my attempt at intersection. The results have been some non-intersections returning true and some intersections returning false. EDIT: Oli Charlesworth helped me and here is working code for any googlers out there.

   package com.example.HelloAndroid;

import android.graphics.Rect;

public class Segment {
    int x1;
    int y1;
    int x2;
    int y2;
    double m;
    double b;
    boolean ishoriz;
    boolean isvert;

    public Segment(int x1s, int y1s, int x2s, int y2s) {
        if (x1s > x2s) {
            this.x1 = x2s;
            this.x2 = x1s;
        } else {
            this.x1 = x1s;
            this.x2 = x2s;
        }
        if (y1s > y2s) {
            this.y1 = y2s;
            this.y2 = y1s;
        } else {
            this.y1 = y1s;
            this.y2 = y2s;
        }
        int ydif = y2s - y1s;
        int xdif = x2s - x1s;
        if (ydif == 0) {
            this.ishoriz = true;
            this.m = 0;
            this.b = x1s;
        } else if (xdif == 0) {
            this.isvert = true;
        } else {
            this.m = (double) ydif / xdif;
            double r = (double) ydif / xdif;
            this.b = y1s - (r * x1s);
            this.isvert = false;
            this.ishoriz = false;
        }
    }

    public final boolean intersected(Segment s, Segment s2) {
        if (s.ishoriz && s2.ishoriz) {
            //parallel
            return false;
        }

        if (s.isvert && s2.isvert) {
            //parallel

            return false;
        }

        if (s.isvert) {
            //x is constant see if the x is on the other line
            int x = s.x1;
            //add 2 for round-off error
            if (s2.x1 <= x + 2 && s2.x2 + 2 >= x) {
                //solve and check if y is on both segments
                int y = (int) ((s.m * x) + s.b);
                if(s.y1<=y+2&&s.y2+2>=y)
                {
                    if(s2.y1<=y+2&&s2.y2+2>=y)
                    {
                return true;}
            }
            }
            return false;
        }

        if (s2.isvert) {
            //x is constant see if the x is on the other line
            int x = s2.x1;
            //add 2 for round-off error
            if (s.x1 <= x + 2 && s.x2 + 2 >= x) {
                //solve and check if y is on both segments
                int y = (int) ((s.m * x) + s.b);
                if(s.y1<=y+2&&s.y2+2>=y)
                {
                    if(s2.y1<=y+2&&s2.y2+2>=y)
                    {
                return true;}
            }
            }
            return false;
        }

        if (s.ishoriz) {
            //y is constant see if the y is on the other line
            int y = s.y1;
            //add 2 for round-off error
            if (s2.y1 <= y + 2 && s2.y2 + 2 >= y) {
                //solve and check if x is on both segments
                int x=(int) ((y-s.b)/s.m);
                if(s.x1<=x+2&&s.x2+2>=x)
                {
                    if(s2.x1<=x+2&&s2.x2+2>=x)
                return true;}
            return false;
        }}

        if (s2.ishoriz) {
            //y is constant see if the y is on the other line
            int y = s2.y1;
            //add 2 for round-off error
            if (s.y1 <= y + 2 && s.y2 + 2 >= y) {
                //solve and check if x is on both segments
                int x=(int) ((y-s.b)/s.m);
                if(s.x1<=x+2&&s.x2+2>=x)
                {
                    if(s2.x1<=x+2&&s2.x2+2>=x)
                return true;}
            }
            return false;
        }

        if (s.m == s2.m) {
            //parallel
            return false;
        }

        // use substitution
        // (s.m-s2.m)x=s2.b-s.b
        int x = (int) (s.m - s2.m);
        x = (int) ((s2.b - s.b) / x);
        // find y
        int y = (int) ((x * s.m) + s.b);
        //check if the values are in between for both lines
        //add 2 for round-off error
        if (s.y1 <= y + 2) {
            if (s.y2 + 2 >= y) {
                if (s2.y1 <= y + 2) {
                    if (s2.y2 + 2 >= y) {
                        if (s.x1 <= x + 2) {
                            if (s.x2 + 2 >= x) {
                                if (s2.x1 <= x + 2) {
                                    if (s2.x2 + 2 >= x) {
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public final boolean intersects2(Segment s, Rect r) {
        //created lines of the rect
        Segment top = new Segment(r.left, r.top, r.right, r.top);
        Segment left = new Segment(r.left, r.top, r.left, r.bottom);
        Segment bottom = new Segment(r.left, r.bottom, r.right, r.bottom);
        Segment right = new Segment(r.right, r.top, r.right, r.bottom);
        boolean topp = s.intersected(s, top);
        if (topp) {
            return true;
        }
        boolean leftp = s.intersected(s, left);
        if (leftp) {
            return true;
        }
        boolean bottomp = s.intersected(s, bottom);
        if (bottomp) {
            return true;
        }
        boolean rightp = s.intersected(s, right);
        if (rightp) {
            return true;
        } else {
            return false;
        }
    }

}

like image 290
jersam515 Avatar asked Nov 21 '25 12:11

jersam515


1 Answers

It's possible that you're not initialising all your member variables correctly. In general, you should aim to make as many member variables final as possible, for (at least) two reasons:

  • the compiler will enforce that they must be initialised in the constructor.
  • the compiler will prevent you from overwriting them accidentally in a normal member function.

In other words, you should always aim to get the compiler to spot your bugs for you!

like image 195
Oliver Charlesworth Avatar answered Nov 24 '25 03:11

Oliver Charlesworth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!