Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.08.2015, 14:21   #1
Sanscrit
Пользователь
 
Регистрация: 23.03.2015
Сообщений: 24
Радость Любой язык. Движение в случайном направлении.

Приветствую!
Собственно сабж: есть поле, на котором в определенных точках появляются объекты (шарики), соответственно у них есть координаты х и у, заданные изначально. Вот я не могу сообразить, какую функцию можно использовать, чтобы шарики двигались в случайно заданном направлении, так же случайно меняя направление движения через некоторое время.
Собственно сам код не нужен, нужен алгоритм движения на любом языке, дальше сам разберусь.
Пока что шарик или катается туда-сюда (при использовании синуса) или прыгает туда-сюда, постепенно продвигаясь в одном направлении (при использовании рандомных чисел).
Sanscrit вне форума Ответить с цитированием
Старый 31.08.2015, 14:34   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я бы сделал шары объектом. Задавал случайно (x,y) точки назначения, и навесил бы событие на достижение этой точки, которое бы генерировало новую точку случайным образом и запускало механизм движения.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 31.08.2015, 15:35   #3
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,899
По умолчанию

Задавать случайно точку назначения не совсем корректно - одна из координат должна повторять координату точки, на которой стоим сейчас, если движение только по ортогоналям, а если ещё и по диагоналям, то генерировать случайно надо не точку а две дельты координат с одной длиной, иначе же путь движения по клеткам придётся рассчитывать ещё по , например, алгоритму Брезенхема.
Я бы предложил немного другой вариант:
на старте и на событии смены движения выбираем случайно либо длину либо направление (в зависимости от того, какую модель хотим приоретизировать), если длину, то можно сразу предусмотреть невыход за границы поля, отсеивая недоступные направления, если же направление, то бросать случайное число ходов в данном направлении, опять же с учётом невыхода за границы поля. На втором шаге рандомизируем то, что не выбрали на первом шаге - дальность или направление.
Как выбирать направление - я предлагаю оператором выбора, требуется одна вводная для такого алгоритма - только ортогонали или ещё и диагонали надо (ещё есть редкий вариант - только диагонали, кстати). Рассмотрим общий (все направления) - кидаем от целое 0 до 1 - выбираем первичную координату (тоже зависит от желаемой модели, можно и зафиксировать, что хотим сперва х или у), этот приём просто позволит не перебрасывать случчисло, если выпадет 0\0. На выбранную первичную координату кидаем целое от -1 до 1 (0-2), в случае 0 на вторую кидаем на -1 или на 1 (0-1) , иначе тоже от -1 до 1. (для только ортогоналей ислючаем вариант когда дельты одновременно 0 или одновременно не ноль)
В итоге получаем две дельты координат, их запоминаем со счётчиком ходов (дальности), запоминаем в структуру\объект, и каждый ход двигаем шарик на эти дельты, уменьшая счетчик, на 0 счетчика снова производим расчёт.
Случайно число кидать стандартными функциями языка, учитывая какой диапазон нужен, и обрабатываем, например вычитать единицу, или для варианта -1 или 1 можно (0 или 1)*2-1

Последний раз редактировалось phomm; 31.08.2015 в 15:37.
phomm вне форума Ответить с цитированием
Старый 31.08.2015, 17:36   #4
ResourceSpace
Форумчанин
 
Аватар для ResourceSpace
 
Регистрация: 30.06.2015
Сообщений: 353
По умолчанию

Код:
double xStart, yStart, xCurr, yCurr, xEnd, yEnd, speed;

changeTrack(){xStart=xCurr; yStart=yCurr; xEnd=random(); yEnd=random();}
move(){if ((xCurr==xEnd && yCurr==yEnd) || ...) changeTrack(); xCurr=...; yCurr=...;}
Достаточно? Сами додумаете?
ResourceSpace вне форума Ответить с цитированием
Старый 01.09.2015, 11:45   #5
8Observer8
Старожил
 
Регистрация: 02.01.2011
Сообщений: 3,328
По умолчанию

Проще, быстрее и безопаснее (в плане ошибок) сделать с применением физического движка. Например, я сделал на игровом движке Unity, который использует физический движок PhysX от NVIDIA.

Сделал быстро:
- добавил шариков
- растянул квадраты, чтобы сделать границы
- поставил гравитацию в ноль
- написал скрипт на C#, который висит на каждом шарике и меняет ему компоненты вектора скорости на случайную величину: [1, 10], через случайное время: [2, 10] секунд.


Последний раз редактировалось 8Observer8; 01.09.2015 в 15:03.
8Observer8 вне форума Ответить с цитированием
Старый 01.09.2015, 21:29   #6
tolikprankster
Пользователь
 
Регистрация: 09.02.2013
Сообщений: 60
По умолчанию

Генерируешь число от 0 до 360 - вот тебе и направление.
Чтоб менять направление делаешь таймер(например каждые 2 секунды), также таймер тоже можно реализовать через рандомное значение(чтоб каждый раз был новый интервал), например: от 3 до 7 секунд)
Или можно завести отдельную переменную, которая инкрементится когда шарик перемещается и проверку типа:
если а > 100 (метод перемещения вызвался больше сто раз)
тогда:
{
а = 0
генерируем новый угол
}
tolikprankster вне форума Ответить с цитированием
Старый 02.09.2015, 10:12   #7
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

x, y натуральные или вещественные?

Если x,y натуральные, то решение такое

Код:
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")

#define _E 2.71828182845
#define _PI 3.14159265359
#define EPS 0.01

struct point1
{
int x;
int y;
struct point1* next;

point1() { x = 0; y = 0; next = 0; }
point1(int a1, int a2) { x = a1; y = a2; next = 0; }
void add_next() { struct point1* i = this; while(i->next) i=i->next; i->next = new point1(); }
void add_next(int a1, int a2) { struct point1* i = this; while(i->next) i=i->next; i->next = new point1(a1,a2); }
};

struct point1* first = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; 
HPEN hpen1; 
int rx, ry; 
struct point1* i; 
int nx, ny; 
int angle; 
float fangle; 
float frad; 
static int limit = 5; 
static int climit = 0;
int sx, sy, tx, ty;


switch (uMsg)
{
case WM_DESTROY: PostQuitMessage(NULL); return 0;
case WM_PAINT: 
hdc = GetDC(hwnd); 
hpen1 = CreatePen(PS_SOLID, 1, RGB(255, 255, 128)); 
rx = rand()%300;   
ry = rand()%300; 
angle = rand()%360; 
fangle = (float)angle; 
frad = fangle * (_PI / 180.0);

if (climit < limit) { if (first) { first->add_next(rx, ry);} else { first = new point1(rx, ry); } climit++; }
i = first; while(i) { SetPixel(hdc,i->x,i->y,RGB(0,0,255)); SetPixel(hdc,i->x,i->y+1,RGB(0,0,255)); SetPixel(hdc,i->x,i->y-1,RGB(0,0,255)); SetPixel(hdc,i->x+1,i->y,RGB(0,0,255)); SetPixel(hdc,i->x-1,i->y,RGB(0,0,255)); i = i->next; }

i = first; 
while(i) 
{ 
sx = rand()%2;
sy = rand()%2;

tx = rand()%2;
ty = rand()%2;

if (tx == 0) { i->x += sx; } else  { i->x -= sx; } 
if (ty == 0) { i->y += sy; } else  { i->y -= sy; } 

i = i->next; 
}

ReleaseDC(hwnd, hdc);
DeleteObject(hpen1);

return 0;
default: return DefWindowProc(hwnd, uMsg,wParam, lParam);
}

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

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR CmdLine, int CmdShow) { WNDCLASSEX wc; MSG msg; HWND hwnd; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hInstance = hInst; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName =  "SimpleWinClass"; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm =LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); RegisterClassEx(&wc); hwnd = CreateWindowEx(NULL, "SimpleWinClass", "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,  NULL, NULL, hInst, NULL); ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
int main(int argc, char* argv[]) { srand(time(0)); HINSTANCE hInstance = GetModuleHandle(0); LPSTR CommandLine = GetCommandLine(); return WinMain(hInstance, NULL,CommandLine, SW_SHOWDEFAULT); }
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 02.09.2015, 10:13   #8
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

Если x,y вещественные, то решение такое
Код:
#include <windows.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")

#define _E 2.71828182845
#define _PI 3.14159265359
#define EPS 0.01

struct point1
{
int x;
int y;
struct point1* next;

point1() { x = 0; y = 0; next = 0; }
point1(int a1, int a2) { x = a1; y = a2; next = 0; }
void add_next() { struct point1* i = this; while(i->next) i=i->next; i->next = new point1(); }
void add_next(int a1, int a2) { struct point1* i = this; while(i->next) i=i->next; i->next = new point1(a1,a2); }
};

struct point1* first = 0;

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc; // контекст рисования
HPEN hpen1; // перо
struct point1* i; // итератор точек
int angle; // натуральный угол в градусах принадлежит множеству N
double fangle; // угол angle в градусах принадлежит множеству R
double frad; // угол в радианах
static int limit = 5; // количество точек
static int climit = 0; // текущее количество заданных точек
int rx, ry; // случайные числа
double r, a, b; // радиус окружности и два катета
int num; // номер точки
double sx, sy, ux, uy;
int nangle;

switch (uMsg)
{
case WM_DESTROY: PostQuitMessage(NULL); return 0;
case WM_PAINT: hdc = GetDC(hwnd); hpen1 = CreatePen(PS_SOLID, 1, RGB(255, 255, 128)); rx = rand()%900; ry = rand()%900; 
if (climit < limit) { if (first) { first->add_next(rx, ry);} else { first = new point1(rx, ry); } climit++; }
i = first; while(i) { printf("point %x \n", i);SetPixel(hdc,i->x,i->y,RGB(0,0,255)); SetPixel(hdc,i->x,i->y+1,RGB(0,0,255)); SetPixel(hdc,i->x,i->y-1,RGB(0,0,255)); SetPixel(hdc,i->x+1,i->y,RGB(0,0,255)); SetPixel(hdc,i->x-1,i->y,RGB(0,0,255)); i = i->next; }

num = 0; 
i = first; 
while(i) 
{ 
printf("point %x \n", i); // номер точки
angle = rand()%360; // случайный угол от 0 до 360 градусов // Угол выбирается для каждой точки 

if (angle >= 0 && angle <= 90) { nangle = angle; }
else if (angle > 90 && angle <= 180) { nangle = angle - 90; }
else if (angle > 180 && angle <= 270) { nangle = angle - 180;}
else if (angle > 270 && angle <= 360) { nangle = angle - 270; }

fangle = (double) nangle; // преобразованный в вещественный угол от 0 до 360 градусов
frad = fangle * (_PI / 180.0); // преобразованный из градусов в радианы угол

r = 3.0;
a = sin(frad)*r; 
b = cos(frad)*r; 

if (angle >= 0 && angle <= 90) { a = -a; b = b; }
else if (angle > 90 && angle <= 180) { a = -a; b = -b; }
else if (angle > 180 && angle <= 270) { a = a; b = -b;}
else if (angle > 270 && angle <= 360) { a = a; b = b; }

printf("%d : %d %d %f %f ", num, i->x, i->y, a, b);

if (angle >= 0 && angle <= 90) { i->x += b;  i->y += a; }
else if (angle > 90 && angle <= 180) { i->x += a; i->y += b;}
else if (angle > 180 && angle <= 270) { i->x += b; i->y += a;}
else if (angle > 270 && angle <= 360) { i->x += a; i->y += b;}

printf("%d %d %d \n", i->x, i->y, angle);

num++;

i = i->next; // переход к следующей точке
}

ReleaseDC(hwnd, hdc); DeleteObject(hpen1); return 0;
default: return DefWindowProc(hwnd, uMsg,wParam, lParam);
}

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

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR CmdLine, int CmdShow) { WNDCLASSEX wc; MSG msg; HWND hwnd; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = NULL; wc.cbWndExtra = NULL; wc.hInstance = hInst; wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName =  "SimpleWinClass"; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hIconSm =LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); RegisterClassEx(&wc); hwnd = CreateWindowEx(NULL, "SimpleWinClass", "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,  NULL, NULL, hInst, NULL); ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
int main(int argc, char* argv[]) { srand(time(0)); HINSTANCE hInstance = GetModuleHandle(0); LPSTR CommandLine = GetCommandLine(); return WinMain(hInstance, NULL,CommandLine, SW_SHOWDEFAULT); }
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Старый 02.09.2015, 10:25   #9
challengerr
Участник клуба
 
Аватар для challengerr
 
Регистрация: 30.07.2008
Сообщений: 1,609
По умолчанию

Строить алгоритмы без проверки в программе, я не умею.
Алгоритмы на псевдокоде же пишутся.
Если почитаете книгу "дискретная математика для программиста" Новикова, то увидите, что там используется псевдокод для описания алгоритма.
То есть реальный код это способ описания алгоритма.
А чем реальный код хуже псевдокода?

В winapi система координат целочисленная. Вещественная модель может потребоваться в компьютерных играх или в двухмерной графике. Дано: точка с координатами x, y, угол alpha [0,360]. Задача: переместить точку в направлении луча, определяемого углом alpha.

Что за угол alpha? Каким образом отсчитывается угол alpha? Что является нулевым углом alpha?
Построить систему координат. Центр системы координат - точка x, y.
Каким образом задаются оси Ox, Oy системы координат, нулем которой является точка x,y относительно системы координат окна OX, OY?
Пусть OX, OY - система координат окна. Пусть Ox, Oy - новая система координат, относительно которой будет отсчитываться угол alpha.
Какие векторы определяют оси Ox, Oy новой системы координат относительно системы координат OX, OY?
Если длина вектора оси Ox имеет единичный размер
(0, 0) в (Ox, Oy) отображается в (x,y) в (OX, OY)
(0, 1) в (Ox, Oy) отображается в (x,y-1) в (OX, OY) // вектор (0, 1)
(1, 0) в (Ox, Oy) отображается в (x+1,y) в (OX, OY) // вектор (1, 0)
Угол alpha отсчитывается от положительного направления оси Ox в направлении оси Oy. Нулевой угол alpha - ось Ox.

Если рассматриваем единичную окружность, то один катет будет sin(alpha), а другой катет будет cos(alpha). При использовании gdi координатная сетка целочисленная, поэтому производится округление до целой части вверх или вниз.

sin(alpha) и cos(alpha) это координаты перемещения изначально заданной точки.

Длину гипотенузы берем произвольно, тогда один катет будет равен r* sin(alpha), а другой r*cos(alpha).
"SPACE.THE FINAL FRONTIER.This's a voyage of starship Enterprise. It's 5-year mission to explore strange new worlds,to seek out new life and civilizations,to boldly go where no man has gone before"
challengerr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Движение картинки по форме при нажатии клавиши (любой) mihaillo Общие вопросы Delphi 3 04.03.2018 19:18
Актуальный язык программирования или в каком направлении развиваться cristianoman Свободное общение 11 09.06.2014 00:12
Программа кластеризации ( язык любой) Payten Фриланс 0 12.05.2014 08:46
решить задачу, используя любой алгоритм и любой язык программирования oncheva Помощь студентам 0 24.12.2012 18:07
Интересная задача, реализация временных логик (любой логики), язык любой. Flyym Помощь студентам 1 05.01.2011 03:10