Funkcja sprawdzająca przecinanie się okręgów

0

Witam,
Staram się napisać funkcję, która umożliwi sprawdzenie czy okręgi zapisane za pomocą struktury

 struct wspolrzedneOkregu{
	int x;
	int y;
	int promien;
};

i tworzone funkcją

void stworzOkregi(){
	srand(time(NULL));
	int i;
	struct wspolrzedneOkregu wspolrzedne[10];
	for(i=0; i<10; i++){
			wspolrzedne[i].x=rand()%21-10;
			wspolrzedne[i].y=rand()%21-10;
			wspolrzedne[i].promien=abs(rand()%21-10);
	}
} 

będą się przecinały.

Zacząłem w ten sposób ale koniec końców utknąłem w martwym punkcie i nie wiem jak z tym dalej ruszyć.

void sprawdzPrzecinanie(){
	struct wspolrzedneOkregu *wsk;
		int i;
		for(i=0; i<10; i++){
			if(abs(wsk->promien-wsk->promien+1)<sqrt((wsk->x+1-wsk->x)(wsk->x+1-wsk->x)+(wsk->y+1-wsk->y)(wsk->y+1-wsk->y))&&(wsk->promien+wsk->promien+1)>sqrt((wsk->x+1-wsk->x)(wsk->x+1-wsk->x)+(wsk->y+1-wsk->y)(wsk->y+1-wsk->y)));
} 

Proszę o pomoc. Nie mam bladego pojęcia jak sprawić aby warunek sprawdzał wszystkie wartości a nie każdą kolejną.

0

Siedzę nad tym i nie bardzo wiem jak rozumieć (nie znam C++)

for(circle cr;cin>>cr.y>>cr.x>>cr.r;tb.push_back(cr)) for(int i=0;i<tb.size();++i) count+=(sqr(tb[i].y-cr.y)+sqr(tb[i].x-cr.x)<sqr(tb[i].r+cr.r)); 
circle cr

to inicjalizacja zmiennej cr przy użyciu struktury circle zgadza się?
2.

cin>>cr.y>>cr.x>>cr.r

na czym polega to wyrażenie testowe?
3.

tb.push_back(cr)

ta aktualizacja zwraca nową wartość cr wykorzystywaną dla następnej iteracji?

1

To są wczytywanie i wypełnienie tabeli, dla ciebie ważne jest:

sqr(tb[i].y-cr.y)+sqr(tb[i].x-cr.x)<sqr(tb[i].r+cr.r);
0

Może ktoś zerknąć czy jest napisany prawidłowo?
Ogólnie ma losować współrzędne okręgów, sprawdzać czy się przecięły, jeśli tak to zapisać w pliku tekstowym i posortować.

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

#define PI 3.14

struct wspolrzedneOkregu{
	int x;
	int y;
	int promien;
};

struct wspolrzedneOkregu wspolrzedne[10];

void stworzOkregi(){
	srand(time(NULL));
	int i;
	for(i=0; i<10; i++){
			wspolrzedne[i].x=rand()%21-10;
			wspolrzedne[i].y=rand()%21-10;
			wspolrzedne[i].promien=abs(rand()%21-10);
	}
}

void sprawdzPrzecinanie(wspolrzedneOkregu wspolrzedne[]){
		int i, j;
		for(i=0; i<10; i++){
			for(j=i+1; j<10; j++){
				if((wspolrzedne[j].y-wspolrzedne[i].y)*(wspolrzedne[j].y-wspolrzedne[i].y)+(wspolrzedne[j].x-wspolrzedne[i].x)*(wspolrzedne[j].x-wspolrzedne[i].x)<(wspolrzedne[j].promien+wspolrzedne[i].promien)*(wspolrzedne[j].promien+wspolrzedne[i].promien));
				printf("Okregi przecinajace sie:\nx=%d y=%d r=%d\tx=%d y=%d r=%d\n", wspolrzedne[j].x, wspolrzedne[j].y, wspolrzedne[j].promien, wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien);
				FILE *fp;
				fp=fopen("przecinajaceSieOkregi.txt", "w");
				fprintf (fp, "Okregi przecinajace sie:\nx=%d y=%d r=%d\tx=%d y=%d r=%d\n", wspolrzedne[j].x, wspolrzedne[j].y, wspolrzedne[j].promien, wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien);
				fclose (fp);
		}
	}
}

void sortowanieOkregow(wspolrzedneOkregu wspolrzedne[], int rozmiar){
	int i, j;
	wspolrzedneOkregu temp;
	for(i=0; i<rozmiar-1; i++){
		for(j=0; j<rozmiar-1-i; j++){
			if(wspolrzedne[j].promien > wspolrzedne[j+1].promien){
				temp=wspolrzedne[j+1];
				wspolrzedne[j+1]=wspolrzedne[j];
				wspolrzedne[j]=temp;
				}
			}
		}
	for(i=0; i<rozmiar-1; i++)	
		printf("Okrag (x=%d y=%d r=%d) ma pole: %f\n", wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien, PI*(wspolrzedne[i].promien*wspolrzedne[i].promien));
}

int main(){

	stworzOkregi();
	sprawdzPrzecinanie(wspolrzedne);
	sortowanieOkregow(wspolrzedne, 10);

return 0;
} 
2

@Naitsabes: co tu jest źle:

  1. stała PI jest zdefiniowana: http://msdn.microsoft.com/pl-pl/library/4hwaceh6.aspx

  2. ten kod jest nieczytelny:

                if((wspolrzedne[j].y-wspolrzedne[i].y)*(wspolrzedne[j].y-wspolrzedne[i].y)+(wspolrzedne[j].x-wspolrzedne[i].x)*(wspolrzedne[j].x-wspolrzedne[i].x)<(wspolrzedne[j].promien+wspolrzedne[i].promien)*(wspolrzedne[j].promien+wspolrzedne[i].promien));

propozycja zamiany:

int pow2(int x)
{
  return x*x;
}

int vect_len2(struct wspolrzedneOkregu wsp1, struct wspolrzedneOkregu wsp2) 
{
  return pow2(wsp1.y-wsp2.y)+pow2(wsp1.x-wsp2.x);
}

                if (vect_len2(wspolrzedne[j], wspolrzedne[i]) < pow2(wspolrzedne[j].promien+wspolrzedne[i].promien))

  1. w jednej funkcji masz kilka czynności: sprawdzPrzecinanie
  • pętla
  • sprawdzenie warunku
  • wyświetlenie na ekranie
  • zapis do pliku (w tym otwarcie, zakmnięcie, zapis)

Powinna być jedna-dwie czynności na funkcję.
Lepiej już jest w sortowanieOkregow - masz tam dwie osobne pętle (czyli dwóch kandydatów na funkcje).

  1. użyj stałej do definiowania rozmiaru tablicy:

Zamiast:

struct wspolrzedneOkregu wspolrzedne[10];
//...
sortowanieOkregow(wspolrzedne, 10);

Napisz:

#define ARRAY_SIZE 10

struct wspolrzedneOkregu wspolrzedne[ARRAY_SIZE];
//...
sortowanieOkregow(wspolrzedne, ARRAY_SIZE);

Dzięki temu zmiana rozmiaru tablicy nie pociągnie za sobą zmiany losowanych wartości:

wspolrzedne[i].x=rand()%21-10;
0

Właśnie zauważyłem że program nie zapisuje do pliku wszystkich przecinających się okręgów oraz błędnie sprawdza, które się przecinają.
Oto kod po przeróbkach:

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

#define _USE_MATH_DEFINES
#include <math.h>

#define ROZMIARTABLICY 10

struct wspolrzedneOkregu{
	int x;
	int y;
	int promien;
};

struct wspolrzedneOkregu wspolrzedne[ROZMIARTABLICY];

void stworzOkregi(){
	srand(time(NULL));
	int i;
	for(i=0; i<10; i++){
			wspolrzedne[i].x=rand()%21-10;
			wspolrzedne[i].y=rand()%21-10;
			wspolrzedne[i].promien=abs(rand()%21-10);
	}
}

int kwadrat(int x){
  return x*x;
}
 
int dlugosc(struct wspolrzedneOkregu wsp1, struct wspolrzedneOkregu wsp2){
  return kwadrat(wsp1.y-wsp2.y)+kwadrat(wsp1.x-wsp2.x);
}

void zapisDoPliku(){
	int i, j;
	for(i=0; i<ROZMIARTABLICY; i++){
			for(j=i+1; j<ROZMIARTABLICY; j++){
				FILE *fp;
				fp=fopen("przecinajaceSieOkregi.txt", "a+");
				fprintf (fp, "Okregi przecinajace sie:\nx=%d y=%d r=%d\tx=%d y=%d r=%d\n", wspolrzedne[j].x, wspolrzedne[j].y, wspolrzedne[j].promien, wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien);
				fclose (fp);
		}
	}
}

void sprawdzPrzecinanie(wspolrzedneOkregu wspolrzedne[]){
		int i, j;
		for(i=0; i<ROZMIARTABLICY; i++){
			for(j=i+1; j<ROZMIARTABLICY; j++){
				if (dlugosc(wspolrzedne[j], wspolrzedne[i]) < kwadrat(wspolrzedne[j].promien+wspolrzedne[i].promien));
				printf("\nOkregi przecinajace sie:\nx=%d y=%d r=%d\tx=%d y=%d r=%d\n", wspolrzedne[j].x, wspolrzedne[j].y, wspolrzedne[j].promien, wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien);
				zapisDoPliku();
		}
	}
}

void sortowanieOkregow(wspolrzedneOkregu wspolrzedne[], int rozmiar){
	int i, j;
	wspolrzedneOkregu temp;
	for(i=0; i<rozmiar-1; i++){
		for(j=0; j<rozmiar-1-i; j++){
			if(wspolrzedne[j].promien > wspolrzedne[j+1].promien){
				temp=wspolrzedne[j+1];
				wspolrzedne[j+1]=wspolrzedne[j];
				wspolrzedne[j]=temp;
				}
			}
		}
	for(i=0; i<rozmiar-1; i++)	
		printf("Okrag (x=%d y=%d r=%d) ma pole: %.2f\n", wspolrzedne[i].x, wspolrzedne[i].y, wspolrzedne[i].promien,  M_PI*(wspolrzedne[i].promien*wspolrzedne[i].promien));
}

int main(){

	stworzOkregi();
	sprawdzPrzecinanie(wspolrzedne);
	sortowanieOkregow(wspolrzedne, ROZMIARTABLICY);

return 0;
}

EDIT:Ok już rozumiem czemu zapisywał tylko jeden okrąg (głuptas ze mnie :), już poprawiłem w kodzie ). Teraz jedyny problem to przecinanie, które nie działa jak powinno.

0

Może jeszcze bardziej niż @vpiotr zamieniłbym tamtą letanie

int sqr(int x) { return x*x; } 
int intersect(struct wspolrzedneOkregu a, struct wspolrzedneOkregu b) { return sqr(a.y-b.y)+sqr(a.x-b.x)-sqr(a.promien+b.promien); }
 
if (intersect(wspolrzedne[j], wspolrzedne[i])<0)

1 użytkowników online, w tym zalogowanych: 0, gości: 1