1

Тема: Секторна діаграма

Дуже потрібна допомога.
Завдання: Намалювати секторну діаграму, де значення x={11,12,23,40,50,60}

Ось, що я вже написала:

int x=500, y=230, xp=500, yp=230;
        double d;
...

case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
   
        //Ellipse(hdc,50,10,500,450); //center (275;230)
       
        d=(11*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;
       
        d=(12*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;

        d=(23*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;

        d=(40*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;

        d=(50*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;

        d=(60*2*3.14)/196;
        x=int(xp*cos(d)+yp*sin(d));
        y=int(-xp*sin(d)+yp*cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp=x; yp=y;

        EndPaint(hWnd, &ps);
        break;


Ось, що мені показує програма:
http://i.pixs.ru/storage/3/4/2/kuaucaPNG_1883367_9890342.png

Ну, ніяк не можу зрозуміти, як зробити повороти секторів. Якщо забрати всюди xp=x; yp=y;, то програма малює правильних розмірів сектори в одному місці. А якщо не забирати, то у секторів якісь дивні розміри, хоча і утворюється коло...

2

Re: Секторна діаграма

Прихований текст
        
    int x=500, y=230, xp=500, yp=230;
    double d;
    
    int x[] = {11, 12, 23, 40, 50, 60}
    
    int ArrLen = sizeof(x)/sizeof(x[0]); //отримуємо довжину масиву
    int summ = 0; 
    
    for (int i=0; i<ArrLen; i++) {
        summ += x[i]; //рахуємо суму всіх секторів
    }
    
    
    for (int i=0; i<ArrLen; i++) {        
        d = (x[i]*2*3.14)/summ; //d, мабуть краще назвати "angle"
        
        //щось мені здається що, формула буде інакша, 
        //x = r*cos(angle); 
        //y = r*sin(angle);
        //r - радіус кола
        x = int(xp * cos(d) + yp * sin(d));
        y = int(-xp * sin(d) + yp * cos(d));
        Pie(hdc,50,10,500,450,xp,yp,x,y);
        xp = x; 
        yp = y;
    }

Ще буває, що сінус з косінусом по різному сприймають кут, буває в градусах, буває в радіанах для конвертування треба поділити/домножити на пі

Код вставляйте, будь ласка у тег "code"

3

Re: Секторна діаграма

Прихований текст

//щось мені здається що, формула буде інакша,

Спробувала весь ваш код із вашою формулою для перетворення координат. Теж не виходить.
Свою формулу знайшла на цьому сайті http://www.pm298.ru/dekart.php (та й в універі це проходили...)

Ще буває, що сінус з косінусом по різному сприймають кут, буває в градусах, буває в радіанах для конвертування треба поділити/домножити на пі

Спробувала і з градусами, і з радіанами. Правильно працює тільки з радіанами.

Якщо я просто малюю сектор із певним кутом, то програма це робить правильно. А вот коли я намагаюсь розвертати ці сектори по колу, починає щось плутатись...

Ось, наприклад, для числа 60 там десь 100 з лишнім градусів.

        for (int i=0; i<1; i++) 
        {
            angle = (mas[5]*2*3.14)/summ; 
            //x = r*cos(angle);
            //y = r*sin(angle);
            x = int(xp * cos(angle) + yp * sin(angle));
            y = int(-xp * sin(angle) + yp * cos(angle));
            Pie(hdc,50,10,500,460,xp,yp,x,y);
            xp = x;
            yp = y;
        }

Якщо вивести просто цей сектор, то все нормально. А якщо по колу разом з іншими, то якийсь глюк.

Post's attachments

222222.PNG 4.28 kb, 223 downloads since 2013-11-29 

4 Востаннє редагувалося Chemist-i (29.11.2013 18:58:18)

Re: Секторна діаграма

А може треба без останньої ітерації циклу? щоб замикання не було.
Хоча стоп, в нас сектор це від попереднього до наступного, може треба щось на кшталт:

Не відкривайте, це фігня
angle1 = (mas[i]*2*3.14)/summ;
angle2 = (mas[i-1]*2*3.14)/summ;

x = int(xp * cos(angle1) + yp * sin(angle2));
y = int(-xp * sin(angle1) + yp * cos(angle2));

Ну, ніяк не можу зрозуміти, як зробити повороти секторів. Якщо забрати всюди xp=x; yp=y;, то програма малює правильних розмірів сектори в одному місці. А якщо не забирати, то у секторів якісь дивні розміри, хоча і утворюється коло...

Треба просто до кута додавати попередне значення

angle = (mas[i]*2*3.14)/summ;

x = int(xp * cos(angle + prev_angle) + yp * sin(angle + prev_angle));
y = int(-xp * sin(angle + prev_angle) + yp * cos(angle + prev_angle));
prev_angle = angle;

а х=хр, у=ур прибрати, і тоді все має покрутитись

5 Востаннє редагувалося Rolana (29.11.2013 19:11:44)

Re: Секторна діаграма

Ось ще трішки відредагований код

Прихований текст
        for (int i=0; i<ArrLen; i++) 
        {
            summ += mas[i]; //рахуємо суму всіх секторів
        }
        angle1=0;
        for (int i=0; i<ArrLen; i++) 
        {
            angle = angle1+(mas[i]*3.14)/summ; 
            angle1=angle;
            grad=57*angle; //контроль градусів
            //x = r*cos(angle);
            //y = r*sin(angle);
            x = int(xp * cos(angle) + yp * sin(angle));
            y = int(-xp * sin(angle) + yp * cos(angle));
            //if (i==ArrLen-1) {x=xp1; y=yp1;}
            Pie(hdc,50,10,500,460,xp,yp,x,y);
            xp = x;
            yp = y;
        }

Йде додавання кута angle1. Сектори повертаються правильно. Мають правильні розміри.
АЛЕ! Останній сектор малюється неправильно...

Без хр і ур сектори малюються один поверх одного.

Айай, по-моєму, все рівно розміри секторів неправильні...

6 Востаннє редагувалося koala (29.11.2013 19:18:34)

Re: Секторна діаграма

void DrawPie(HDC hdc, int x, int y, int r, int from, int to)
/*намалювати сектор кола з центром (x,y) радіуса r від кута в градусах from до to 
(від додатнього напрямку OX проти годинникової стрілки*/
{
  Pie( hdc, x - r, y - r, x + r, y + r, 
         x + r * cos( M_PI * from / 180 ), y - r * sin( M_PI * from / 180), 
         x + r * cos( M_PI * to   / 180 ), y - r * sin( M_PI * to   / 180 ) );
}
...
int parts[]={11,12,23,40,50,60},total=0;

for(int i=0;i<sizeof(parts)/sizeof(parts[0]);i++)
  total+=parts[i];

int angle=0;
for(int i=0;i<sizeof(parts)/sizeof(parts[0]);i++)
{
  int newangle = angle+parts[i]*360/total;
  DrawPie(hdc, 275, 230, 225, angle, newangle);
  angle = newangle;
}

От десь так... Ставите angle в потрібний кут і насолоджуєтеся :)

Подякували: Rolana1

7 Востаннє редагувалося Rolana (29.11.2013 19:46:22)

Re: Секторна діаграма

Це неймовірно!!! Воно працює! Ви — мій герой.
Безмежно вдячна!

8

Re: Секторна діаграма

Який гарний код...)) *це я вже вчиталася*

Подякували: Replace1