Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.07.20;
Скачать: CL | DM;

Вниз

Как перетащить круг в Canvas е   Найти похожие ветки 

 
ice-hammer   (2007-11-18 20:54) [0]

У меня есть объект TCircle, который умеет рисоваться на канве в виде окружности.
Необходимо уметь перетаскивать этот круг с одного места в другое, перед этим выделив именно его(желательно по клику мышки). Главный вопрос в том, как его выделить? Ведь объект не визуальный.
Тупое, муторное решение : подставлять координаты клика (x,y) в уравнение окружности этого объекта, (x-x0)^2+(y-y0)^2<=r^2 - если удовлетворяет, то делаем вывод, что мы кликнули на круг, выделяем его(вручную), и после этого перетаскиваем(тоже вручную, перерисовываем в новое место). Больше ничего в голову не пришло, может у Вас есть идеи?


 
boa_kaa ©   (2007-11-18 21:05) [1]


> Тупое, муторное решение

и единственно верное


 
ice-hammer   (2007-11-18 21:23) [2]

Жаль


 
boa_kaa ©   (2007-11-19 08:29) [3]

В качестве варианта для ускорения могу предложить вычислять попадние точки в описанный вокруг круга квадрат. Если попадает в квадрат, то уже проводить вычисления для круга.


 
Leonid Troyanovsky ©   (2007-11-19 09:09) [4]


> boa_kaa ©   (19.11.07 08:29) [3]

Примерно тоже можно было б предложить про само рисование,
т.е., нужен круг, вписанный в квадрат, и квадратная маска
с круглой дыркой.

Ну, а сами вычисления ускорятся не намного.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2007-11-19 09:15) [5]

> Leonid Troyanovsky  (19.11.2007 09:09:04)  [4]

Или удвоятся, по статистике N*1.41


 
Leonid Troyanovsky ©   (2007-11-19 10:10) [6]


> Anatoly Podgoretsky ©   (19.11.07 09:15) [5]

Для статистики еще потребуется знать отношение
площадей квадрата и формы. Или экрана :)

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2007-11-19 10:13) [7]

> Leonid Troyanovsky  (19.11.2007 10:10:06)  [6]

Не важно, понятно, что ускорение будет только в случае промаха, а в остальных случаях пенальти.


 
easy ©   (2007-11-19 10:16) [8]

http://www.dfc.com.ru/?sid=2&id=18&itemid=44


 
boa_kaa ©   (2007-11-19 10:17) [9]


> Leonid Troyanovsky ©   (19.11.07 09:09) [4]

> Anatoly Podgoretsky ©   (19.11.07 09:15) [5]

В нормальном случае, когда на канве один объект и обрабатывается по клику мышки, можно и не делать так. В случае, если объектов много, или если нужно проводить вычисления при движении, то желательно локализовать область. Самое простое - это описывающий квадрат.

Попадание в него можно проверить с помощью четырех опереций сравнений. Дело ускорится, если ограничивающий квадрат вычислить заранее.

> Или удвоятся, по статистике N*1.41

Анатолий, я могу легко доказать, что это не так. Количество вычислений уменьшится. Причем с уменьшением относительного  размера круга, будет только меньше. И даже не в 2 раза.

Просто Вам, видимо, не приходилось, или не достаточно приходилось, иметь дело с графическими алгоритмами, когда на счета каждое лишнее действие. Не сочтите за грубость.


 
Anatoly Podgoretsky ©   (2007-11-19 10:23) [10]

> boa_kaa  (19.11.2007 10:17:09)  [9]

Да не хочу я спорить, только хочу заметить, что на канве нет объектов.
А это резко меняет ситуацию.


 
boa_kaa ©   (2007-11-19 10:55) [11]


> Anatoly Podgoretsky ©   (19.11.07 10:23) [10]

Не важно, он все равно меньше, чем канва


 
Anatoly Podgoretsky ©   (2007-11-19 11:01) [12]

Не знаю кто меньше, но работа с объектом позволит отойти от сложных расчетов, для формулы круга к сравнению с радиусом.


 
boa_kaa ©   (2007-11-19 11:07) [13]


> Anatoly Podgoretsky ©   (19.11.07 11:01) [12]
> Не знаю кто меньше, но работа с объектом позволит отойти
> от сложных расчетов, для формулы круга к сравнению с радиусом.

Не совсем понял, о работе с каким объектом идет речь? Если про круг, так я и предлагаю уменьшить ОБЩИЙ объем вычислений.


 
Anatoly Podgoretsky ©   (2007-11-19 11:27) [14]

> boa_kaa  (19.11.2007 11:07:13)  [13]

Откуда круги на канве? Там же только точки. А объект TCircle и видимо есть список объектов, иначе для одного и говорить то практически не о чем.


 
boa_kaa ©   (2007-11-19 12:10) [15]

Пока ребенка укачивал, накатал тестирующий модуль :)

unit Circle;

interface

uses Windows;

type

TCircle = class
private
 SqrR: Integer;
 Bounds: TRect;
public
 // не будет усложнять все свойствами
 X0: Integer;
 Y0: Integer;
 R: Integer;

 constructor Create(AX, AY, AR: Integer);
 function PointInCircle1(AX, AY: Integer): Boolean;
 function PointInCircle2(AX, AY: Integer): Boolean;
end;

implementation

uses Types;

constructor TCircle.Create(AX, AY, AR: Integer);
var
 r2: Integer;
begin
 X0:=AX;
 Y0:=AY;
 R:= AR;
 SqrR := R * R;
 r2 := Trunc(R/2) + 1;
 Bounds.Left := X0 - r2;
 Bounds.Right := X0 + r2;
 Bounds.Top := Y0 - r2;
 Bounds.Bottom := Y0 + r2;
end;

// вычисляем напрямик
function TCircle.PointInCircle1(AX, AY: Integer): Boolean;
begin
 Result := Sqr(AX-X0)+Sqr(AY-Y0) <= SqrR;
end;

function TCircle.PointInCircle2(AX, AY: Integer): Boolean;
begin
 if ((Bounds.Left <= AX) and (AX <= Bounds.Right) and
     (Bounds.Top <= AY) and (AY <= Bounds.Bottom)) then
    // можно попробовать и так и так
    Result := Sqr(AX-X0)+Sqr(AY-Y0) <= SqrR //PointInCircle1(AX, AY)
 else
   Result := false;
end;

end.


Размер канвы выбрал 100x100.

Снимаю шляпу и ем :) Разница составила не более 15% для круга любого диаметра. Но все-таки в сторону второго метода :) Та же репка с вещественной арифметикой.

Так что заниматься оптимизацией в данном случае нет смысла.


 
ice-hammer   (2007-11-19 22:10) [16]

Спасибо за предоставленные исследования по оптимизации. ))
Вчера я сделал через попадание в круг, а не в квадрат, скорее всего так и оставлю.

> А объект TCircle и видимо есть список объектов

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

> Да не хочу я спорить, только хочу заметить, что на канве
> нет объектов.

Нету, они только рисуются, выделяются, стираются и переносятся на канве

Вот код:

TCircle=Class(Telement)
     pnt:Tpoint;
     image:TImage;
     index:word;
     R:TRect;
     Procedure Draw;
     Constructor Create(pnt0:Tpoint;image0:TImage;index0:word);
     Destructor Destroy;
     Function Select(move_point0:Tpoint):boolean;
     Procedure Allocation;
    end;

От ТElement наследуются все графические объекты



Страницы: 1 вся ветка

Текущий архив: 2008.07.20;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.02 c
11-1191827466
Nikfel
2007-10-08 11:11
2008.07.20
Получить список файлов и папок.


2-1213780489
lewka-serdceed
2008-06-18 13:14
2008.07.20
Выделение в ListBox


1-1195232021
wipr
2007-11-16 19:53
2008.07.20
Окно программы становится недоступным (программа не отвечает)


15-1212254418
wl
2008-05-31 21:20
2008.07.20
Валерий Фаронов. Delphi 2005. Руководство по переходу с...


2-1213795339
TUserClass
2008-06-18 17:22
2008.07.20
Даже не знаю как тему обозвать ... )))