Module py3d.calculs

Module calculs, contient des fonctions permettant de calculer les intersections entre divers objets

Expand source code
"""Module calculs, contient des fonctions permettant de calculer les intersections entre divers objets

"""
import droites, plans, points, vecteurs
from utils import MIN_DELTA

def intersection(ObjetA, ObjetB):
        """Sert de fonction tampon pour renvoyer l'intersection entre A et B

        Voir les fonctions intersection_droite_droite(), intersection_plan_plan() et intersection_droite_plan()
        """

        if isinstance(ObjetA, droites.Droite):

                if isinstance(ObjetB, droites.Droite):

                        if droites.secantes(ObjetA, ObjetB):
                                return intersection_droite_droite(ObjetA, ObjetB)
                        else:
                                return None

                elif isinstance(ObjetB, plans.Plan):
                        if droites.secante_plan(ObjetA, ObjetB):
                                return intersection_droite_plan(ObjetA, ObjetB)
                        else:
                                return None

                else:
                        typeA = ObjetA.__class__.__name__
                        typeB = ObjetB.__class__.__name__
                        raise TypeError(f"Impossible de déterminer l'intersection entre [{typeA}] et [{typeB}]")

        elif isinstance(ObjetA, plans.Plan):

                if isinstance(ObjetB, droites.Droite):

                        if droites.secante_plan(ObjetB, ObjetA):
                                return intersection_droite_plan(ObjetB, ObjetA)
                        else:
                                return None

                elif isinstance(ObjetB, plans.Plan):
                        if plans.secants(ObjetA, ObjetB):
                                return intersection_plan_plan(ObjetA, ObjetB)
                        else:
                                return None                     

        else:
                return None

def intersection_droite_droite(droiteA, droiteB):
        """Renvoie le point d'intersection entre les droites si elles sont sécantes
        None sinon
        
        Args:
            droiteA (Droite): Droite A
            droiteB (Droite): Droite B
        
        Returns:
            Point: Point d'intersection entre A et B

        Utilisée via la fonction intersection()
        """
        v = droiteA.vecteur
        v2 = droiteB.vecteur

        p = droiteA.point
        p2 = droiteB.point

        v3 = vecteurs.Vecteur(p, p2).produit_vectoriel(v2)
        v4 = v.produit_vectoriel(v2)

        scalaire = v4.scalaire(v4)
        if scalaire == 0:
                return None

        alpha = v3.scalaire(v4) / scalaire

        point = points.Point(droiteA.point.x + alpha * droiteA.vecteur.x,
                                                droiteA.point.y + alpha * droiteA.vecteur.y,
                                                droiteA.point.z + alpha * droiteA.vecteur.z)

        return point

def intersection_droite_plan(droite, plan):
        """Renvoie le point d'intersection entre la droite et le plan si ils sont sécants
        None sinon
        
        Args:
            droite (Droite): Droite
            plan (Plan): Plan
        
        Returns:
            Point: Point d'intersection entre la droite et le plan 

        Utilisée via la fonction intersection()
        """
        p = droite.point
        v = droite.vecteur

        dot1 = plan.vecteur_n.scalaire(vecteurs.Vecteur(p.x, p.y, p.z))
        dot2 = plan.vecteur_n.scalaire(v)

        if dot2 == 0:
                return None
        
        d = plan.cartesienne()[1][-1]
        t = -(dot1 - d) / dot2

        return points.Point(p.x + (v.x*t), p.y + (v.y*t), p.z + (v.z*t))

def resoudre_cramer(equa_a, equa_b):
        """Résout un systeme dans une matrice de 2x4
        Renvoie alpha et beta, qui seront les coordonées non nulles d'un point
        de la droite d'intersection entre deux plans
        
        Args:
            equa_a (tuple): Equation du plan A
            equa_a (tuple): Equation du plan B
        
        Returns:
            alpha, beta: coordonées non nulles d'un point de la droite d'intersection entre deux plans

        Utilisée par la fonction intersection_plan_plan()
        """
        a, b, c, d = equa_a
        a2, b2, c2, d2 = equa_b

        d, d2 = -d, -d2

        det = b * c2 -  c * b2
        alpha = (d * c2 - c * d2) / det
        beta = (b * d2 - d * b2) / det
        return alpha, beta

def intersection_plan_plan(planA, planB):
        """Renvoie la droite d'intersection entre les plans si ils sont sécantes
        None sinon
        
        Args:
            planA (Plan): Plan A
            planA (Plan): Plan B
        
        Returns:
            Droite: Droite d'intersection entre A et B

        Utilisée via la fonction intersection()
        """
        equa_a = planA.cartesienne()[1]
        equa_b = planB.cartesienne()[1]

        vec_a = planA.vecteur_n
        vec_b = planB.vecteur_n

        vec_d = vec_a.produit_vectoriel(vec_b)

        if abs(vec_d.x) > MIN_DELTA:
                #X non nul -> on prend x = 0
                x = 0
                y, z = resoudre_cramer(equa_a, equa_b)

        elif abs(vec_d.y) > MIN_DELTA:
                #Y non nul -> on prend y = 0
                y = 0
                x, z = resoudre_cramer(equa_a, equa_b)

        else:
                #Z non nul -> on prend z = 0
                z = 0
                x, y = resoudre_cramer(equa_a, equa_b)

        point = points.Point(x, y, z)

        d = droites.Droite(point, vec_d)

        return d

__all__ = ("intersection", "intersection_plan_plan", "intersection_droite_plan", "intersection_droite_droite")

Functions

def intersection(ObjetA, ObjetB)

Sert de fonction tampon pour renvoyer l'intersection entre A et B

Voir les fonctions intersection_droite_droite(), intersection_plan_plan() et intersection_droite_plan()

Expand source code
def intersection(ObjetA, ObjetB):
        """Sert de fonction tampon pour renvoyer l'intersection entre A et B

        Voir les fonctions intersection_droite_droite(), intersection_plan_plan() et intersection_droite_plan()
        """

        if isinstance(ObjetA, droites.Droite):

                if isinstance(ObjetB, droites.Droite):

                        if droites.secantes(ObjetA, ObjetB):
                                return intersection_droite_droite(ObjetA, ObjetB)
                        else:
                                return None

                elif isinstance(ObjetB, plans.Plan):
                        if droites.secante_plan(ObjetA, ObjetB):
                                return intersection_droite_plan(ObjetA, ObjetB)
                        else:
                                return None

                else:
                        typeA = ObjetA.__class__.__name__
                        typeB = ObjetB.__class__.__name__
                        raise TypeError(f"Impossible de déterminer l'intersection entre [{typeA}] et [{typeB}]")

        elif isinstance(ObjetA, plans.Plan):

                if isinstance(ObjetB, droites.Droite):

                        if droites.secante_plan(ObjetB, ObjetA):
                                return intersection_droite_plan(ObjetB, ObjetA)
                        else:
                                return None

                elif isinstance(ObjetB, plans.Plan):
                        if plans.secants(ObjetA, ObjetB):
                                return intersection_plan_plan(ObjetA, ObjetB)
                        else:
                                return None                     

        else:
                return None
def intersection_droite_droite(droiteA, droiteB)

Renvoie le point d'intersection entre les droites si elles sont sécantes None sinon

Args

droiteA : Droite
Droite A
droiteB : Droite
Droite B

Returns

Point
Point d'intersection entre A et B

Utilisée via la fonction intersection()

Expand source code
def intersection_droite_droite(droiteA, droiteB):
        """Renvoie le point d'intersection entre les droites si elles sont sécantes
        None sinon
        
        Args:
            droiteA (Droite): Droite A
            droiteB (Droite): Droite B
        
        Returns:
            Point: Point d'intersection entre A et B

        Utilisée via la fonction intersection()
        """
        v = droiteA.vecteur
        v2 = droiteB.vecteur

        p = droiteA.point
        p2 = droiteB.point

        v3 = vecteurs.Vecteur(p, p2).produit_vectoriel(v2)
        v4 = v.produit_vectoriel(v2)

        scalaire = v4.scalaire(v4)
        if scalaire == 0:
                return None

        alpha = v3.scalaire(v4) / scalaire

        point = points.Point(droiteA.point.x + alpha * droiteA.vecteur.x,
                                                droiteA.point.y + alpha * droiteA.vecteur.y,
                                                droiteA.point.z + alpha * droiteA.vecteur.z)

        return point
def intersection_droite_plan(droite, plan)

Renvoie le point d'intersection entre la droite et le plan si ils sont sécants None sinon

Args

droite : Droite
Droite
plan : Plan
Plan

Returns

Point
Point d'intersection entre la droite et le plan

Utilisée via la fonction intersection()

Expand source code
def intersection_droite_plan(droite, plan):
        """Renvoie le point d'intersection entre la droite et le plan si ils sont sécants
        None sinon
        
        Args:
            droite (Droite): Droite
            plan (Plan): Plan
        
        Returns:
            Point: Point d'intersection entre la droite et le plan 

        Utilisée via la fonction intersection()
        """
        p = droite.point
        v = droite.vecteur

        dot1 = plan.vecteur_n.scalaire(vecteurs.Vecteur(p.x, p.y, p.z))
        dot2 = plan.vecteur_n.scalaire(v)

        if dot2 == 0:
                return None
        
        d = plan.cartesienne()[1][-1]
        t = -(dot1 - d) / dot2

        return points.Point(p.x + (v.x*t), p.y + (v.y*t), p.z + (v.z*t))
def intersection_plan_plan(planA, planB)

Renvoie la droite d'intersection entre les plans si ils sont sécantes None sinon

Args

planA : Plan
Plan A
planA : Plan
Plan B

Returns

Droite
Droite d'intersection entre A et B

Utilisée via la fonction intersection()

Expand source code
def intersection_plan_plan(planA, planB):
        """Renvoie la droite d'intersection entre les plans si ils sont sécantes
        None sinon
        
        Args:
            planA (Plan): Plan A
            planA (Plan): Plan B
        
        Returns:
            Droite: Droite d'intersection entre A et B

        Utilisée via la fonction intersection()
        """
        equa_a = planA.cartesienne()[1]
        equa_b = planB.cartesienne()[1]

        vec_a = planA.vecteur_n
        vec_b = planB.vecteur_n

        vec_d = vec_a.produit_vectoriel(vec_b)

        if abs(vec_d.x) > MIN_DELTA:
                #X non nul -> on prend x = 0
                x = 0
                y, z = resoudre_cramer(equa_a, equa_b)

        elif abs(vec_d.y) > MIN_DELTA:
                #Y non nul -> on prend y = 0
                y = 0
                x, z = resoudre_cramer(equa_a, equa_b)

        else:
                #Z non nul -> on prend z = 0
                z = 0
                x, y = resoudre_cramer(equa_a, equa_b)

        point = points.Point(x, y, z)

        d = droites.Droite(point, vec_d)

        return d