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

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

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

Delphi.int.ru Expert

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

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

#   

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


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

Подробнее »



Вопрос # 4 684

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

Такой вопрос.
У меня есть массив массивов : A[ A1[4,5], A2[2,5], A3[x,y]....]
Тоесть в одном массиве несколько массивов в каждом из которых по два элемента - координаты х,y.
1. Что можно использовать вместо внутренних массивов для записи координат ? Тоесть A1[4,5] заменить на Что-то (x,y).
2. Как огласить такой массив?
2. Как присвоить например значения x=4,y=7 , например, 3 -элементу массива?

Для конкретики - задавайте вопросы.
Благодарен за помощь.

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

Вопрос задал: hatecows (статус: Посетитель)
Вопрос отправлен: 27 октября 2010, 10:35
Состояние вопроса: открыт, ответов: 2.

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

Здравствуйте, hatecows!
объявить так

var a:array[1..100] of TPoint;
и использовать так
a[1].x := 1;
a[1].y := 3;

хотя Ваша запись вида A[ A1[4,5], A2[2,5], A3[x,y]....] говорит о том, что у вас трёхмерный массив. Наверно правильно все таки было записать так
a = ((4,5), (2,5), (x,y), ....)

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 27 октября 2010, 10:40

Ответ #2. Отвечает эксперт: min@y™

Если пишешь на Delphi и координаты целые, то можно использовать массив из TPoint:

type
  TPointArray = array[0..N - 1] of TPoint; // статитческий массив
  TPointDynArray = array of TPoint; // динамический массив
var
  PA: TPointArray;
  PDA: TPointDynArray;
Обращаться к элементам таких массивов можно так:
PA[3].X:= 5;
PA[3].Y:= -7;

Если координаты вещественные, то тип записи точки придётся придумать самому:
type
  TPointF = record
    X, Y: Double; // или любой другой вещественный тип
  end;
  TPointArray = array[0..N - 1] of TPointF; // статитческий массив
  TPointDynArray = array of TPointF; // динамический массив
var
  PA: TPointArray;
  PDA: TPointDynArray;

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 27 октября 2010, 10:48


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

Всего сообщений: 12; последнее сообщение — 3 ноября 2010, 19:43; участников в обсуждении: 4.
hatecows

hatecows (статус: Посетитель), 28 октября 2010, 00:51 [#1]:

Координаты целые. А что если количество элементов массива наперед неизвестно ?
То есть массив должен быть динамическим ?
Это так как тут ?

TPointDynArray = array of TPoint; // динамический массив
А добавлять к масиву тогда так ?:

PDA[3].X:= 5;
PDA[3].Y:= -7;

Я правильно понял ?
hatecows

hatecows (статус: Посетитель), 28 октября 2010, 06:18 [#2]:

Что-то не то =(
Задача такая, я бегаю по канве рисунка в поисках красных пикселей. Как только нахожу - координаты заношу в массив.
Что я неверно написал ?
type
   TPoint = record
    m, n: integer;
    end;
   TPointDynArray = array of TPoint; 
 
var
 i:integer; PDA: TPointDynArray;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  x, y, c : integer;
begin
i:=0;
  c := clRed;
  for x:=0 to Image1.Width-1 do
    for y:=0 to Image1.Height-1 do
      if Image1.Canvas.Pixels[x,y]=c then
      begin
        i:=i+1;
        PDA[i].m=x ;(Тут бьет ерором)
        PDA[i].n:=y ;
        Label1.Caption := 'x=' + IntToStr(x) + '  y=' + IntToStr(y);(Тут координаты выводит нормально)
      end;
 
end;
 
end.

Лишний код не писал.
Где я туплю ?
min@y™

min@y™ (статус: Доктор наук), 28 октября 2010, 08:20 [#3]:

Цитата (hatecows):

Где я туплю ?

Ты не тупишь, это нормальная ошибка для начинающего, не прочитавшего ни одного материала по дин. массивам. Чтобы начать работать с таким массивом, нужно сначала выделить под него память с помощью процедуры SetLength(). Вот тебе подборка материалов, изучай.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
hatecows

hatecows (статус: Посетитель), 31 октября 2010, 20:23 [#4]:

Изучил =) Помогите с эрором:
Коротко суть: есть картинка с красной точкой. Нахожу красный пиксель - суну в массив. Пробую вывести любые данные с массива на Label1 для проверки. Бьет эрором =(

unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
 
type
 
  MyType = record
    x:byte;
    y:byte;
  end;
 
  TForm1 = class(TForm)
    Image1: TImage;
    Button1: TButton;
    Label1: TLabel;
 
  procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1; A: array of MyType;
 
implementation
 
{$R *.dfm}
 
 
procedure TForm1.Button1Click(Sender: TObject);
var
  x, y, c, i : integer;
begin
  i:=0;
  c := clRed;
  for x:=0 to Image1.Width-1 do
    for y:=0 to Image1.Height-1 do
      if Image1.Canvas.Pixels[x,y]=c then
       begin
          i:=i+1;
            SetLength(A, Length(A) + 1);
            A[i].x := x;
            A[i].y := y;
       end;
Label1.Caption := 'x=' + IntToStr(A[i].x) + '  y=' + IntToStr(A[i].y);
end;
 
end.

Что не так ? Че еще изучить ? =)
min@y™

min@y™ (статус: Доктор наук), 31 октября 2010, 20:48 [#5]:

Где еррор-то возникает?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 31 октября 2010, 21:52 [#6]:

представьте себе такой случай, что в приведенном выше коде не нашлась ни одна красная точка (ну представим себе), тогда по выходу с цикла, массив будет пустой (нулевой длины) и i=0;
И теперь, когда будет выполнятся строка
Label1.Caption := 'x=' + IntToStr(A[i].x) + ' y=' + IntToStr(A[i].y);
произойдет обращение к несуществующему элементу. И получаем ошибку...
Если же припустить, что было найдено n точек, то размер массива будет тоже n. И i будет равно n. Но так как последний элемент массива будет иметь индекс n-1, то снова будет выход за пределы массива и соответственно ошибка.

Сможете исправиться?
Галочка "подтверждения прочтения" - вселенское зло.
hatecows

hatecows (статус: Посетитель), 1 ноября 2010, 00:36 [#7]:

Справился :
rocedure TForm1.Button1Click(Sender: TObject);
var
  x, y, c, i : integer;
begin
  i:=-1;
  c := clRed;
  for x:=0 to Image1.Width-1 do
    for y:=0 to Image1.Height-1 do
      if Image1.Canvas.Pixels[x,y]=c then
       begin
            i:=i+1;
            SetLength(A, Length(A) + 1);
            A[i].x := x;
            A[i].y := y;
 
       end;
if (i>=1) then Label1.Caption := 'x=' + IntToStr(A[i-1].x) + '  y=' + IntToStr(A[i-1].y);
 
end;
 
end.

Огромное спасибо. Пока что дальше сам.
hatecows

hatecows (статус: Посетитель), 1 ноября 2010, 00:42 [#8]:

А, вот еще вопрос наболел =)

По поводу
c := clRed;
Где список других цветов(оттенков) достать можно ?
И что если у меня на рисункеточка красный цвет, но я наперед не знаю какого он оттенка. Возможно ли как -нибудь програмно его определить ? или это очень громоздко будет ?
bugmenot

bugmenot (статус: 3-ий класс), 1 ноября 2010, 01:12 [#9]:

мне нравится терминология: "огласить массив" :-)

RE: предопределенные цвета - a) нажми F1 (такая кнопка в левом верхнем углу, рядом с Esc) b) команда Find declaration
виконання програми розпочинається з того самого мiсця, де призупинилося.

hatecows

hatecows (статус: Посетитель), 1 ноября 2010, 01:47 [#10]:

Хорошо, например тот же красный цвет будет $000000FF , тут ясно что оттенки можно подобрать от 00000000 до FFFFFFFF.
Как насчет второго вопроса, как определить оттенок.
Понимаю что можно искать не белый, а потом определить, но что если цветов на картинке много, а надо найти только красный(любого оттенка).
Можно проверять каждый пиксель, входит ли он в диапазон значений красных оттенков, но какой тогда диапазон от 000000ХХ до 000000ХХ ???
И может есть другой способ ?
Вадим К

Вадим К (статус: Академик), 1 ноября 2010, 10:18 [#11]:

что бы посмотреть "список цветов" (на самом то деле список констант), можно просто кликнуть мышкой по clRed с нажатым Ctrl. А там дальше будет видно.
Как определить "возможные оттенки красного" - не знаю, то что для одного ещё явно красный, для другого может быть зеленым... Но подскажу пару веселых функций.
function rgb(r:byte; g:byte; b:byte):TColor;
мы ей передаем три числа в диапазоне 0-255, а она возвращает готовый цвет. (Реализация там примитивная (r shl 16) or (g shl 8) or b, но...).
Тройка функций
function GetRValue(color:TColor):byte;
function GetGValue(color:TColor):byte;
function GetBValue(color:TColor):byte;
возвращает красную, зелёную и синюю составляющие.
Галочка "подтверждения прочтения" - вселенское зло.
hatecows

hatecows (статус: Посетитель), 3 ноября 2010, 19:43 [#12]:

Вот кусок кода:
procedure TForm1.Button1Click(Sender: TObject);
var
  x, y, i,j : integer;
begin
 
for I := 0 to Image1.Width - 1 do
  for J := 0 to Image1.Height - 1 do
  begin
    if (GetRValue(Image1.Canvas.Pixels[i, j]) > 220) and
       (GetGValue(Image1.Canvas.Pixels[i, j]) < 150) and
       (GetBValue(Image1.Canvas.Pixels[i, j]) < 150) then
 
     Image1.Canvas.Pixels[i, j] := RGB(GetRValue(Image1.Canvas.Pixels[i, j]), 0, 0)
    else
      Image1.Canvas.Pixels[i, j] := RGB(0, 0, 0);
 
  end;
end;

В принципе самый простой фильтр. И очень даже нормально работает. Но в результате получается размытая красная область. Как мне тогда найти координаты центра этой обрасти (круга)?

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

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