# -*- coding: utf-8 -*-
# python version 3.4 
 
from reperes import * 
from euclidiens import * 
 
 
class Hyperplan(): 
    """Hyperplan défini par une équation cartésienne dans un espace euclidien""" 
 
    def __init__(self, R, E): 
        """constructeur prenant en argument un repère et une équation sous forme de liste de coefficients""" 
        self.Rep = R 
        self.Equ = E 
        self.n = len(R.Base)  # dimension de l'espace 
        # test de compatibilité 
        if len(E) != self.n + 1: 
            raise MyError("Tailles non concordantes") 
 
    def __str__(self): 
        return "+".join(['(' + str(self.Equ[i]) + ')' + "x" + str(i + 1) for i in range(0, self.n)]) + '=' + str( 
            self.Equ[-1]) 
 
    def Contains(self, P): 
        """test de l'appartenance du point P à l'hyperplan""" 
        X = self.Rep.Coord(P) 
        return sum([self.Equ[i] * X[i] for i in range(0, self.n)]) == self.Equ[-1] 
 
    def Equanorm(self): 
        """Equation normale""" 
        u = VecteurKn(self.Equ[0:-1]) 
        n = u.norm() 
        L = [x / n for x in u.V] 
 
    def Distance(self, P): 
        """Distance d'un point à l'hyperplan""" 
        X = self.Rep.Coord(P) 
        d = abs(sum([self.Equ[i] * X[i] for i in range(0, self.n)]) - self.Equ[-1]) 
        u = VecteurKn(self.Equ[0:-1]) 
        n = u.norm() 
        return d / n 
 
 
class Variete(): 
    """Variete définie comme intersection d'hyperplans""" 
 
    def __init__(self, L): 
        """Initialisation à partir d'une liste d'hyperplans""" 
        self.LH = L 
 
    def Contains(self, P): 
        """test de l'appartenance du point P à la variété""" 
        return all([H.Contains(P) for H in self.LH]) 
 
 
def main(): 
    P = PointKn([0, 0, 0])  # origine standard 
    u = VecteurKn([1.0, 0.0, 0.0]) 
    v = VecteurKn([0.0, 1.0, 0.0]) 
    w = VecteurKn([0.0, 0.0, 1.0]) 
    B = ([u, v, w])  # base canonique 
    R = Repere(P, B) 
    Equation = [1.0, -2.0, -1.0, 3.0]  # plan x-2y-z=3 
    H = Hyperplan(R, Equation) 
    print(H) 
    M = PointKn([1.0, -2.1, 0.0]) 
    N = PointKn([1.0, -1.0, 0.0]) 
    print(H.Distance(M)) 
    print(H.Distance(N)) 
 
 
if __name__ == '__main__': 
    main()