Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Нахождение точки графика по рисунку, Измерение кривой отрезками 
:(
    Опции темы
colaa
Дата 8.3.2006, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



Зараннее спасибо всем кто поможет
Программа измеряет одинаковыми отрезками кривую
Что я сделал:
- загрузил в окно BMP-файл с нужной кривой
- создал функцию для поиска начала этой кривой
-создал функцию, которая перемещает начало координат в точку начала кривой , допустим точку А, сканирует окружность вокруг точки А с заданным радиусом, находит там черную точку Б и проводит линию от точки А к точке Б, все

Я не знаю как зацикловать, то есть дальше нужно чтобы начало координат перемещалось в точку Б, также сканировалась следующая окружность, находилась точка В И строилась бы линия от Б к В, и так до конца

Сейчас код уже рабочий и строит одну линию, файл BMP должен быть в той же папке что и прога и называться dogs.bmp

Вот листинг
Код

#include <windows.h>
#include <math.h>

#define TWOPI   (2 * 3.14159)

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
     {
     static char szAppName[] = "LineDemo" ;
     HWND        hwnd ;
     MSG         msg ;
     WNDCLASSEX  wndclass ;

     wndclass.cbSize        = sizeof (wndclass) ;
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = NULL ;
     wndclass.lpszClassName = szAppName ;
     wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;

     RegisterClassEx (&wndclass) ;

     hwnd = CreateWindow (szAppName, "Line Demonstration",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;

     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;

     while (GetMessage (&msg, NULL, 0, 0))
          {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
          }
     return msg.wParam ;
     }

//Вычисляем первую черную точку

POINT SearthFirstPixel(HDC hdc, int cxClient, int cyClient)
{
    int i, j;
    COLORREF BlackPixel;
    POINT   BlackPoint;

    BlackPixel = RGB(0,0,0);
    for (i = 0; i < cxClient; i = i++)
        for(j = 0; j < cyClient; j++)
        
            if(BlackPixel == GetPixel(hdc, i, j))
            {
             BlackPoint.x = i;
             BlackPoint.y = j;
             return BlackPoint;
            }

}

//Ищем на дуге круга с заданным радиусом черную точку
//И проводим линию от начала координат до черной точки на дуге
void GoClock (HDC hdc, POINT pt,  POINT CenterPoint )
     {
     double     i ;
     POINT        ptTemp ;
     COLORREF   BlackPixel;
     HPEN        PenStyle;

     PenStyle = CreatePen(PS_SOLID,1,RGB(0,0,255));
     SelectObject(hdc, PenStyle);
     BlackPixel = RGB(0,0,0);
     SetWindowOrgEx(hdc, -CenterPoint.x, -CenterPoint.y, NULL);
     MoveToEx(hdc, 0, 0, NULL);
     for (i = 0 ; i < 180 ; i = i + 0.1)
       {
          ptTemp.x = (int) (pt.x * cos (TWOPI * i / 360) +
                            pt.y * sin (TWOPI * i / 360)) ;

          ptTemp.y = (int) (pt.y * cos (TWOPI * i / 360) -
                            pt.x * sin (TWOPI * i / 360)) ;

          if(BlackPixel == GetPixel(hdc,ptTemp.x, ptTemp.y))
          {
            LineTo(hdc,ptTemp.x, ptTemp.y);            
            break;
          }
        }     
     DeleteObject(PenStyle);    
     }

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
     {
     static int  cxClient, cyClient ;
     HDC         hdc,hdcMem ;
     PAINTSTRUCT ps ;
     HANDLE     hBitmap, hOldBitmap;
     BITMAP         Bitmap;
     RECT         Rect;
     POINT         FirstBlackPoint, pt;


     switch(iMsg)
     {
            case WM_SIZE:
                cxClient = LOWORD(lParam);
                cyClient = HIWORD(lParam);
             return 0;

            case WM_PAINT:
                //Загружаем рисунок из файла
                //=============================================================
                hdc = BeginPaint(hwnd, &ps);
                hBitmap = LoadImage(NULL,"dogs.bmp",IMAGE_BITMAP,
                                    0, 0, LR_LOADFROMFILE);
                GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
                hdcMem = CreateCompatibleDC(hdc);
                hOldBitmap = SelectObject(hdcMem,hBitmap);
                GetClientRect(hwnd,&Rect);
                StretchBlt(hdc, 0, 0, Rect.right, Rect.bottom,
                            hdcMem, 0, 0, Bitmap.bmWidth, 
                            Bitmap.bmHeight, SRCCOPY);
                SelectObject(hdcMem,hOldBitmap);
                DeleteObject(hBitmap);
                DeleteDC(hdcMem);
                //==============================================================
                //Получаепм первую черную точку
                FirstBlackPoint = SearthFirstPixel(hdc, cxClient, cyClient);
                //Задаем радиус
                pt.x = 0;
                pt.y = 200;
                //Строим первую линию
                GoClock (hdc, pt, FirstBlackPoint);
                EndPaint(hwnd,&ps);
                return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
     }



PM MAIL   Вверх
Fixin
Дата 8.3.2006, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Во-первых, причем здесь раздел по апи?
Во-вторых,
Цитата(colaa @ 8.3.2006, 17:10 Найти цитируемый пост)
дальше нужно чтобы начало координат перемещалось в точку Б, также сканировалась следующая окружность, находилась точка В И строилась бы линия от Б к В, и так до конца
Ты сам описал все, что нужно. Тоько учитывай, чтобы следующая точка не совпала с предыдущей, те не иди назад.

ЗЫ: конкурс - кто знает, куда эту тему отнести? в центр?

PM MAIL ICQ   Вверх
colaa
Дата 8.3.2006, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



С циклом разобрался
Осталось как раз это
Цитата

Ты сам описал все, что нужно. Тоько учитывай, чтобы следующая точка не совпала с предыдущей, те не иди назад.

Например если А(0;0) - начало координат, а Б - точка к которой проводится линия, например Б(-15;10), то при следующем цикле уже Б(0;0) - начало координат, а вот А - точка которая должна исключаться из дуги, чтобы к ней не шла линия опять,
и как я понимаю она должна быть равна А(15;-10) (координаты обратные Б в предыдущем цикле), все так и описал но все равно не выходит, что делать?

Цитата

ЗЫ: конкурс - кто знает, куда эту тему отнести? в центр?

создам еще в общих тему
PM MAIL   Вверх
Fixin
Дата 8.3.2006, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Цитата(colaa @ 8.3.2006, 20:07 Найти цитируемый пост)
создам еще в общих тему
Не стоит - за дубли получишь.

Зачем ты вообще оси переносишь? считай все в одних осях, проще будет. Ты же рисунок анализируешь (хотя и смешным и мутным способом, но достаточно простым), а в нем все координаты положительные, все просто. Ты график ф-ции анализируешь? Тогда просто запоминай координаты предыдущей точки и все, ведь график - линия.

PM MAIL ICQ   Вверх
colaa
Дата 9.3.2006, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



Fixin,
Спасибо тебе,
Цитата

Не стоит - за дубли получишь.

Блин, теперь не знаю как удалить, там только редактирование
Цитата

Зачем ты вообще оси переносишь? считай все в одних осях, проще будет. Ты же рисунок анализируешь (хотя и смешным и мутным способом, но достаточно простым), а в нем все координаты положительные, все просто.

Я так и хотел сначала без координат, только не понял как модифицировать уравнение круга, не подскажешь?
Код

   ptTemp.x = (int) (pt.x * cos (TWOPI * j / 360) +
                            pt.y * sin (TWOPI * j / 360)) ;

          ptTemp.y = (int) (pt.y * cos (TWOPI * j / 360) -
                            pt.x * sin (TWOPI * j / 360)) ;

Цитата

Ты график ф-ции анализируешь? Тогда просто запоминай координаты предыдущей точки и все, ведь график - линия.

Потом я просто считаю количество отрезков и умножаю на их длину
PM MAIL   Вверх
Fixin
Дата 9.3.2006, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Цитата(colaa @ 9.3.2006, 00:16 Найти цитируемый пост)
не знаю как удалить
Нажми кнопку "репорт" и напиши модератору.

Я бы взялся за векторы с направлением, противоположным "движению по линии". Для этого, нужно искать первые две точки (по ним строить первый вектор) и продолжать.

Какова цель проги? Нынешний метод ее решения весьма нерационален и неоптимален...

Переношу в "центр помощи".

PM MAIL ICQ   Вверх
Fixin
Дата 9.3.2006, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Для домашних заданий, курсовых, существует "Центр Помощи"
PM MAIL ICQ   Вверх
colaa
Дата 9.3.2006, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



Цитата

Какова цель проги?

Цель измерить кривую одинаковыми отрезками с заданной длиной
Потом умножаем количество отрезков на их длину получаем длину кривой
И так несколько раз с разной длиной отрезка
Дальше строим график X - длина отрезка, Y - длина кривой

Это на самом деле моя первая прога, поэтому и такие методы
Цитата

Нынешний метод ее решения весьма нерационален и неоптимален...

Напиши пожалуйста как лучше сделать, как оптимально?
PM MAIL   Вверх
Fixin
Дата 9.3.2006, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Цитата(colaa @ 9.3.2006, 19:36 Найти цитируемый пост)
моя первая прога
ТОгда все путем. Главное - результат. опыт придет. Я думаю, стоит подождать мнения других участников.

PM MAIL ICQ   Вверх
colaa
Дата 9.3.2006, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



Вот написал за вечер совсем по другому, уже без перестановки координат, теперь работает, но
Вопрос
У меня функция NumBlackPoints возвращает количество точек на кривой
Я не знаю как после этого создать массив точек как раз для этого количества, сейчас он у меня фиксированный, на 10000 точек

Код

#include <windows.h>

POINT        Tex[10000];

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
//////////////////////////////////////////////////////////////////////////////////////
}

 POINT SearthFirstPixel(HDC hdc, int cxClient, int cyClient)
{
////////////////////////////////////////////////////////////////////////////////////
}

int NumBlackPoints(HDC hdc, POINT FirstPoint)
{
    int            summa = 0;
    int            x, y, i;
    COLORREF    BlackPixel;

    x = FirstPoint.x;
    y = FirstPoint.y;
    BlackPixel = RGB(0,0,0);
    SetPixel(hdc, x, y, RGB(0,0,255) );

    for(i = 0; i < 10000; i++)
    {

    if (BlackPixel == GetPixel(hdc, x + 1, y - 1)  )
    {
        x = x +1;
        y = y -1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x + 1, y)  )
    { 
        x = x + 1;
        y = y;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x + 1, y + 1)  )
    { 
        x = x + 1;
        y = y + 1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x, y - 1)  )
    { 
        x = x;
        y = y - 1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x, y + 1)  )
    { 
        x = x;
        y = y + 1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x - 1, y - 1)  )
    { 
        x = x - 1;
        y = y - 1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    if(BlackPixel == GetPixel(hdc, x - 1, y)  )
    { 
        x = x - 1;
        y = y;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }    
    if(BlackPixel == GetPixel(hdc, x - 1, y + 1)  )
    { 
        x = x - 1;
        y = y + 1;
        summa = summa + 1;
        SetPixel(hdc, x, y, RGB(0,0,255) ); continue;
    }
    break;
    }
    return summa;
}

void Video(HDC hdc, int Summa, int Radius, POINT FirstPoint)
{
//////////////////////////////////////////////////////////////////////////////////
}
int    Krugi(HDC hdc, POINT FirstPoint, int Radius)
{
//////////////////////////////////////////////////////////////////////////////////
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
     {
     static int  cxClient, cyClient ;
     HDC         hdc, hdcMem ;
     PAINTSTRUCT ps ;
     HANDLE         hBitmap, hOldBitmap;
     BITMAP         Bitmap;
     RECT         Rect, TextRect;
     POINT         FirstBlackPoint;
     int         Summa, Radius, Num;
     char         Stroka[120];
     

     switch(iMsg)
     {
            case WM_SIZE:
                cxClient = LOWORD(lParam);
                cyClient = HIWORD(lParam);
             return 0;

            case WM_PAINT:
                //Çàãðóæàåì ðèñóíîê èç ôàéëà
                //=============================================================
                hdc = BeginPaint(hwnd, &ps);
                hBitmap = LoadImage(NULL,"dogs.bmp",IMAGE_BITMAP,
                                    0, 0, LR_LOADFROMFILE);
                GetObject(hBitmap,sizeof(BITMAP),&Bitmap);
                hdcMem = CreateCompatibleDC(hdc);
                hOldBitmap = SelectObject(hdcMem,hBitmap);
                GetClientRect(hwnd,&Rect);
                StretchBlt(hdc, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight,
                            hdcMem, 0, 0, Bitmap.bmWidth, 
                            Bitmap.bmHeight, SRCCOPY);
                SelectObject(hdcMem,hOldBitmap);
                DeleteObject(hBitmap);
                DeleteDC(hdcMem);
                //==============================================================
                //Ïîëó÷àåïì ïåðâóþ ÷åðíóþ òî÷êó
                FirstBlackPoint = SearthFirstPixel(hdc, cxClient, cyClient);
                Summa = NumBlackPoints(hdc, FirstBlackPoint);
                Radius = 45;
                Video(hdc, Summa, Radius, FirstBlackPoint);
                Num = Krugi(hdc, FirstBlackPoint, Radius);
                wsprintf(Stroka, " %s%d\n %s%d\n %s%d ","Ðàçìåð îòðåçêà = ", Radius,
                                "Êîëè÷åñòâî îòðåçêîâ = ", Num, "Îáùàÿ äëèíà = ", Radius*Num);    
                SetRect(&TextRect,0,0, 400,200);
                DrawText(hdc, Stroka, -1, &TextRect, DT_LEFT);
                EndPaint(hwnd,&ps);
                
                
            


            EndPaint(hwnd,&ps);
                return 0 ;

          case WM_DESTROY:
               PostQuitMessage (0) ;
               return 0 ;
          }

     return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
     }



Это сообщение отредактировал(а) Fixin - 10.3.2006, 20:57
PM MAIL   Вверх
Fixin
Дата 10.3.2006, 21:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 5
Всего: 18



Модератор: Когда код окаймляешь тегами, выбирай язык.
Цитата(colaa @ 9.3.2006, 23:55 Найти цитируемый пост)
Я не знаю как после этого создать массив точек как раз для этого количества
Почитай про динамические массивы. Алгоритм:
Код

1 Создаешь массив из К елементов
2 Заполняешь его. Если заполняешь данное количество элементов 
    а) создаешь массив из (текущее_количество+К) элементов
    б) копируешь туда старые данные
    в) добавляешь новые
    г) удаляешь старый масив и на его место вставляешь новый.

Сделай отдельную функцию для всатвки элементов, возвращающую новый указатель на массив, а принимающая старый и новый элемент. Делайтак:
Код

POINT* PointMassive;
POINT CurPoint;
int count = 0;
for (int i = 0; i < 10; i++)
{
    PointMassive = AddPoint(PointMassive, CurPoint); //пример использования
    count++;
}

Добавлено @ 21:06
count - колво элементов.
PM MAIL ICQ   Вверх
colaa
Дата 12.3.2006, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 12.2.2006

Репутация: нет
Всего: нет



Спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0571 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.