def find_point(self, node):
        # Kod pisan po uzoru na http://www.dyn4j.org/2011/11/contact-points-using-clipping/

        object1 = node.items[1] # incident object
        object2 = node.items[0] # reference object
        normal = node.value1

        max_extreme_e1, point1_e1, point2_e1 = object1.getCoallisionEdge(-normal) # incident edge
        max_extreme_e2, point1_e2, point2_e2 = object2.getCoallisionEdge(normal) # reference edge
        #print(max_extreme_e1, point1_e1, point2_e1, object2.angle, normal)
        if isinstance(object1, Ball):
            return max_extreme_e1
        if isinstance(object2, Ball):
            d1 = object2.getCenter() - point1_e1
            d2 = object2.getCenter() - point2_e1
            d1 = np.linalg.norm(d1)
            d2 = np.linalg.norm(d2)
            if d1 < d2:
                return point1_e1
            return point2_e1

        e2 = point2_e2 - point1_e2

        e2 = e2 / np.linalg.norm(e2)

        o1 = e2.dot(point1_e2)

        clips = self.clip(point1_e1, point2_e1, e2, o1)
        if len(clips) < 2:
            return

        o2 = e2.dot(point2_e2)

        clips = self.clip(clips[0], clips[1], -e2, -o2)
        if len(clips) < 2:
            return

        max_value = normal.dot(max_extreme_e2)

        if normal.dot(clips[0]) - max_value > 0:
            clips.pop(0)
            if normal.dot(clips[0]) - max_value > 0:
                clips.pop(0)
        elif normal.dot(clips[1]) - max_value > 0:
            clips.pop(1)
        for c in clips:
            Debug.draw_point(c, (50, 50, 50))
        dot = None
        if len(clips) == 2:
            clips[0] = (clips[0] + clips[1])/2
            clips.pop()
        if len(clips) == 1:
            dot = clips[0]
        return dot
    def collide(self):
        # Kod pisan po uzoru na https://github.com/erincatto/box2d-lite/

        coallisions = self.check_coallision()
        if not coallisions:
            return

        self.cashed_data_new = {}
        for i in range(len(coallisions)):
            node = coallisions[i]

            referenced_object = node.items[0]
            incident_object = node.items[1]

            referenced_object.updateSpeeds()
            incident_object.updateSpeeds()

            n = incident_object.getCenter() - referenced_object.getCenter()
            if n.dot(node.value1) < 0:
                node.value1 *= -1
            normal = node.value1
            point_of_coallision = self.find_point(node)
            if point_of_coallision is None:
                coallisions[i] = None
                continue
            # DRAW COLLISION POINTS
            else:
                Debug.draw_point(point_of_coallision)
            r1 = point_of_coallision - referenced_object.getCenter()
            r2 = point_of_coallision - incident_object.getCenter()


            rn1 = r1.dot(normal)
            rn2 = r2.dot(normal)
            k_normal = 1/referenced_object.mass + 1/incident_object.mass

            k_normal += referenced_object.inverse_inertia * (r1.dot(r1) - rn1*rn1) + incident_object.inverse_inertia * (r2.dot(r2) - rn2*rn2)

            mass_normal = 1/k_normal

            bias = -Fluid.BETA * (1/Shape.DELTA_TIME)*min(0, node.value2 + Fluid.SLOP)


            tangent = cross(normal, 1)
            rt1 = r1.dot(tangent)
            rt2 = r2.dot(tangent)
            k_tangent = 1/referenced_object.mass + 1/incident_object.mass
            k_tangent += referenced_object.inverse_inertia * (r1.dot(r1) - rt1*rt1) + incident_object.inverse_inertia * (r2.dot(r2) - rt2*rt2)
            mass_tangent = 1/k_tangent
            node.mass_tangent = mass_tangent

            node.r1 = r1
            node.r2 = r2
            node.mass_normal = mass_normal
            node.bias = bias
            friction = np.sqrt(referenced_object.friction * incident_object.friction)
            node.friction = friction

            key = (str(id(referenced_object)) + str(id(incident_object)))
            if key in self.cashed_data_old:
                node.normal_impulse = self.cashed_data_old[key].normal_impulse
                node.tangent_impulse = self.cashed_data_old[key].tangent_impulse
                self.cashed_data_new[key] = node

                old_impuse = node.normal_impulse * normal + node.tangent_impulse*tangent
                referenced_object.add_impulse(-old_impuse, node.r1)
                incident_object.add_impulse(old_impuse, node.r2)
                node.key = key
            else:
                node.normal_impulse = 0
                node.tangent_impulse = 0
                node.key = key
                self.cashed_data_new[key] = node

        for i in range(10):
            for node in coallisions:
                if node is None:
                    continue
                referenced_object = node.items[0]
                incident_object = node.items[1]
                normal = node.value1
                velocity = incident_object.vector + cross(incident_object.angularspeed, node.r2) - referenced_object.vector - cross(referenced_object.angularspeed, node.r1)

                velocity_value = velocity.dot(normal)

                normal_impulse = node.mass_normal*(-velocity_value + node.bias)

                temp = node.normal_impulse
                node.normal_impulse = max(temp + normal_impulse, 0)
                normal_impulse = node.normal_impulse - temp


                impulse = normal_impulse*normal
                referenced_object.add_impulse(-impulse, node.r1)
                incident_object.add_impulse(impulse, node.r2)

                velocity = incident_object.vector + cross(incident_object.angularspeed, node.r2) - cross(
                    referenced_object.angularspeed, node.r1) - referenced_object.vector
                tangent = cross(normal, 1)
                tangent_velocity_value = velocity.dot(tangent)
                tangent_impulse_value = node.mass_tangent*(-tangent_velocity_value)

                friction = node.friction

                max_tangent_value = friction * node.normal_impulse
                old_tangent_impulse = node.tangent_impulse
                node.tangent_impulse = clamp(old_tangent_impulse + tangent_impulse_value, -max_tangent_value, max_tangent_value)
                tangent_impulse_value = node.tangent_impulse-old_tangent_impulse

                end_tangent_impulse = tangent_impulse_value * tangent


                referenced_object.add_impulse(-end_tangent_impulse, node.r1)
                incident_object.add_impulse(end_tangent_impulse, node.r2)

        self.cashed_data_old = self.cashed_data_new