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

Author Topic: Collisions and vertex arrays  (Read 4138 times)

0 Members and 1 Guest are viewing this topic.

deadsi

  • Newbie
  • *
  • Posts: 1
    • View Profile
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;
    }



« Last Edit: July 23, 2021, 10:24:28 pm by deadsi »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Collisions and vertex arrays
« Reply #1 on: October 10, 2021, 06:20:40 pm »
Hope you have in the mean time already found some solutions. :)

As a general tip when approaching pretty much any (technical) problem, try very small steps, remove unnecessary things and be clear in what exactly you're trying to achieve.

From the description, I don't really know what you're trying to achieve.
And if I don't even really know what's going on, it's even harder to understand what these code snippets should represent exactly.

If you're still stuck on this, feel free to provide some more concise description of a) what you're trying to do and b) what is actually happening/not happening right now.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

 

anything