Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - deadsi

Pages: [1]
1
General / Collisions and vertex arrays
« on: July 23, 2021, 10:19:21 pm »
Hi guys, I don't know if I've missed something, am tired, or am going crazy,
possibly all three.
I'm a beginner, been messing around with a little collision sandbox, which I kinda expanded from the particle system example in the tutorials.
I'm slowly getting things working though there are weird behaviours everywhere.
I have a bunch of balls (2d) bouncing around, and am able to draw a line and add points to it which the circles will bounce off of, so I thought I can use basically the same functions to make em bounce off a square, which is a quad.
After a load of stupid omissions I got the balls bouncing off 3 sides like they should, the fourth (vertex 3-0) was bouncing wrong though.
The line function has a quirk that if its not drawn left to right it doesnt work properly and it got transferred to the quad, I tried all sorts of different things to fix it (doingfunction(vertex 3,vertex0) instead of function(vertex0, vertex3) til finally I found a way which really puzzles me.
For that one side only, I have to create a new vertexarray with two vertices, copy the positions from the two vertices from the quad into them, and feed those vertices into the formula.
The formula just takes coordinates so why would it matter if I copy those coordinates into some new vertices?
Even so it only works partially though, if the bottom vertex(3rd) is on the left and top(1st) on the right

The code is ridiculously messy please be gentle ;D I'm happy to read any suggestions as long as they're attached with an answer to my question,
thanks guys

if (obstSpawned == true) {
                if (drawing == false)
                    for (int j = 0; j < m_obstQ.size(); j++)
                        for (int k = 0; k < (m_obstQ[j].getVertexCount()); k++) {
                            sf::Vector2f o1;
                            sf::Vector2f o2;
//if going from last vertex to 0 do this weirdness with the new vertices
                            int id = k + 1;
                            if (id == m_obstQ[j].getVertexCount())
                                id = 0;
                            if (id == 0) {
                                sf::Vertex v0(m_obstQ[j][k].position);
                                sf::Vertex v1(m_obstQ[j][id].position);
                                sf::VertexArray va;
                                va.setPrimitiveType(sf::LineStrip);
                                va.append(v0);
                                va.append(v1);
                                o1 = (va[0].position);
                                o2 = (va[1].position);
                            }
//which vertex is on which side seems to matter too
                            else {
                                if (m_obstQ[j][k].position.x < m_obstQ[j][id].position.x)
                                {
                                    o1 = (m_obstQ[j][k].position);
                                    o2 = (m_obstQ[j][id].position);

                                }
                                else {
                                    o1 = (m_obstQ[j][id].position);
                                    o2 = (m_obstQ[j][k].position);
                                   

                                }
                            }
                           
                               
                         


                            sf::Vector2f Cp = closestPoint(o1, o2, bPos);

                            float x = Cp.x - bPos.x;
                            float y = Cp.y - bPos.y;
                            float Dis = sqrt((x * x) + (y * y));
                            if (Dis <= r) p.gravity = false;
                            else
                                if(gravity == true) p.gravity = true;
//the collisionsO stuff is just cuz I run a clock when a collision happens so it don't do it again next frame
                            if (collisionsO[j * pCount + i] == false) {
                                //point a
                                sf::Vector2f A = checklinescollide(bPos, p.bVec, o1, o2);
//little helper to see where the collision point is
                                cC.setRadius(20);
                                cC.setOrigin(20, 20);
                                cC.setFillColor(sf::Color(0, 70, 120, 255));
                                cC.setPosition(A);
                                if(A != sf::Vector2f(0,0))
                               
                                if (A.x > 0 || A.y > 0)
                                {
                                   


                                    //closest point

                                    sf::Vector2f cP = closestPoint(o1, o2, bPos);
//little helper to see closest point on line
                                   /* cp[0].position = sf::Vector2f(cP);
                                    cp[1].position = sf::Vector2f(cP.x + 5, cP.y);
                                    cp[2].position = sf::Vector2f(cP.x + 5, cP.y + 5);
                                    cp[3].position = sf::Vector2f(cP.x, cP.y + 5);*/

                                    if (p.colliding == false) {
                                        p.Circ = bPos;

                                        //point 1

                                        p.P1 = closestPoint(o1, o2, bPos);



                                        p.colliding = true;
                                    }

                                    float x = cP.x - bPos.x;
                                    float y = cP.y - bPos.y;
                                    float dis = sqrt((x * x) + (y * y));
                                    if (dis <= r) {
                                       

                                        if (gravity || !gravity  ) {
                                            sf::Vector2f P3 = bPos + (p.P1 - cP);

                                            sf::Vector2f vel = ((P3 - bPos) + (P3 - bPos)) + bPos;
                                            p.velocity = normalize(p.Circ - vel) * p.speed;


                                           
                                           
                                            collisionsO[j * pCount + i] = true;


                                            p.colliding = false;



                                        }

                                    }
                                   
                                }
                            }
                           


                        }
            }

sf::Vector2f checklinescollide(sf::Vector2f b, sf::Vector2f bV,
        sf::Vector2f l1, sf::Vector2f l2) {
        float A1 = bV.y - b.y;
        float B1 = b.x - bV.x;
        float C1 = A1 * b.x + B1 * b.y;
        float A2 = l2.y - l1.y;
        float B2 = l1.x - l2.x;
        float C2 = A2 * l1.x + B2 * l1.y;
        float det = A1 * B2 - A2 * B1;
        if (det != 0) {
            float x = (B2 * C1 - B1 * C2) / det;
            float y = (A1 * C2 - A2 * C1) / det;
            if (x >= fmin(b.x, bV.x) && x <= fmax(b.x, bV.x)
                && x >= fmin(l1.x, l2.x) && x <= fmax(l1.x, l2.x)
                && y >= fmin(b.y, bV.y) && y <= fmax(b.y, bV.y)
                && y >= fmin(l1.y, l2.y) && y <= fmax(l1.y, l2.y))
                return  sf::Vector2f(x, y);
        }
        else
            return sf::Vector2f(0, 0);
    }

sf::Vector2f closestPoint(sf::Vector2f l1,
        sf::Vector2f l2, sf::Vector2f c) {
        float A1 = l2.y - l1.y;
        float B1 = l1.x - l2.x;
        double C1 = (l2.y - l1.y) * l1.x + (l1.x - l2.x) * l1.y;
        double C2 = -B1 * c.x + A1 * c.y;
        double det = A1 * A1 - -B1 * B1;
        double cx = 0;
        double cy = 0;
        if (det != 0) {
            cx = (float)((A1 * C1 - B1 * C2) / det);
            cy = (float)((A1 * C2 - -B1 * C1) / det);
        }
        else {
            cx = c.x;
            cy = c.y;
        }
        sf::Vector2f cP(cx, cy);


        if (cP.x < l1.x || cP.x > l2.x)
            return sf::Vector2f(0, 0);
        else
        return cP;
    }




Pages: [1]