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

Odpowiedz Nowy wątek
2014-12-17 19:15
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ą.

Pozostało 580 znaków

2014-12-17 19:19
1

http://4programmers.net/Forum/1091904


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-12-17 22:01
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)); 
  1. 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?

Pozostało 580 znaków

2014-12-17 22:22
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);

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-12-18 10:09
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;
} 

Pozostało 580 znaków

2014-12-18 10:40
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))
 

3) 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).

4) 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;
edytowany 2x, ostatnio: vpiotr, 2014-12-18 10:42

Pozostało 580 znaków

2014-12-18 12:07
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.

edytowany 1x, ostatnio: Naitsabes, 2014-12-18 12:10

Pozostało 580 znaków

2014-12-18 12:12
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)

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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