Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 036

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Написал код по перетаскиванию графика функции мышью, но перетаскивается некорректно и с мерцанием помогите от этого избавиться прилагаю полный код:

Приложение:
  1. unit Unit3;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, StdCtrls, ExtCtrls, math;
  8.  
  9. type
  10. TForm3 = class(TForm)
  11. Button1: TButton;
  12. Image1: TPaintBox;
  13. procedure Button1Click(Sender: TObject);
  14. procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
  15. Shift: TShiftState; X, Y: Integer);
  16. procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
  17. Shift: TShiftState; X, Y: Integer);
  18. procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  19. Y: Integer);
  20. private
  21. { Private declarations }
  22. public
  23. { Public declarations }
  24. end;
  25.  
  26. var
  27. Form3: TForm3;
  28. Xmax,Xmin,Ymax,Ymin:real;
  29. b:boolean;
  30. vx,vy:integer;
  31.  
  32. implementation
  33.  
  34. {$R *.dfm}
  35.  
  36. Function DrawSin(x1:real; var Xmax,Xmin,Ymax,Ymin:real):Real;
  37. begin
  38. DrawSin:=Cos(X1);
  39. Xmax:=pi;
  40. Xmin:=-pi;
  41. Ymax:=pi;
  42. Ymin:=-pi;
  43. end;
  44.  
  45. procedure TForm3.Button1Click(Sender: TObject);
  46. var X1,Y:real;
  47. px,py:LongInt;
  48. begin
  49. image1.Canvas.FillRect(rect(0,0,width,height));
  50. for PX:=1 to Image1.Width do
  51. begin
  52. X1:=Xmin+PX*(Xmax-Xmin)/(Image1.Width)-2*vx*pi/500;
  53. Y:=DrawSin(X1,Xmax,Xmin,Ymax,Ymin)-2*vy*pi/500;
  54. PY:=trunc((Image1.Height)-(Y-Ymin)*(Image1.height)/(Ymax-Ymin));
  55. image1.Canvas.Pixels[PX,PY]:=clBlack;
  56. end;
  57. end;
  58.  
  59. procedure TForm3.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  60. Shift: TShiftState; X, Y: Integer);
  61. begin
  62. b:=true;
  63. vx:=x;
  64. vy:=y;
  65. end;
  66.  
  67. procedure TForm3.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  68. Y: Integer);
  69. var rx,ry:Integer;
  70. begin
  71. rx:=x;
  72. ry:=y;
  73. if b = true then
  74. begin
  75. vx:=rx-vx;
  76. vy:=ry-vy;
  77. Button1Click(Sender);
  78. end;
  79. if b = false then
  80. begin
  81. exit;
  82. end;
  83. end;
  84.  
  85. procedure TForm3.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  86. Shift: TShiftState; X, Y: Integer);
  87. begin
  88. b:=False;
  89. vx:=0;
  90. vy:=0;
  91. end;
  92.  
  93. end.


ierihon1 Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: ierihon1 (статус: 1-ый класс)
Вопрос отправлен: 20 февраля 2011, 10:23
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, ierihon1!
Просмотрел бегло Ваш код - классическая проблема. Мерцания возникают потому, что изображение перерисовывается много-много раз.
А учитывая то, что метод установки цвета конкретного пискеля очень медленный, это ещё больше замедляет код.
Что бы ничего не мерцало и рисовалось красиво, нужно рисовать картинку в памяти, а потом в нужный момент копировать готовую на экран.

Для этого вначале заводим себе TBitmap, нужно размера, на котором рисуем картинку. Когда вся картинка готова, методом Draw переносим ее по назначению. Но перенос делается в методе OnPaint нужного компонента. Так как Windows не знает, когда рисовать, то можно вызывать методо Repaint или Refresh по окончанию прорисовки картинки на TBitmap.

Читайте статью тут http://www.beluch.ru/progr/100comp/4_2.htm и немного тут http://forums.overclockers.ru/viewtopic.php?f=28&t=44662&start=600

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 20 февраля 2011, 17:04
Оценка за ответ: 5

Комментарий к оценке: хех о чём я думал) спасибо)

Мини-форум вопроса

Всего сообщений: 2; последнее сообщение — 20 февраля 2011, 20:31; участников в обсуждении: 2.
Amidamaru

Amidamaru (статус: 4-ый класс), 20 февраля 2011, 17:30 [#1]:

очень интересный способ, я правда делал проще, хотя не знаю насколько это эффективно в плане скорости:
установить ParentBackGround:=false; и DoubleBuffered:=true; (второе можно установить только во время выполнения, т.е. в коде), если не получиться на форме (хотя должно получиться), ставишь панельку на всю форму, на неё уже нужные компоненты, и устанавливаешь эти свойства для неё, а не для формы.
Приглашаю Вас на наш IRC-канал: #delphiintru в сети DalNet.
ierihon1

ierihon1 (статус: 1-ый класс), 20 февраля 2011, 20:31 [#2]:

Amidamaru: ну с мерцанием можно сказать разобрался но график всё равно через пень колоду отрисовывается... если слишком переместить вниз то та часть что исчезает снизу появляется сверху... и наоборот... может сам способ построения графика не подходит под такие испытания?

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:23
Выполнено за 0.02 сек.