Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование с нуля - это совсем просто! 43) Матрица: Загрузка Графической Подсистемы


Информационный Канал Subscribe.Ru

 
Школа программирования

Программирование с нуля - это совсем просто!

43) Матрица: Загрузка Графической Подсистемы

Выбор мин/макс элементов, если сразу код не пишется, то представьте просто, что перед вами куча фишек с числами, из них надо отобрать максимальное. Как вы будете действовать? Будете брать по одной, сравнивать с неким значением, и если больше текущая, то ее значение запомните:

  vmax := 0;

  for i := 1 to 100 do
    if q[ i ] > vmax then
       vmax := q[i];

И все.

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

Тут главное, обобщить решение на алгоритм, как в общем случае он будет работать. И с сортировкой - есть длинный ящик из N элементов, в каждом из N позиций - фишка с числом. Как вы будете их сортировать, если разрешено перекладывать фишки? Опишите этот алгоритм словами, а потом уже запрограммируйте.

Жалобы.

* Если записать:

  if (mw = ' m ' || ' man ' )

- работает как положено, но как только добавить:

  if (mw = ' w ' || ' woman ' )

- тут и облом.
Сергей

  if (mw = ' m ' || ' man ' )

Нет, это неправильная запись. В ней сразу несколько ошибок.

Во-первых, = -это не сравнение, а присваивание. Сравнение - == .

Потом, после || ставится целое, законченное условие, никаких сокращений. Нельзя записывать

если x равен 5 или 7. Надо записывать если (x равен 5) или (x равен 7).

То, что вы подразумевали, может так записаться:

  if (mw == ' m ' || mw == ' man ' )

но и это неправильно. Увы, в Си вы не можете сравнивать строки в лоб с помощью == . На самом деле в записи

  if (mw == ' m ' ...

сравнивается значение переменной mw, которая массив символов (не строка! это разные вещи), а в Си она считается так называемым указателем на массив, хоторая хранит физичский адрес строки в памяти - то есть абракадабру с точки зрения программиста!

Как минимум можно записать правильно только так:

  if (mw[0] == ' m ' )

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

  if (mw = ' m ' || ' man ' )

тут второе условие в трактовке компилятора Си - просто значение man, которое сравнивается с нулем. Если оно не ноль (а оно заведомо не ноль), то трактуется как истина, и все выражение будет истинным.

А все равно, woman тут трактуется как отдельное условие. То есть woman преобразуется в int по какому-то правилу, и сравнивается с нулем. С mw[0] оно никак не связано.

* Я в функции задаю матрицу, а вот как эту матрицу использовать в другой функции, скажем в main?
Сергей

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

  #include ...
  int massiv[100];

  int funk() {
   massiv[1] = 0;
  }

  int main() {
   massiv[2] = 5;
  }

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

*   1) Я не поняла, почему когда я задаю деревья и сосны как целые
  (что, на мой взгляд, логично :)
  int tree,pine;
  float percent;
  percent=pine/tree;
  percent становится равным нулю?
  Екатерина

Потому что в Си int деленное на int дает int. Выполняется целочисленное деление, берется только целая часть. Можно явно указать, что результат должен быть дробным:

percent=pine * 1.0 / tree;

Число деревьев, целое конечно :) Хотя ведь их можно распиливать :) Бесконечно :)

* 2) И еще хотела пожаловаться: несмотря на то, что я изменяю цвет шрифта надписи на кнопке, надпись нагло остается черного цвета!

Это только для стандартных Button, возьмите с панели Additional кнопку BitBtn, и все замечательноо будет. На ней еще картиночки можно размещать.

27. Списки.
Вроде особых проблем пока со списками не возникло. Вот только рассортировать не получается. Я не поняла, это какая-то функция отката должна быть, или список просто надо запомнить, прежде чем сортировать?
В общем я думала-думала и ничего не придумала лучше, чем немножко схитрить. Не совсем уверена, что это то решение, которого Вы ждали, но я добавила третий (не видимый), временный список, где храню неотсортированные значения:

Список рассортировать невозможно. А зачем? В задании такого не было, имелось в виду только включать/отлючать режим сортировки.

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

* Что то у меня не получается с типом Char. Во первых Си ругается что не может преобразовывать тип AnsiStringв char. И потом я не очень поняла, как заносить строку в массив char. Если я пишу:

  char str[10];
  str="ххххх";

он просит (в смысле, требует) указать номер элемента: [C++ Error] Unit1.cpp(21): E2277 Lvalue required
Так что я решила с AnsiStringделать. Но так тоже не получилось. В результате я использовала оба типа и наконец заработало!

char, да, в Си к сожалению стандартного типа строк не было,AnsiString в борланде добавился, поэтому там бывают проблемы. По идее вот так должно работать:

  char str[10] ="ххххх"; // в момент декларации только!

Но переменная str - это не строка в классическом понимании на самом деле в Си, поэтому присваивать ей в лоб строки нельзя (хотя в некоторых компиляторах разрешается, но значит не в C++Builder). str - это как бы пометка места в памяти, где хранятся далее 10 символов (указатель, называется).

С символами менее привычно первое время, действительно.

А с "ё", кодировкой, проблемы вообще по-моему, в самих настройках виндовс русских, плохо она там поддерживается. Бывают и такие ситуации, человек делал кодировку строки:

Я ДВА дня с этим делом промучилась. Не получается, хоть тресни. Программа одно выдаёт, а у меня, когда я сама считаю другое получается. Пока мне не пришла гениальная мысль изменить сам алгоритм программы. Во-первых она стала намного короче , во-вторых - проще. Без всяких заумностей. Опять выручил консольный вариант. Сделала так, чтобы абсолютно все значения выводились под номером шага (когда код прибавляется) . Стала проверять, где же я могла ошибиться. Оказалось - НИГДЕ. Это в книге в таблице символов опечатка была, там две строчки "105 - i". Вот и получалось, что программа считала правильно, а у меня на один шаг всегда больше, если приходилось через 105 переходить. Вот!!!!!!!!!!!!!!!
Лена

* И еще может отправлять RES файлы, а то Delphi ругаеться и пересоздаёт их ??
Артём

Нет, RES-файлы не нужны именно потому, что Дельфи их пересоздает :)

* И еще у меня на машине происходят странные вещи: программы, которые я писала в Дельфи стали со значками С++ . В Дельфи они открываются все нормально.
Наталья

* Я уже спрашивала, если форма хранится не в "Делфи", а в "С++", это ничего страшного????? Или мне всё-таки пока "С++" убрать с компьютера?????
Лена

Это она только так пишется, что хранится в С++ - просто файлы форм проассоциированы :) с С++Builder. Да это без разницы, что пишется.

Так у многих. Это из-за C++Builder. Вы его ставили наверно следом за Дельфи, вот он и проассоциировал расширения форм с собой. Не обращайте внимания.

А ещё у меня один раз не голубой полоской строка выделилась, а зелёной. Это что было????? Я так поняла, что какая то ошибка имела место, т.к на голубой полосе всегда стоит галочка, а на зелёной стоял крестик.

Это возможно установлена точка прерывания, F5, ее еще можно поставить, просто щелкнув мышкой слева от строки, строчку пустую, в которой кода исполнимого не было. И крестиком показано, что здесь ничего не выполняется, и поэтому остановки не будет. Пустая, или одно описание переменной например только в строке, нету операторов рабочих.

* ListBox1.Items.Clear; // очищается первый список. ???????(а надо?)
// Но тогда какой смысл в сортировке первого списка, если во- первых он стирается, а во- вторых во втором списке сортировка всегда включена. Получается, что если в первом сортировки нет, она всё-равно произойдёт во втором.

А смысла в этом упражнении нету :)

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

* Почему Strings это свойство, а Cleae - метод? Как понять,где что??? если и то и другое относится к свойству Items Что такое "Add"??? (для чего используется я понимаю).

ЭТо надо у разработчиков Дельфи спросить :)

Понять, что где, можно через Хелп - там есть все компоненты, и для каждогоразделены методы и свойства явно. Я им пользуюсь постоянно, без него никуда. Расскажу как нибудь поподробрнее в рассылке.

А понимать, метод или свойство, на самом деле необязательно. Потому что свойства почти все - тоже методы :) только выглядят как переменные. Это сделано умышленно, чтобы программисты не заморачивались, просто пользуйтесь и все. На западе, любят такой подход, это мне надо знать, а это не надо. Метод, свойство, какая разница.

У нас же более народ любопытный :)

ItemIndex, да, многие спрашивают, почему его нет в инспекторе объектов.

Не все свойства показываются в инспекторе. Программно к нему обращаетесь:

  if listbox1.itemindex > -1 then // есть выделенный

Или выделяете самую первую строку вот так:

  listbox1.itemindex := 0; // номер строки выделяемой

А Count - это функция на самом деле (метод объекта), ее тоже нету в инспекторе. Возвращает число элементов в списке, из которого вызывается. Удобно сделаны методы, наглядно, правда?

Нередки, увы, и такие письма.

Здравствуйте, Сергей!
Это Илья.
Может, покажусь назойливым, но хотелось бы узнать, когда же НАКОНЕЦ выйдет очередной выпуск вашей рассылки?

Выпуск выйдет, когда мне захочется. Или когда вы заплатите мне сто долларов.

А может, никогда не выйдет, если мне будут надоедать подобными письмами :)

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

Больше 1-1,5 часов в день тратить на рассылку я не могу, поэтому можете сами подсчитать, несколько десятков на пять минут, сколько остается на рассылку. Хотите, чтобы рассылка выходила чаще? Делайте упражнения, проверяйте на тестовых примерах, и подробный отчет присылаете, с минимумом бессвязной информации (энтропии :), с максимумом по делу. ЭТо и в жизни пригодится, умение мусор в мыслях от позитива отделять.

А какие-то свои собственные мелкие проблемы пытаться с моей помощью решать не стоит. Потому что вы всегда можете решить их САМИ.


Матрицы

Матрицы, как говорилось, это двумерные массивы. Фактически то же самое, что таблицы (столбцы и строки). Одномерный массив - можно считать строка (или столбец :), недаром строковый тип - массив символов. А матрица - массив строк (строк не в смысле String, а в смысле "строки" и "столбцы").

Другой аналог - двумерная плоскость, где каждая точка имеет две координаты, x и y. Игровая карта, обычно разбита на квадраты, она в программе представлена в виде матрицы.

Два измерения - ширина и высота. В одномерном - только длина.

Описывается двумерный массив схожим способом - сначала первое измерение, потом второе, через запятую:

var d2: array[ 1..10, 1..10 ] of Integer;

Вот мы описали табличку размером 10*10 (для морского боя например :). Доступ к каждому элементу по его обоим индексам:

d2[ 3, 5 ] := 123;

Индексы через запятую перечисляются. Какой индекс какому измерению соответствует, в принципе только программист решает. Хотите, считайте, что первый по порядку - это ширина, второй - высота, без разницы. Главное, последовательны будьте в выборе :)

Опишем таблицу размером 33 на 77 элементов:

var tab: array[ 1..33, 1..77 ] of Integer;

Заполним ее суммами индексов:

  for x := 1 to 33 do
   for y := 1 to 77 do
    tab[ x,y ] := x + y;

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

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

   int tab[33][77], x, y;
   for( x=0; x<33; x++ )
   for( y=0; y<77; y++ )
     tab[x][y] = x+y;

В Бейсике, как и в Паскале, перечисление индексов через запятую, только используем круглые скобки:

          Dim tab(33, 77) As Integer
          Dim x, y As Integer

          for x = 0 to 32
              for y = 0 to 76
                  tab(x, y) = x + y
              Next
          Next

У массива в принципе может быть произвольное число измерений.

var d3: array[ 1..10, 1..10, 1..10 ] of Integer;

Это трехмерный массив, (аналог куба), доступ к его элементам требует уже трех индексов:

d3[ 2,3,4 ] := d3[ 2,3,4 ] + 1;

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

По матрицам, все!

Задания. Много будет.

N 28. Заполните матрицу размером 100*100 элементов (дробный тип) случайными значениями от -1 до 1, и найдите ее максимальный элемент по модулю (абсолютное значение, abs()) и его оба индекса.

N 31. В такой же матрице поменяйте местами i-й и j-й столбцы.

N 34. В такой же матрице поменяйте местами i-й столбец и j-ю строку.

N 29. Даны три матрицы A, B, C. Первые две заполняются случайными числами от 0 до 100.

Матрицу C считаем, C = A * B (каждый элемент i,j матрицы C будет произведением соответствующих i,j-элементов матриц A и B)

N 30. Важное! Каждый элемент C из прошлого примера должен быть суммой всех окружающих его элементов матрицы A (B не используем) с 8 прилегающих сторон, клеток (i-1,j-1), (i-1,j), (..), (i+1,j), (i+1,j+1)).

Проверить, если один из индексов выходит за границы (в углу, на сторонах), брать значение "заграничного" элемента равным 0.

Например, если i=1, то вместо элементов с индексами (i-1, ...) берем 0.

N 32. Заполните первые три строки матрицы размером 27 * 72 элемента случайными целыми числами от 0 до 100, каждая четная строка, начиная с 4-й, будет суммой трех предыдущих, а каждая нечетная - разностью двух предыдущих (из n-2 -й вычитаем n-1 -ю).

N 33. Заполните матрицу случайными символами (тип char). Найдите столбец, где какой-то символ (для каждого столбца надо определить, какой он будет в этом столбце - какой будет встречаться в столбце чаще всего) встречается наибольшее число раз (если в столбце 3 символ "*" - самый частый, встретился 6 раз, а в столбце 2 символ "J" - самый частый, встретился 7 раз, то результатом будет 2-й столбец).

Если условие не ясно, спрашивайте!

Далее - закрепляющие упражнения:)

Строки.

N 35. Написать функцию, находящую первое вхождение заданной подстроки в строку - номер символа (подстрока "345" в строке "12345", номер-позиция вхождения, равен 3).

N 36. Написать функцию, заменяющую все вхождения одной подстроки на другую (могут быть разной длины!). Например, заменить каждый пробел на три звездочки. Или наоборот.

N 37. R - дробное число. Сколько разных цифр использовано в его записи?

N 38. Длинная строка, из обычного текста. Выделить все слова, разделенные символами, заданными в другой строке.

Например, входная строка "привет тебе, пух!", символы-разделители - строка " ,.!?". Выводите результат в список, должно выдаться:

привет
тебе
пух

Пустые результирующие строки не выводятся.

N 39. Дано целое число N. Проверить, является ли оно суммой своих делителей (которые тоже надо найти). 6 = 1+2+3.


Графика. Учимся рисовать.

Для повышения увлекательности занятий хорошо подойдет компонент PaintBox с панели System.

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

Этот компонент просто размещается на форме, и в его пределах можно рисовать. Например, вывод цветной точки с координатами x,y выполняется так (считаем, что мы предварительно поместили на форму этот компонент и название его сохранили, по умолчанию, PaintBox1; размер его сделаем 100*100, он выглядит как прозрачный пунктирный квадрат). Рисование выполняется обращением к свойству Canvas (графическая канва) этого компонента (PaintBox1.Canvas). У него в свою очередь есть свойство Pixels (PaintBox1.Canvas.Pixels), которое представляет собой матрицу, двумерный массив заданного размера (100*100 в нашем случае) - поточечный образ канвы, каждый элемент - отдельная точка. К нему обращаемся, как и положено массивам, с двумя индексами.

Координаты x,y отсчитываются от верхнего левого угла, то есть он считается точкой с координатой 0,0, увеличение по оси x идет слева направо, а по оси y - сверху вниз.

А что записывать? Указать надо цвет, значение цвета для конкретной точки.

В Дельфи есть удобная функция RGB(), которая формирует цвет комбинацией интенсивности красного, зеленого и синего (интенсивность задается числом от 0 до 255). Так, черный будет RGB(0,0,0), красный - rgb(255,0,0), синий - rgb(0,0,255), белый - rgb(255,255,255).

Заполним доступную канву 300 красными точками в случайных позициях :) - по нажатиям на некоторую кнопку, разместите ее на форме и запишите код в обработчике нажатия (с умом!):

  procedure TForm1.Button1Click(Sender: TObject);
  var i,x,y: Integer;
  begin
  for i := 1 to 300 do
    begin
    x := random(100);
    y := random(100);
    PaintBox1.Canvas.Pixels[x,y] := RGB(255,0,0);
    end
  end;

Уже запускайте - можно посмотреть!

Берем random(100) а не random(100)+1, потому что в Pixels[] отсчет точек (пикселов экрана) начинается с 0.

Важно! Вывод по точкам ОЧЕНЬ медленный! Ну относительно конечно...

Если изменить RGB(255,0,0) на rgb( random(255),random(255),random(255) ) то выйдет еще красивее. Ясно, почему?

Только вот фон плохой,не черный, правда? Ну его надо просто заполнить черным цветом перед началом. Для этого поможет метод канвы FillRect. В его детали вдаваться не будем, а вызывается он, немного хитрым способом с указанием прямоугольной области заливки цветом:

FillRect(Rect(0,0, 100,100)) // координаты верхнего левого и правого нижнего углов

На вложенное слово Rect, это типа функции, она формирует данное типа "прямоугольник", пока не обращайте внимания. Потом изучим такую особенность записи.

А каким цветом? У канвы есть еще свойство популярное, Brush (кисть заливки), тоже пока в детали вдаваться не будем, а у нее - свойство Color (цвет кисти :), просто перед вызовом FillRect надо указать цвет заливки, так:

  procedure TForm1.Button1Click(Sender: TObject);
  var i,x,y: Integer;
  begin

  PaintBox1.Canvas.Brush.Color := rgb(0,0,0); // черным - можете
  изменить конечно
  PaintBox1.Canvas.FillRect(Rect(0,0,100,100));

  for i := 1 to 300 do
    begin
    x := random(100);
    y := random(100);
    PaintBox1.Canvas.Pixels[x,y] := rgb(
  random(255),random(255),random(255) ) ;
    end
  end;

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

Линия рисуется тоже совсем просто, с помощью пары методов, сначала начальная точка задается, потом конечная.

  PaintBox1.Canvas.MoveTo(10,10); // откуда
  PaintBox1.Canvas.LineTo(50,50); // куда

Цвет линии, и толщина, задаются свойством канвы Pen (по аналогии с Brush, которая фон задавала, а Pen - карандаш, передний план). У Pen есть свойство Color (цвет карандаша) и Width - толщина линии в пикселах (по умолчанию - 1).

Вот как можно заполнить канву случайными разноцветными линиями разной толщины:

  for i := 1 to 300 do
    begin
    PaintBox1.Canvas.Pen.Color := rgb(
  random(255),random(255),random(255) ) ;
    PaintBox1.Canvas.Pen.Width := random(3)+1;
    x := random(100);
    y := random(100);
    PaintBox1.Canvas.MoveTo(x,y);
    x := random(100);
    y := random(100);
    PaintBox1.Canvas.LineTo(x,y);
    end

Уже получается некое подобие произведений абстракционистов :)

Эллипсы (круги, окружности - частный случай эллипса, очевидно) - рисуются методом Ellipse() с четырьмя параметрами - координатами верхнего левого и правого нижнего углов прямоугольника, в который эллипс вписывается. Кайма эллипса рисуется в соответствии с параметрами свойства Pen канвы, а заливается эллипс внутри цветом кисти Brush канвы.

  for i := 1 to 300 do
    begin
    // цвет и ширина каймы будущего эллипса
    PaintBox1.Canvas.Pen.Color := rgb(
  random(255),random(255),random(255) ) ;
    PaintBox1.Canvas.Pen.Width := random(3)+1;

    // цвет заливки внутренности эллипса
    PaintBox1.Canvas.Brush.Color := rgb(
  random(255),random(255),random(255) ) ;

    // координаты углов :) эллипса
    x := random(100);
    y := random(100);
    x2 := random(100);
    y2 := random(100);

    // вписываем эллипс
    PaintBox1.Canvas.Ellipse(x,y,x2,y2);
    end;

Ну прям Пикассо!

Только наше творение, исчезнет, если окно свернуть/развернуть или переключиться на другую задачу, а потом вернуться. Так Windows устроены, программа должна сама себя перерисовывать, но этот нюанс мы изучим, когда до графики полноценно доберемся. Пока же можно рисовать, главное, рисунок не закрывать ничем.

Сделайте побольше канву, на весь экран, и попробуйте так же прямоугольниками разноцветными заполнить в случайных позициях и случайных размеров, с помощью FillRect().

В C++Builder, так же, только вместо точек - стрелочки, напоминаю, при обращении к свойствам и методам объектов, расположенных на форме:

  PaintBox1->Canvas->Ellipse(x,y,x2,y2);

Функция RGB() записывается заглавными.


Visual Studio.NET

Вот в Visual Studio.NET, посложнее. Как пикселы выводить, я вообще не нашел.

Такой пример рассмотрим. Компонента типа PaintBox в VS.NET нет, однако рисовать там можно практически на любых объектах, достаточно взять например декоративную панель (Panel). Разместим ее на форме, добавим кнопку и создадим обработчик нажатия на кнопку. Кстати, и в Дельфи можно рисовать на поверхности панелей, у них должно быть свойство Canvas (но лучше брать PaintBox).

Чтобы рисовать на панели, надо получить доступ к так называемому графическому контексту, который в .NET называется Graphics. Это своего рода аналог канвы в Дельфи. Получается он так:

  private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
  System.EventArgs) Handles Button1.Click

    dim gf As Graphics
    gf = Panel1.CreateGraphics()

  end Sub

В переменной gf - графический контекст панели.

Здесь Panel1 - наша панель на форме, по умолчанию ее название - Panel1.

Теперь необходимо явно создать карандаш (объект Pen), кисть (Brush), а также отдельную переменную, хранящую цвет.

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

          dim p As Pen ' p - это переменная-карандаш
          dim c As Color ' c - это переменная-цвет
          dim br As SolidBrush ' br - это переменная-кисть

Аналогом функции RGB(), строящей цвет, в .NET будет такая запись:

Color.FromArgb(255, r,g,b)

где вместо r,g,b подставляется интенсивность красного, зеленого, синего, от 0 до 255. А первое число 255- это интенсивность так называемого альфа-канала (степень прозрачности). 255, сначит НЕпрозрачный совсем. А 0 - прозрачный (невидимый).

Но карандаш и кисть, перед использованием, помимо объявления в качестве переменных, надо еще явно создать. Этот принцип, дополнительного создания различных системных объектов в дополнение к их декларации, широко распорстранен. Его придется запомнить :)

Для создания, используется слово New, после которого ставится название объекта (не переменной! это своего рода тип данных, Pen или SolidBrush например). Карандаш, нуждается в указании цвета и толщины линии:

  c = Color.FromArgb(255, 0, 0, 0) ' черный цвет
  p = New Pen(c, 1) ' карандаш, цветом черный, толщиной 1 пиксел

Кисть создается также, ей только цвет нужен:

br = New SolidBrush(c)

Все! Теперь можно рисовать. Для очистки всей области рисования (поверхности панели) можно воспользоваться методом графического контекста Clear с указанием цвета заливки:

gf.Clear(c)

Линии рисуются методом DrawLine, ему нужен карандаш и координаты начала и конца линии. Залитый прямоугольник - метод FillRectangle, первый параметр - кисть, затем координата левого верхнего угла, ширина и высота. Эллипс залитый - FillEllipse, также кисть, и координаты прямоугольника + ширина и высота, в который эллипс вписывается.

Объявим также переменные, которые нам потребуются:

Dim r, g, b, n, x, y, x1, y1 As Integer

Цикл, в котором рисуются линии (весь обработчик):

      private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
  System.EventArgs) Handles Button1.Click

          dim gf As Graphics
          dim p As Pen
          dim c As Color
          dim br As SolidBrush
          dim r, g, b, n, x, y, x1, y1 As Integer

          gf = Panel1.CreateGraphics()

          c = Color.FromArgb(255, 0, 0, 0)
          p = New Pen(c, 1)
          br = New SolidBrush(c)

          gf.Clear(c)

          for n = 1 to 100
             ' считаем случайные значения r,g,b в диапазоне 0..255 каждый
              r = CInt(Int((255 * Rnd())))
              g = CInt(Int((255 * Rnd())))
              b = CInt(Int((255 * Rnd())))

              c = Color.FromArgb(255, r, g, b) ' создаем из них цвет
              p.Color = c ' меняем цвет карандаша

         ' считаем 4 случайные значения от 1 до 100
              x = CInt(Int((100 * Rnd()) + 1))
              y = CInt(Int((100 * Rnd()) + 1))
              x1 = CInt(Int((100 * Rnd()) + 1))
              y1 = CInt(Int((100 * Rnd()) + 1))

       ' рисуем линию
  gf.DrawLine(p, x, y, x1, y1)

          Next

      end Sub

Для прямоугольника, в месте, где линия, добавим фиксацию цвета кисти:

br.Color = c

и вывод прямоугольника:

gf.FillRectangle(br, x, y, x1, y1)

или эллипса:

gf.FillEllipse(br, x, y, x1, y1)

Творите! :) Видите, даже с помощью простейших вещей можно красивые вещи создавать. А чуть-чуть посложнее?

Будем не юзерами, а Нео-Программистами, КОТОРЫЕ ЭТУ МАТРИЦУ СОЗДАЮТ И УЛУЧШАЮТ.


(c) 2004-2005 Сергей Бобровский bobrovsky@russianenterprisesolutions.com

Школа программирования с нуля
http://russianenterprisesolutions.com/sbo/

Все предыдущие выпуски базового курса тут:
http://russianenterprisesolutions.com/sbo/base.htm

 

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.prognull
Отписаться

В избранное