Аналоговые часы создание стрелок через типизированный массив

Форум для изучающих FPC и их учителей.

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

Аналоговые часы создание стрелок через типизированный массив

Сообщение Водород » 18.05.2010 14:58:56

Народ вот помогли сделать часы
Код: Выделить всё
Program fdgfaf;
uses graph, crt, SysUtils;
var
  c : char;
  T : TSystemTime;                         
                       
  gd, gm, r, x, y,i,j     : integer;
  H, PrH, PrM, PrS : integer;


const
  Grd : double=pi/180;
BEGIN
gd:=vga;
gm:=2;
InitGraph(gd,gm,'');
r:=174;
SetColor(15);
SetFillStyle(1,12);
Circle(300,250,200);
Circle(300,250,180);
FloodFill(110,250,15);
SetColor(15);
SetFillStyle(1,10);
Circle(300,250,174);
FloodFill(126,250,15);
SetColor(15);
SetFillStyle(1,15);
FloodFill(299,249,15);
SetFillStyle(1,12);
Bar(150,247,170,253);
Bar(435,247,455,253);
Bar(297,389,303,409);
Bar(297,95,303,115);

repeat
  GetLocalTime(T); //Љ®¬ ­¤  бзЁвлў Ґв ўаҐ¬п б Є®¬ЇмвҐа .
  if T.Hour>=12     
  then H:=T.Hour-12 
  else H:=T.Hour;
  if PrH<>T.Hour
  then             
   begin
    x:=300+round((r-55)*sin(PrH*30*Grd));
    y:=250-round((r-55)*cos(PrH*30*Grd));
    SetColor(15);
    Line(300,250,x,y);
    PrH:=T.Hour;
   end;
  if PrM<>T.Minute
  then               
   begin
    x:=300+Round((r-55)*sin(PrM*6*Grd));
    y:=250-Round((r-55)*cos(PrM*6*Grd));
    SetColor(15);
    Line(300,250,x,y);
    PrM:=T.Minute;
   end;
  if PrS<>T.Second
  then
   begin
    x:=300+Round((r-25)*sin(PrS*6*Grd));
    y:=250-Round((r-25)*cos(PrS*6*Grd));
    SetColor(14);
    Line(300,250,x,y);
    setcolor(15);
    Line(300,250,x,y);
    PrS:=T.Second;
   end;
  SetColor(0);
  SetFillStyle(1,15);
  Bar(345,240,400,255);
  SetfillStyle(1,12);
  OutTextXY(350,247,Format('%.2d.%.2d.%.4d',[T.Day, T.Month, T.Year]));
  SetFillStyle(1,15);
  Bar(265,365,370,390);
  SetFillStyle(1,12);
  SetColor(0);
  OutTextXY(270,370,Format('%.2d:%.2d:%.2d',[T.Hour, T.Minute, T.Second]));
  case T.Second of
   00..01,59 : Bar(297,95,303,115);
   14..16 : Bar(435,247,455,253);
   29..31 : Bar(297,389,303,409);
   44..46 : Bar(150,247,170,253);
  end;
  x:=300+Round((r-55)*sin(H*30*Grd));
  y:=250-Round((r-55)*cos(H*30*Grd));
  SetColor(0);
  Line(300,250,x,y);
  x:=300+Round((r-55)*sin(T.Minute*6*Grd));
  y:=250-Round((r-55)*cos(T.Minute*6*Grd));
  SetColor(0);
  Line(300,250,x,y);
  x:=300+Round((r-25)*sin(T.Second*6*Grd));
  y:=250-Round((r-25)*cos(T.Second*6*Grd));
  SetColor(14);
  Line(300,250,x,y);

  Delay(500);

  if keypressed
  then c:=readkey;
until c=#27;
ReadLn;
CloseGraph;
END.

А щас не получается вместо стрелок(простых линий) сделать типизированный массив (такой красивой объёсной стрелки) и тогда я окончательно доделаю работу
ну или хоть подскажите команды и как их делать а стрелку я сам дорисую очень надо плизз вот через два дня работы сдавать
Водород
новенький
 
Сообщения: 28
Зарегистрирован: 12.05.2010 12:29:35

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Climber » 19.05.2010 13:02:11

Водород писал(а):А щас не получается вместо стрелок(простых линий) сделать типизированный массив (такой красивой объёсной стрелки) и тогда я окончательно доделаю работу
То есть что-то типа растрового изображения стрелки? А как его поворачивать, придумал уже?
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Водород » 19.05.2010 13:03:26

изображение как бы есть а вот поварачивать хз как всё перебробывал ен фига не робит

Добавлено спустя 1 минуту 10 секунд:
у меня к центру не привязываеться.Я рисую в вертикальном положении стрелку потмо когда стрелка повораичваеться а сам массив(моя стрелка) так же в вертикальном положении остаёться
Водород
новенький
 
Сообщения: 28
Зарегистрирован: 12.05.2010 12:29:35

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Brainenjii » 19.05.2010 13:39:48

Вращай циферблат? :-D
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Водород » 19.05.2010 14:13:37

ну а если правда, вообще не пойму как делать
Водород
новенький
 
Сообщения: 28
Зарегистрирован: 12.05.2010 12:29:35

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Putnick » 19.05.2010 18:23:50

Уважаемый Водород,
рискну предположить, что "копать" Вам нужно в направлении DrawPoly(FillPoly). На "входе" количество точек и массив (типизированный :) ) координат этих самых точек.
выглядеть это может примерно так:
1. Создаём массив pointtype (аналог TPoint, но в старые времена был именно такой тип) в него загоняем описание нашей стрелки в "нулевом" состоянии;
2. Поворачиваем все координаты на заданный угол вокруг заданной точки, угол вычисляется как
Код: Выделить всё
HourAngle:=(Hour mod 12)*30;
MinutesAngle:=Minutes*6;
SecundAngle:=Secund*6

3. Отрисовываем через DrawPoly стрелку;
4. каждую секунду поворачиваем секундную стрелку на 6 градусов, каждую минуту - минутную на 6 и каждый час - часовую на 30, и отрисовываем стрелку.

Примерная процедура поворота (сделана по аналогии с DrawPoly из исходников):
Код: Выделить всё
Procedure RotateAround(x,y:integer; angle:real; NumPoints:integer; var PolyPoints);
type
  pt = array[0..16000] of pointtype;
var
  i:integer;
  tx, ty:integer;
  sn, cs:real;
begin
  if NumPoints<2 then exit;
  sn:=sin(angle/180*pi); // В данном случае передаются градусы, хотя, как Вы понимаете, лучше передавать радианы. Просто градусы привычнее и нагляднее (лично для меня :) ).
  cs:=cos(angle/180*pi);
  for i:=0 to NumPoints-1 do begin
    tx:=pt(PolyPoints)[i].x-x;
    ty:=pt(PolyPoints)[i].y-y;
    pt(PolyPoints)[i].x:=x+round(tx*cs-ty*sn);
    pt(PolyPoints)[i].y:=y+round(tx*sn+ty*cs);
  end;
end;

Надеюсь, смог помочь.

С уважением, Алексей.
Putnick
новенький
 
Сообщения: 62
Зарегистрирован: 18.03.2009 13:02:56

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Водород » 20.05.2010 10:40:47

Не знаю но всё равно спосибо но в нашей школле мы и подавно такого не изучали если я это вставлю в своё проект то меня сразу впалят((((Алексей а ты можешь написать что то полегче на уровне 10 класса))))
Водород
новенький
 
Сообщения: 28
Зарегистрирован: 12.05.2010 12:29:35

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение ViTality » 20.05.2010 12:29:19

Водород
глянь в examples lazarus`a там есть пример поворота картинки
ViTality
постоялец
 
Сообщения: 308
Зарегистрирован: 05.10.2007 15:12:02

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Vadim » 20.05.2010 13:02:01

Водород писал(а):если я это вставлю в своё проект то меня сразу впалят

Если Вы сможете объяснить то, что Вы написали в программе, то никто не сможет Вас впалить. :) Другое дело, если препод сильно обидчивый попадётся, то увидив, что ученик умнее учителя, может обидеться. Тогда уж точно будет палево сплошное... ;)
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение ViTality » 20.05.2010 14:16:52

< папка lazarus`а>/examples/lazintfimage
ViTality
постоялец
 
Сообщения: 308
Зарегистрирован: 05.10.2007 15:12:02

Re: Аналоговые часы создание стрелок через типизированный массив

Сообщение Putnick » 20.05.2010 17:43:36

Водород писал(а):Не знаю но всё равно спосибо но в нашей школле мы и подавно такого не изучали если я это вставлю в своё проект то меня сразу впалят((((Алексей а ты можешь написать что то полегче на уровне 10 класса))))

Простите, Водород, а что конкретно Вы не изучали?
1. DrawPoly? Ну, как говорится: "Читающий Хелпы, да прочтёт!" :wink: . Однако если по каким-либо (видимо, религиозным) причинам Вам запрещают ЭТО использовать, то приведу реализацию из ФПС:
Код: Выделить всё
procedure DrawPoly(numpoints : word;var polypoints);
    type
      ppointtype = ^pointtype; // зачем здесь вот это не знаю. Видимо, великое колдунство.
      pt = array[0..16000] of pointtype;
    var
      i : longint;
    begin
      if numpoints < 2 then
        begin
          _GraphResult := grError;
          exit;
        end;
      for i:=0 to numpoints-2 do
        line(pt(polypoints)[i].x,
             pt(polypoints)[i].y,
             pt(polypoints)[i+1].x,
             pt(polypoints)[i+1].y);
    end;

2. Прикол вида:
Код: Выделить всё
type
pt = array[0..16000] of pointtype;
...
pt(polypoints)[i].x...
- называется, ЕМНИП, "приведение типов". Суть прикола: программист говорит машине "А знаешь, этот PolyPoints на самом деле длиннюююююююющий массив с координатами вершин. Да, не похож... А ты поверь!". После чего тупой компьютер начинает обращаться с этим PolyPoints как с массивом. Все бурно радуются. Пока не происходит выход за границы диапазона. Но это уже совсем другая история.
3. Наконец, "афинское преобразование" на плоскости. В школе, вроде, действительно не проходят. Однако, человеком, знакомым с тригонометрией, выводится легко.
4. Если же у Вас стрелка хранится в памяти как картинка, то посмотрите в примерах по Лазарусу, как советует Виталити.

Если хотите, вот черной вариант:
Код: Выделить всё
Program fdgfaf;
uses graph, crt, SysUtils;
var
  c : char;
  T : TSystemTime;

  gd, gm, r, x, y,i,j     : integer;
  H, PrH, PrM, PrS : integer;
MinutA, SecundA, HourA, Arrow: array [0..4] of pointtype;


const
  Grd : double=pi/180;

Procedure RotateAround(x,y:integer; angle:real; NumPoints:integer; var PolyPoints, OutPoints);
type
  pt = array[0..16000] of PointType;
var
  i:integer;
  tx, ty:integer;
  sn, cs:real;
begin
  if NumPoints<2 then exit;
  sn:=sin(angle*Grd); 
  cs:=cos(angle*Grd);
  for i:=0 to NumPoints-1 do begin
    tx:=pt(PolyPoints)[i].x-x;
    ty:=pt(PolyPoints)[i].y-y;
    pt(OutPoints)[i].x:=x+round(tx*cs-ty*sn);
    pt(OutPoints)[i].y:=y+round(tx*sn+ty*cs);
  end;
end;

BEGIN
// описываем стрелки
SecundA[0].X:=300;
SecundA[0].Y:=250;
SecundA[1].X:=300;
SecundA[1].Y:=95;
SecundA[2].X:=305;
SecundA[2].Y:=120;
SecundA[4].X:=295;
SecundA[4].Y:=120;
SecundA[3].X:=300;
SecundA[3].Y:=95;

MinutA[0].X:=300;
MinutA[0].Y:=250;
MinutA[1].X:=300;
MinutA[1].Y:=95+20;
MinutA[2].X:=305;
MinutA[2].Y:=120+20;
MinutA[4].X:=295;
MinutA[4].Y:=120+20;
MinutA[3].X:=300;
MinutA[3].Y:=95+20;

HourA[0].X:=300;
HourA[0].Y:=250;
HourA[1].X:=300;
HourA[1].Y:=95+40;
HourA[2].X:=305;
HourA[2].Y:=120+40;
HourA[3].X:=295;
HourA[3].Y:=120+40;
HourA[4].X:=300;
HourA[4].Y:=95+40;


gd:=vga;
gm:=2;
InitGraph(gd,gm,'');
r:=174;
SetColor(15);
SetFillStyle(1,12);
Circle(300,250,200);
Circle(300,250,180);
FloodFill(110,250,15);
SetColor(15);
SetFillStyle(1,10);
Circle(300,250,174);
FloodFill(126,250,15);
SetColor(15);
SetFillStyle(1,15);
FloodFill(299,249,15);
SetFillStyle(1,12);
Bar(150,247,170,253);
Bar(435,247,455,253);
Bar(297,389,303,409);
Bar(297,95,303,115);
GetLocalTime(T);
PrS:=T.Second;
PrM:=T.Minute;
PrH:=T.Hour;
SetColor(1);
RotateAround(300,250,30*T.Hour,5, HourA, Arrow);
DrawPoly(5, Arrow);
SetColor(2);
RotateAround(300,250,6*T.Minute,5, MinutA, Arrow);
DrawPoly(5, Arrow);
SetColor(3);
RotateAround(300,250,6*T.Second,5, SecundA, Arrow);
DrawPoly(5, Arrow);
//SetWriteMode(XorPut);

repeat
  GetLocalTime(T); //Љ®¬ ¤  бзЁвлў Ґв ўаҐ¬п б Є®¬ЇмвҐа .
  if PrS<>T.Second
  then
   begin
//    SetColor(0);
    SetFillStyle(1,15);
    Bar(345,240,400,255);
    SetfillStyle(1,12);
//    OutTextXY(350,247,Format('%.2d.%.2d.%.4d',[T.Day, T.Month, T.Year]));
    SetFillStyle(1,15);
    Bar(265,365,370,390);
    SetFillStyle(1,12);
    SetColor(0);
//    OutTextXY(270,370,Format('%.2d:%.2d:%.2d',[T.Hour, T.Minute, T.Second]));
    SetColor(15);
RotateAround(300,250,30*PrH,5,HourA,Arrow);
DrawPoly(5, Arrow);
RotateAround(300,250,6*PrM,5,MinutA,Arrow);
DrawPoly(5, Arrow);
RotateAround(300,250,6*PrS,5,SecundA,Arrow);
DrawPoly(5, Arrow);
SetColor(0);
OutTextXY(350,247,Format('%.2d.%.2d.%.4d',[T.Day, T.Month, T.Year]));
OutTextXY(270,370,Format('%.2d:%.2d:%.2d',[T.Hour, T.Minute, T.Second]));
Bar(297,95,303,115);
Bar(435,247,455,253);
Bar(297,389,303,409);
Bar(150,247,170,253);
SetColor(1);
if T.Hour<>PrH then PrH:=T.Hour;
RotateAround(300,250,30*PrH,5, HourA,Arrow);
DrawPoly(5, Arrow);
SetColor(2);
if T.Minute<>PrM then PrM:=T.Minute;
RotateAround(300,250,6*PrM,5, MinutA,Arrow);
DrawPoly(5, Arrow);
SetColor(3);
PrS:=T.Second;
RotateAround(300,250,6*PrS,5, SecundA,Arrow);
DrawPoly(5, Arrow);
   
  end;
  if keypressed
  then c:=readkey;
until c=#27;
ReadLn;
CloseGraph;
END.
Putnick
новенький
 
Сообщения: 62
Зарегистрирован: 18.03.2009 13:02:56


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 43

Рейтинг@Mail.ru