Waňov web

PB071 - 4. cvicení

Vzájemná poloha dvou kruznic

Zadání:

Vytvorte program, který bude (opakovane) od uzivatele nacítat dvojice kruznic  a vyhodnotí vzdy jejich vzájemnou polohu. Kazdá kruznice bude zadána souradnicemi svého stredu a polomerem. Program bude rozlisovat techto sest prípadu:

Pozadavky:

  1. Program zkontroluje vsechny zadané polomery, zda nejsou nulové nebo záporné. V takovém prípade ohlásí chybu, nevyhodnocuje polohu dané dvojice kruznic a pokracuje nactením dalsí dvojice kruznic. Program po ukoncení vrací hodnotu 0, kdyz byly vsechny kruznice platne zadané, poprípade vrací pocet spatne zadaných kruznic.

  2. Program bude pracovat s presností na jednu tisícinu délkové jednotky. To znamená, ze prípad, kdy se kruznice priblízí na vzdálenost 0.001, bude uz povazován za dotyk, stejne jako prípad, kdy se kruznice protnou tak, ze jedna presáhne druhou o tuto malou vzdálenost. Podobne kruznice s polomerem mensím nez 0.001 jiz bude povazována za chybne zadanou (jako kdyby polomer byl nulový). Samotná vstupní data vsak nezaokrouhlujte - tolerance se týká jen posuzování výsledku, resp. správnosti zadání!

  3. Program se normálne ukoncuje zadáním znaku konce souboru (Ctrl D v unixových systémech,Ctrl Zv systémech Microsoft) pred zapocetím nacítání hodnot pro novou dvojici kruznic. Program je schopen akceptovat konec vstupu také po nactení neúplného zadání dané dvojice kruznic, v tom prípade pred ukoncením vypíse chybovou hlásku o neúplnosti vstupu. Návratová hodnota programu se v tomto prípade nemení.

  4. Program bude s uzivatelem komunikovat, vypíse na obrazovku zadané parametry dané dvojice kruznic. Program bude schopen akceptovat jakékoli reálné císlo, nemusí vsak kontrolovat, jestli uzivatel nezadal neco jiného (retezec atp.).

  5. Program nazvete kruznice.c

Bonus:

Az 2 body navíc získá ten, kdo vyresí príklad obecneji pro n-rozmerný prostor, kde n je císlo 1, 2 nebo 3. Takový program bude tedy rozhodovat vzájemnou polohu zobecnených "kruznic", tj. koncových bodu 2 úsecek na prímce (n=1), kruznic v rovine (n=2) nebo kulových ploch v prostoru (n=3). Dimenze prostoru by se v normálním prípade zadávala makrem DIM, napr.

#define DIM 2

program by potom po prelození pracoval podle pozadavku na základní verzi. Kvuli moznosti otestovat program pro ruzné dimenze bez zásahu do zdrojového programu vsak do nej uvedenou direktivu nevkládejte! Program místo toho napiste tak, aby bylo mozno tuto symbolickou konstantu zmenit na jinou hodnotu pomocí parametru pri prekladu (napr. -DDIM=2). Program  uzivateli sdelí, kolik souradnic od nej ocekává, a uzpusobí dané dimenzi nacítání, výpis souradnic, apod.

Pokud odevzdáváte pouze základní variantu, makro DIM nepouzívejte. Rozhodnete-li se zpracovat variantu rozsírenou, oznamte to cvicícímu v E-mailu, kterým úlohu odevzdáváte, aby vedel, ze má testovat speciálním zpusobem a pri správném zpracování priznat body navíc.

Poznámky:


Riešenie:


kruznice.c
#include <stdio.h>
#include <math.h>

extern double round(double x);

int i, chyba, koniec, navratova_hodnota = 0;
float x1, x2, y1, y2, r1, r2, h;
int main()
{
    printf("\n Program na zistenie vzajomnej polohy 2 kruznic\n");
    printf("v 2 dimenzionalnom  priestore.\n \n");
    chyba = x1 = x2 = h = y1 = y2 = r1 = r2 = 0;

    printf("Zadaj prvu kruznicu (x y polomer):");
    if (scanf("%f", &x1) == EOF)
	return navratova_hodnota;
    koniec = (scanf("%f%f", &y1, &r1) == EOF);
    if (koniec)
    {
	printf("ERORR: Neuplny vstup\n");
	return navratova_hodnota;
    }
    printf("Zadaj druhu kruznicu (x y polomer):");
    koniec = (scanf("%f%f%f", &x2, &y2, &r2) == EOF);
    if (koniec)
    {
	printf("ERORR: Neuplny vstup\n");
	return navratova_hodnota;
    }
    if (r1 <= 0)
    {
	++navratova_hodnota;
	chyba += 1;
    };
    if (r2 <= 0)
    {
	++navratova_hodnota;
	chyba += 2;
    };

    r1 = round(1000 * r1) / 1000;
    r2 = round(1000 * r2) / 1000;
    printf("Kruznica1: S[ %f, %f ] r=%f \n", x1, y1, r1);
    printf("Kruznica2: S[ %f, %f ] r=%f \n", x2, y2, r2);


    if (chyba)
    {
	printf("CHYBA - Nesedi polomer ");
	switch (chyba)
	{
	case 1:
	    printf("prvej kruznice.\n");
	    break;
	case 2:
	    printf("druhej kruznice.\n");
	    break;
	case 3:
	    printf("oboch kruznic.\n");
	    break;
	}
    } else
    {
	h = (round(1000 * sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)))) / 1000;
	printf("Vzdialenost stredu kruznic je %f \n", h);
	if ((h == 0) && (r1 == r2))
	    printf("Kruznice sa zhoduju\n");
	if (h > (r1 + r2))
	    printf("Kruznice sa nepretinaju\n");
	if ((h == (r1 + r2)) && (h > r1) && (h > r2))
	    printf("Kruznice sa dotykaju, nelezi jedna v druhe\n");
	if ((h == fabs(r1 - r2)) && (h != 0))
	    printf("Kruznice sa dotykaju, jedna lezi v druhej\n");
	if (h < fabs(r1 - r2))
	    printf("Kruznica lezi v druhej, nedotykaju sa\n");
	if ((h < (r1 + r2)) && (h > fabs(r1 - r2)))
	    printf("Kruznice sa pretinaju\n");
    }

    main();

    return navratova_hodnota;

}