eMatematikas Prisijunk Forumas Egzaminų užduotys ONLINE testai

Koordinačių plokštuma ir atstumai. Programavimas


Sveiki, gal galit pagebėti su vienu uždaviniu?:
Koordinačių plokštumoje yra daug apskritimų, kurių centrų koordinatės(x;y) ir spinduliai žinomi. Surasti kuris apskritimas daugiausiai kerta kitų ir koks jo atstumas iki koordinačių pradžios taško. Sukurti ir naudoti funkciją, kuri skaičiuoja atstumą tarp dviejų duotų taškų. Spausdinti duomenis ir skaičiavimo rezultatus.

Neįsivaizduoju kaip daryti pirmą dalį(kuris apskritimas daugiausiai kerta kitus), kitas suprantu. Kolkas duomenis pasiemiau tokius:
5(skaicius apskritimu)
x y r
2 3 3
5 -2 4
1 1 2
-4 2 5
-2 -4 4
Kokas tik tiek padariau...
#include <iostream>
#include <fstream>
#include <iomanip>
//========================================================================
const char in[]="Duomenys.txt";
const char out[]="Rezultatai.txt";
const int CMax=100;
//========================================================================
using namespace std;
//========================================================================
void skaityti(int x[],int y[], int r[], int sk);
//========================================================================
int main()
{
    int x[CMax];//x kordinaciu masyvas
    int y[CMax];//y kordinaciu masyvas
    int r[CMax];//Spinduliu masyvas
    int sk; // Apskritimu skaicius

    skaityti(x,y,r,sk);

    return 0;
}
//========================================================================
void skaityti(int x[],int y[], int r[], int sk){
    ifstream fd(in);
    fd>>sk;
    for(int i=0; i<sk; i++){
        fd>>x[i]>>y[i]>>r[i];
    }
}
//========================================================================
void Kerta_kitus(int x[],int y[], int r[], int sk){
    for(int i=0; i<sk; i++){
    if()
}
}

Tau reikia išsiaiškinti būtinas dviejų apskritimų kirtimosi sąlygas. Reikia nagrinėti tris atvejus. Kai vieno apskritimo centras yra kito apskritimo viduje, kai vieno apskritimo centras yra ant kito apskritimo ir kai vieno apskritimo centras yra kito išorėje. Kiekvienu atveju išsiaiškinti, kokias sąlygas turi atitikti tų apskritimų spinduliai atstumo tarp tų apskritimų centrų atžvilgiu.

pakeista prieš 6 m

http://i.imgur.com/6dSkD4b.jpg
[tex](x_{0},y_{0})[/tex] ir [tex](x_{1},y_{1})[/tex], bei [tex]s_{0}[/tex] ir [tex]s_{1}[/tex] - atitinkamai primo ir antro apskritimų centrų koordinatės bei spindulių ilgiai, d - astumas tarp apskritimų centrų.

Nesunku pastebėti, kad klaidingi atvejai bus tada ir tik tada, kai
[tex]\begin{cases} d > s_{1}+s_{0} \text{ (išvis nekerta)}\\ d < |s_{1}-s_{0}| \text{ (vienas apskritimas kitame)} \\ d = 0, s_{1}=s_{0} \text{ (tie patys apskritimai)}\\\end{cases}[/tex],

o mus tenkins tik
[tex]\begin{cases} d < s_{1}+s_{0} \text{ (kirs apskritimą du kartus)}\\ d = s_{0}+s_{1} \text{ (apskritimai liesis)}\\\end{cases}[/tex]

C kodas: (dėl patogumo įdėjau ir čia: https://pastebin.com/XHiHYRGw)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//---------------------------------------------------------------------------------
#define MAX 100
#define FILE_NAME "input.txt"
//---------------------------------------------------------------------------------
// Funkciju prototipai
void duomenuNuskaitymas(int *sk, double x[], double y[], double s[]);
double distanceBetweenTwoPoints(int x0, int y0, int x1, int y1);
int searchForIntersects(int sk, double x[], double y[], double s[]);
int theMostIntersects(int arr[], int n);
//---------------------------------------------------------------------------------
int main()
{
    int sk;                        // apskritimu skaicius
    double x[MAX], y[MAX], s[MAX]; // apskritimu parametrai

    duomenuNuskaitymas(&sk, x, y, s);
   
    printf("Daugiausiai kartu kerta %d-asis apskritimas\n", searchForIntersects(sk, x, y, s)+1);
    return 0;
}
//---------------------------------------------------------------------------------
// grazinamas indeksas apskritimo, kuris kertasi daugiasiai kartu
int theMostIntersects(int arr[], int n)
{
    int index = 0, max = 0;
    for(int i = 0; i<n; i++)
        if(arr[i] > max){
            max = arr[i];
            index = i;
        }
    return index;
}
//---------------------------------------------------------------------------------
// Blogi atvejai:
// d > s1 + s0 (isvis nekerta)
// d < |s1 - s0| (vienas apskritimas kitame)
// d = 0 ir s1 = s0 (tie patys apskritimai)
//
// Geri atvejai:
// d < s1 + s0 (apskritimai kertami du kartus)
// d = s1 + s0 (apskritimai lieciasi)
//
// funkcija grazins to apskritimo, kuris daugiausiai kerta kitu, indeksa.
// Jeigu yra keli tokie apskritimai, bus grazinamas pirmiau duomenu faile
// pateikto apskritimo indeksas
int searchForIntersects(int sk, double x[], double y[], double s[])
{
    int howManyIntersects[sk];    // kiek kiekvienas apskritimas kerta kitu
    double d;                      // atstumas tarp dvieju tasku

    // apnulinamos reiksmes kad galetume sumuoti susikirtimus:
    for(int i = 0; i<sk; i++)
        howManyIntersects[i] = 0;

    for(int i = 0; i<sk; i++){ // einame per pradini apskritima
        for(int j = 0; j<sk; j++){ // i-tasis apskritimas lyginamas su j-tuoju apskritimu
            if(i != j){ // praleidziame vienodus apskritimus
                d = distanceBetweenTwoPoints(x[i], y[i], x[j], y[j]);
                if(d > s[i] + s[j] || d < fabs(s[i] - s[j]) || (d == 0 && s[i] == s[j]))
                    ; // do nothing as those cases are wrong
                else if(d < s[i] + s[j] || d == s[i] + s[j])
                    howManyIntersects[i]++; // vadinasi i-tasis apskritimas kerta j-taji apskritima
            }
        }
    }
    return theMostIntersects(howManyIntersects, sk);
}
//---------------------------------------------------------------------------------
// funkcija randa ir grazina atstuma tarp dvieju tasku
double distanceBetweenTwoPoints(int x0, int y0, int x1, int y1)
{
    return sqrt(pow((x1-x0),2)+pow((y1-y0),2));
}
//---------------------------------------------------------------------------------
void duomenuNuskaitymas(int *sk, double x[], double y[], double s[])
{
    FILE *fp = fopen(FILE_NAME, "r");

    if(fp != NULL){
        fscanf(fp, "%d", &*sk);
        if(*sk > 0){
            for(int i = 0; i<*sk; i++)
                fscanf(fp, "%lf%lf%lf", &x[i], &y[i], &s[i]);
        }else{
            printf("Nekorektiska ivestis..\n");
            exit(EXIT_FAILURE);
        }
        fclose(fp);
    }else{
        printf("Toks failas pavadinimu %s nerastas\n", FILE_NAME);
        exit(EXIT_FAILURE);
    }
}

pakeista prieš 6 m

x y s
2 3 3  ==> 3 kartus
5 -2 4  ==> 3 kartus
1 1 2  ==> 4 kartus
-4 2 5  ==> 3 kartus
-2 -4 4 ==> 3 kartus


brėžinys:
https://i.imgur.com/jo96moE.png
(apskritimai sunumeruoti A, B, ..., E pagal eiliškumą)

pakeista prieš 6 m

purexlt, argi tavo sąlygos tikrai teisingos?
Pagal tave apskritimai tikrai kirsis, jei atstumas tarp apskritimų centrų bus mažesnis už tų apskritimų spindulių ilgių sumą. Štai atvejis, paneigiantis tavo teiginį:
https://www.ematematikas.lt/upload/images/1510413730_2093.gif

pakeista prieš 6 m

Pakoreguoju:
tenkinantis atvejis bus kai apskritimai liesis viename taške, t.y. [tex]d=s_{0}+s_{1}[/tex], ir tenkins visi kiti atejai, prieštaraujantys klaidingiems (lygčių sistema su 3 reiškiniais). 63 kodo eilutėje galima nutraukti tolimesnį tikrinimą ir pereiti prie i+1 apskritimo nagrinėjimo. Ačiū už pastebėjimą tomas14.

pakeista prieš 6 m

Wow! labai dėkui.

Nori sudalyvauti šioje temoje ir parašyti savo pranešimą? Prisijungti »