// Use this for initialization
    void Start()
    {
        plano = new Plano();
        retasPlano = new Reta[2];
        retasPlano[0] = new Reta(ObjsPontoPlano[0], ObjsPontoPlano[1]);
        retasPlano[1] = new Reta(ObjsPontoPlano[0], ObjsPontoPlano[2]);

        normal = new Reta();
        normal = plano.CalcularN(retasPlano[0], retasPlano[1]);

        vetorDirecaoReta = new Reta();
        vetorDirecaoReta.x = Mathf.Round(ObjsPontoReta[1].transform.position.x) - (Mathf.Round(ObjsPontoReta[0].transform.position.x));
        vetorDirecaoReta.y = Mathf.Round(ObjsPontoReta[1].transform.position.y) - (Mathf.Round(ObjsPontoReta[0].transform.position.y));
        vetorDirecaoReta.z = Mathf.Round(ObjsPontoReta[1].transform.position.z) - (Mathf.Round(ObjsPontoReta[0].transform.position.z));

        EquacaoParam = vetorDirecaoReta.EquacaoParametrica(ObjsPontoReta[0]);
        stringTema.text = "Parametrica";
        stringEquacaoParametrica.text = "";
        foreach (var item in EquacaoParam)
        {
            stringEquacaoParametrica.text += item;
        }
        print("Reta Direção: " + Mathf.Round(vetorDirecaoReta.x) + ", " + vetorDirecaoReta.y + ", " + vetorDirecaoReta.z);
        print("Normal: " + normal.x + ", " + normal.y + ", " + normal.z);
    }
    public static Ponto?Inter(Reta r1, Reta r2)
    {
        if (r1 == r2)
        {
            return(null);          // infinitos pontos
        }
        else if (Paralela(r1, r2))
        {
            return(null);                       // nenhum ponto
        }
        Ponto p = new Ponto();

        if (r1.a == 0)
        {
            p.y = -r1.c / r1.b;
            p.x = (-r2.c - r2.b * p.y) / r2.a;
        }
        else
        {
            p.y = (-r2.c + (r1.c * r2.a / r1.a)) / (r2.b - (r1.b * r2.a / r1.a));
            p.x = (-r1.c / r1.a) - (r1.b * p.y / r1.a);
        }

        return(p);
    }
    public Reta CalcularN(Reta AB, Reta AC)
    {
        Reta N = new Reta();

        N.x = (AB.y * AC.z) - (AB.z * AC.y);
        N.y = -(AB.x * AC.z) - (AB.z * AC.x);
        N.z = (AB.x * AC.y) + (AB.y * AC.x);
        this.N = N;
        return N;
    }
    // Update is called once per frame
    void Update()
    {
        ChangeText();

        plano = new Plano();
        retasPlano = new Reta[2];
        retasPlano[0] = new Reta(ObjsPontoPlano[0], ObjsPontoPlano[1]);
        retasPlano[1] = new Reta(ObjsPontoPlano[0], ObjsPontoPlano[2]);

        normal = new Reta();
        normal = plano.CalcularN(retasPlano[0], retasPlano[1]);

        vetorDirecaoReta = new Reta();
        vetorDirecaoReta.x = Mathf.Round(ObjsPontoReta[1].transform.position.x) - (Mathf.Round(ObjsPontoReta[0].transform.position.x));
        vetorDirecaoReta.y = Mathf.Round(ObjsPontoReta[1].transform.position.y) - (Mathf.Round(ObjsPontoReta[0].transform.position.y));
        vetorDirecaoReta.z = Mathf.Round(ObjsPontoReta[1].transform.position.z) - (Mathf.Round(ObjsPontoReta[0].transform.position.z));
        plano.EqGeral(ObjsPontoPlano[0]);
        distancia.text = plano.Distancia(pontaFlecha).ToString();
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            switch (stringTema.text)
            {
                case "Eq. Geral Plano":
                    stringTema.text = "Parametrica";
                    stringEquacaoParametrica.text = "";
                    EquacaoParam = vetorDirecaoReta.EquacaoParametrica(ObjsPontoReta[1]);

                    foreach (var item in EquacaoParam)
                    {
                        stringEquacaoParametrica.text += item;
                    }

                    break;

                case "Simetrica":
                    stringTema.text = "Eq. Geral Plano";
                    stringEquacaoParametrica.text = "asd";

                    stringEquacaoParametrica.text = plano.EqGeral(ObjsPontoPlano[0]);
                    print("n " + normal.x + "\n" + ObjsPontoReta[1].transform.position.x + "\n" + plano.x);
                    break;

                case "Parametrica":
                    stringTema.text = "Simetrica";
                    stringEquacaoParametrica.text = vetorDirecaoReta.EquacaoSimetrica(ObjsPontoReta[1]);
                    break;
            }
        }
    }
        /// <summary>
        /// Calculo de intersecção de retas dados 2 pontos para cada reta. Metodo: Determinante
        /// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
        /// </summary>
        /// <param name="r">Segunda reta para calculo de intersecção</param>
        /// <returns>Ponto de intersecção das retas</returns>
        public Point Intersect(Reta r)
        {
            var x1 = this.startPoint.X;
            var y1 = this.startPoint.Y;
            var x2 = this.endPoint.X;
            var y2 = this.endPoint.Y;

            var x3 = r.startPoint.X;
            var y3 = r.startPoint.Y;
            var x4 = r.endPoint.X;
            var y4 = r.endPoint.Y;

            return(new Point(
                       ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
                       ,
                       ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4))
                       ));
        }
    public static Ponto?Inter(Segmento seg, Reta r)
    {
        Ponto?p = Reta.Inter(r, seg.r);

        if (p == null)
        {
            return(null);
        }

        if (r.Contem(seg.p1))
        {
            return(seg.p1);
        }
        if (r.Contem(seg.p2))
        {
            return(seg.p2);
        }

        return(seg.Contem((Ponto)p) ? p : null);
    }
    public static List <Tuple <Ponto, int> > Inter(Poligono poly, Reta r)
    {
        int i;
        var intersec = new List <Tuple <Ponto, int> >();

        for (i = 0; i < poly.pontos.Count; i++)
        {
            //seg [p_i - p_i+1]
            int prox = (i + 1) % poly.pontos.Count;

            Segmento seg = new Segmento(poly.pontos[i], poly.pontos[prox]);
            if (r.Contem(seg.p1) && r.Contem(seg.p2))
            {
                //intersec.Add(new Tuple<Ponto, bool>(seg.p1, true));
                intersec.Add(new Tuple <Ponto, int>(seg.p2, prox));
            }
            else
            {
                Ponto?p = Segmento.Inter(seg, r);
                if (p != null)
                {
                    bool isExtremo = false;
                    if (p == seg.p1 || p == seg.p2)
                    {
                        isExtremo = true;
                    }

                    if (!isExtremo || p == seg.p2)
                    {
                        intersec.Add(new Tuple <Ponto, int>((Ponto)p, isExtremo ? prox : -1));
                    }
                }
            }
        }

        return(intersec);
    }
 public Segmento(Ponto p1, Ponto p2)
 {
     this.p1 = p1; this.p2 = p2;
     this.r  = new Reta(p1, p2);
 }
 public static bool Paralela(Reta r1, Reta r2)
 {
     return(Ponto.Colinear(new Ponto(0), new Ponto(r1.a, r1.b), new Ponto(r2.a, r2.b)));
 }
 public double ProdutoEscalar(Reta N, Ponto A)
 {
     double prod = (N.x * A.x) + (N.y * A.y) + (N.z * A.z);
     return prod;
 }