Calcular la intersección de dos segmentos

Iniciado por DickGumshoe, 31 Octubre 2011, 01:43 AM

0 Miembros y 1 Visitante están viendo este tema.

DickGumshoe

Hola.

Estoy haciendo un programa en c++; el cual debe calcularme la intersección entre dos segmentos.

Tengo planteado todo el problema.  Y además, me calcula bien casi todos los tipos de intersecciones.

Mi código es:



//Este programa calcula la interseccion de dos segmentos

#include<stdio.h>
#include<stdlib.h>

int main (void){
   
    float a,b,c,d;
   
    printf("\n Introduzca el primer numero del primer segmento");
    scanf ("%f",&a);

    printf("\n Introduzca el segundo numero del primer segmento");
    scanf ("%f",&b);
   
    printf("\n Introduzca el primer numero del segundo segmento");
    scanf ("%f",&c);
   
    printf("\n Introduzca el segundo numero del segundo segmento");
    scanf ("%f",&d);
   
   
          if (b<c){
          printf ("La interseccion es vacia");
          }
          else { if (a>d)
          printf ("La interseccion es vacia"); 
         
          else {if (a<c, b>d)
                   printf ("La interseccion es %f,%f", c,d);
                    else
                     {if (a>c, b>d)
                 printf ("La interseccion es %f,%f", a,d);
                 
              else {
          if (a<c, b==d) {
                   printf ("La interseccion es %f,%f", c,b);
                   }
                   else {if (a==c, b==d)
                   printf ("La intersección es %f,%f", a,c);
                   
           
           
     
            else {
          if (b==c){
          printf ("La interseccion es el punto %f",b);
          }
       
   
          else { if (a==d)
          printf ("La interseccion es el punto %f",a);
                   
                   
                   
          else{
          if (a<c, b>d) {
                   printf ("La interseccion es %f,%f", c,d);
                   }
                   
                   
                   }}}}}}}}
           
   system("pause");
}




Bien; ahora planteo el problema... Me coge bien todas las intersecciones, excepto los dos tipos siguientes:

else {if (a<c, b>d)
                   printf ("La interseccion es %f,%f", c,d);
                    else
                   
                  {if (a>c, b>d)
                 printf ("La interseccion es %f,%f", a,d);


Al ir cambiando el código, siempre me sale bien uno de los dos tipos de intersecciones de arriba, pero no soy capaz de que me salgan los dos a la vez. Con eso, completaría el programa que estoy creando.

Muchas gracias.

rir3760

En ese programa asumes, por alguna razón que esto:
if (a<c, b>d)
Es valido y hace lo que tu esperas de el (No es así).

En C la coma es un operador secuencial, este evalúa su expresión a la izquierda y descarta su resultado. A continuación se evalúa la expresión a su derecha y ese es su resultado. Por ejemplo esto:
2, 5
Es una expresión y su resultado es 5.


En tu caso esto:
if ( a < c, b > d)
Es equivalente a:
if ( b > d )


Lo que debes hacer es utilizar los operadores lógicos AND/OR. Cual utilizar depende del caso y su explicación la puedes encontrar en un buen libro (Revisa los temas fijos del foro).

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

DickGumshoe

¡Muchísimas gracias! He estado toda la noche mirando todo el código, y al final era solo poniendo & en vez de ",".


do-while

¡Buenas!

Creo que se puede hacer mucho mas corto añadiendo dos variables mas, inf y sup que indiquen el infimo y supremo del conjunto resultante, si existe:

//Este programa calcula la interseccion de dos segmentos

#include<stdio.h>
#include<stdlib.h>

int main (void){

    float a,b,c,d,inf,sup;

    printf("\n Introduzca el primer numero del primer segmento");
    scanf ("%f",&a);

    printf("\n Introduzca el segundo numero del primer segmento");
    scanf ("%f",&b);

    printf("\n Introduzca el primer numero del segundo segmento");
    scanf ("%f",&c);

    printf("\n Introduzca el segundo numero del segundo segmento");
    scanf ("%f",&d);
    getchar(); // leemos el salto de linea que queda en stdin

    //comprobamos que los intervalos esten bien definidos (a <= b y c <=d)
    if(a > b || c > d)
    {
        printf("Los intervalos no estan bien definidos.\n");
    }
    else
    {
        //si el supremo de uno de los intervalos es menor que el infimo del otro
        if(b < c || d < a)
        {
            //el conjunto es vacio
            printf("Interseccion vacia.\n");
        }
        else
        {
            inf = a; //probamos con uno de los valores candidatos a infimo
            if(c > a) //y si no es el mayor de los infimos, lo cambiamos
                inf = c;

            sup = b; //probamos candidato a supremo
            if(d < b) //si no es el minimo de los dos supremos, lo cambiamos
                sup = d;

            printf("Interseccion: %f , %f\n",inf,sup);
        }
    }

    printf("Pulsar intro para terminar...");
    //leemos hasta que se wencuentre intro
    while(getchar() != '\n');

    return 0;
}


Espero que entiendas la logica del programa, sino, pregunta.
Se puede acortar todavia mas si conoces el operador condicional ternario.

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!

DickGumshoe

Ah, muchas gracias a ti también.

Por ahora lo voy a hacer así, porque estoy empezando, supongo que en los manuales vendrá después cómo usar esos conceptos.

De todas formas voy a probar.

Gracias de nuevo.

ghastlyX

Esto se suele resolver con la técnica de máximos-mínimos, generalizable a más dimensiones. Si se tienen dos segmentos en R, su intersección claramente será el máximo de los extremos izquierdos y el mínimo de los extremos derechos (siempre que esta exista, es decir, que el máximo sea menor o igual que el mínimo).

De esta forma, queda un código muy simple:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main() {
    int a1, b1, a2, b2;
    cin >> a1 >> b1 >> a2 >> b2;
    int a = max(a1, a2), b = min(b1, b2);
    if (a <= b) cout << a << " " << b << endl;
    else cout << "Interseccion vacia" << endl;
}

DickGumshoe

Ah, muchas gracias a ti también.

Todavía no he estudiado los tipos de librerías, así que no conocía la de <iostream>, pero muchas gracias, estoy practicando con este tipo ahora ^^