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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Pascal] Динамические массивы, модуль "Многоугольник" 
V
    Опции темы
Fortop
Дата 18.5.2008, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 1
Всего: 42



Цитата(KasMP @  18.5.2008,  17:07 Найти цитируемый пост)
Да, но ведь нормальный программист должен хотя бы раз додуматься до всего этого сам.
(или хотя бы поразмышлять на эту тему, чтобы понять все нюансы и всю красоту оптимального варианта, понять свои ошибки и сделать вывод на будущее)

Это классно smile Но кто из нас двоих собирается быть нормальным программистом? smile


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
KasMP
Дата 20.5.2008, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Я вчера наконец-то отошла от раздумий над алгоритмами и приступила к написанию программы.

Решила создать модуль, в котором будут нужные ВА.
В модуле были созданы типы для списка и некоторые переменные:
Код

type    TPointer=^TCoordinate;
        TCoordinate=record
            x, y: integer;
            next: TPointer;
            end;
var    start, step, finish: TPointer;
        num: integer; {число вершин многоугольника}


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

function Perimeter (var start: TPointer; var num: integer): real;
    var    i: integer;
        tempSum: real;
        tempStep, tempNext: TPointer;
        tempX, tempY: integer;
    begin
    tempSum:=0; tempStep:=start; tempNext:=start^.next;
    for i:=1 to num do
        begin
        tempX:=(tempStep^.x-tempNext^.x)*(tempStep^.x-tempNext^.x);
        tempY:=(tempStep^.y-tempNext^.y)*(tempStep^.y-tempNext^.y);
        tempSum:=tempSum+SQRT(tempX+tempY);
        tempNext:=tempNext^.next; tempStep:=tempStep^.next;
        end;
    Perimeter:=tempSum;
    end;

Код

function Square (var start: TPointer; var num: integer): real;
    var    i: integer;
        tempSum: real;
        tempStep, tempNext: TPointer;
        tempX, tempY: integer;
    begin
    tempSum:=0; tempStep:=start; tempNext:=start^.next;
    for i:=1 to num do
        begin
        tempX:=tempNext^.x-tempStep^.x;
        tempY:=tempNext^.y+tempStep^.y;
        tempSum:=tempSum+tempX*tempY;
        tempNext:=tempNext^.next; tempStep:=tempStep^.next;
        end;
    Square:=tempSum*0.5;
    end;

Дальше идет определение принадлежности точки многоугольнику: точка последовательно соединяется со всеми соседними вершинами, накапливается сумма площадей полученных треугольников (площадь каждого отдельного треугольника считается по формуле Герона); если накопленная сумма площадей равна площади многоугольника, то точка принадлежит многоугольнику (иначе не принадлежит, это понятно).
Очевидно, что при подсчете площадей двух соседних треугольников длина одной и той же стороны будет нужна 2 раза. Это учтено: длина каждой стороны считается один раз, а в цикле просто переводятся указатели.
Мне удалось найти у себя несколько ошибок: периметр вместо полупериметра, непереведенные на вершину вперед указатели и т.п.. Но функция по прежнему всегда выдает false.

Код

function PointInPolyhedron (var start: TPointer; var num: integer; var x, y: integer): boolean;
    var    i: integer;
        tempSum: real; {накопление суммы площадей треугольников}
        tempStep, tempNext: TPointer;
        difX, difY, difStepX, difStepY, difNextX, difNextY: integer;
        len, lenStep, lenNext: real;
        tempP: real; {полупериметр каждого получевшегося реугольника}
    begin
    {для разностей и длин::
     Step - точка и текущая вершина;
     Next - точка и следующая вершина;
     [ничего] - текущая и следующая вершины}
    tempSum:=0; tempP:=0; tempStep:=start; tempNext:=start^.next;
    difStepX:=(x-tempStep^.x)*(x-tempStep^.x);
    difStepY:=(y-tempStep^.y)*(y-tempStep^.y);
    lenStep:=SQRT(difStepX+difStepY);
    for i:=1 to num do
        begin
        {расстояние от текущей вершины до следующей}
        difX:=(tempNext^.x-tempStep^.x)*(tempNext^.x-tempStep^.x);
        difY:=(tempNext^.y-tempStep^.y)*(tempNext^.y-tempStep^.y);
        len:=SQRT(difX+difY);
        {расстояние от точки до следующей вершины}
        difNextX:=(tempNext^.x-x)*(tempNext^.x-x);
        difNextY:=(tempNext^.y-y)*(tempNext^.y-y);
        lenNext:=SQRT(difNextX+difNextY);
        {полупериметр}
        tempP:=(len+lenStep+lenNext)*0.5;
        tempSum:=tempSum+SQRT(tempP*(tempP-len)*(tempP-lenStep)*(tempP-lenNext));
        {переносим длины текущей стороны
         сдвигаем указатели на  одну вершину вперед}
        lenStep:=lenNext; tempStep:=tempNext; tempNext:=tempNext^.next;
        end;
    {сумма площадей равно площади многоугольника?}
    PointInPolyhedron:=(Square(start,num)=tempSum);
    end;

В упор не могу найти еще ошибки (помогите, пожалуйста).

Ну и сама программа, в которой все это тестируется, выглядит так:
Код

uses Module;

var    input: text;
    i: integer;
    x, y: integer;

begin
{создание списка из вершин­}
assign(input, 'C:\in.txt'); reset(input);
MReadFirst(input,num,start,step);
for i:=1 to (num-1) do MRead(input,step);

{закольцовывание списка}
finish:=step; finish^.next:=start;

writeln(Perimeter(start,num):2:2);
writeln(Square(start,num):2:2);
readln(x,y); writeln(PointInPolyhedron(start,num,x,y));
readln;
end.


Это сообщение отредактировал(а) KasMP - 20.5.2008, 07:59
PM MAIL   Вверх
KasMP
Дата 20.5.2008, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



 smile  smile  smile 
Я вместо массива организовала динамический список smile !
PM MAIL   Вверх
skyboy
Дата 20.5.2008, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 5
Всего: 260



я так понял, у тебя сравниваются площади "строго равно". все же у тебя дробный тип данных.
воспользуйся сравнением "отлиается на некую погрешность".
Цитата(KasMP @  20.5.2008,  06:58 Найти цитируемый пост)
 Но функция по прежнему всегда выдает false.

ну, так отладь функции в отдельности.
корми тестовые данные, смотри дебаггером текущие значения переменных. сравнивай с ожидаемым.
когда функции в отдельности будут отлажены и проверены по мере сил, приходи к тестированию программы в целом.
а то даже с помощью целого форума искать ошибку в непростом коде - вещь небыстрая, малоинтересная и низкоинформативная smile
PM MAIL   Вверх
KasMP
Дата 20.5.2008, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



skyboy, smile !
(очень рада тебя видеть!!!)

Цитата(skyboy @  20.5.2008,  16:43 Найти цитируемый пост)
я так понял, у тебя сравниваются площади "строго равно". все же у тебя дробный тип данных.
 smile 
Цитата(skyboy @  20.5.2008,  16:43 Найти цитируемый пост)
воспользуйся сравнением "отлиается на некую погрешность"
 smile  smile 
Т.е., другими словами, взять модуль разности суммы площадей треугольников и площади многоугольника, а затем сравнить этот модуль с какой-то положительной величиной?
Цитата(skyboy @  20.5.2008,  16:43 Найти цитируемый пост)
ну, так отладь функции в отдельности.
корми тестовые данные, смотри дебаггером текущие значения переменных. сравнивай с ожидаемым.
когда функции в отдельности будут отлажены и проверены по мере сил, приходи к тестированию программы в целом.

Я так и делаю smile . Видимо, сказывается недостаток опыта smile .
PM MAIL   Вверх
Fortop
Дата 21.5.2008, 01:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 1
Всего: 42



Цитата(KasMP @  20.5.2008,  19:19 Найти цитируемый пост)
Т.е., другими словами, взять модуль разности суммы площадей треугольников и площади многоугольника, а затем сравнить этот модуль с какой-то положительной величиной?

Если в Delphi нет специальной функции, то алгоритм описан правильно smile
главное чтобы эта положительная величина была достаточно мала smile



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
KasMP
Дата 21.5.2008, 10:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Цитата(Fortop @  21.5.2008,  01:25 Найти цитируемый пост)
главное чтобы эта положительная величина была достаточно мала

Подумаем, сколько это должно быть...

Только проблема в том, что функция проверки принадлежности точки многоугольнику выдает false даже тогда, когда результаты всех вычислений, всех извлечений корней целочисленны smile . Буду дальше искать и сравнивать... smile
PM MAIL   Вверх
Fortop
Дата 21.5.2008, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 1
Всего: 42



KasMP
А что тут искать?

бери треугольник со сторонами 3, 4, 5

переведи на листике его в векторы и точку где-нибудь внутри.

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


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
KasMP
Дата 21.5.2008, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



О smile !
Сегодня запустила тот же самый код на другом компе - функция работала идеально smile . Сейчас запустила у себя - тоже идеально smile .

Как такое может быть smile  smile ?
(может память надо чаще очищать smile  smile ?)
PM MAIL   Вверх
KasMP
Дата 22.5.2008, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Сделала все кроме пересечения двух многоугольников (вторым "многоугольником" может быть точка). Про пересечение буду читать вот это.
Сдавать в классе мы уж не успеваем, поэтому буду писать на e-mail. Я попробовала прокомментировать модуль и саму программу так, чтобы преподаватель понял, откуда что взялось.

Не могли бы вы оценить то, насколько понятно получилось?
Помогите, пожалуйста, своей оценкой. Я нисколько не хочу, чтобы преподаватель увяз в дебрях переменных, связей между ними и т.п.. Хочется, чтобы ему было не очень сложно и чтобы он не мучился слишком сильно...
(видимо, придется посылать два варианта: с комментариями и без - уж слишком много их получилось)
PM MAIL   Вверх
THandle
  Дата 22.5.2008, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 30
Всего: 372



KasMP, покажи что у тебя получилось, почитаю smile 
PM   Вверх
KasMP
Дата 22.5.2008, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Сейчас smile .

Добавлено через 2 минуты и 44 секунды
Эм...
Если открыть *.pas в блокноте, выбрать шрифт "Terminal", скопировать и вставить сюда, то вместо кириллицы получается абракадабра. Если выбирать не "Terminal", то получается абракадабра и в блокноте, и здесь... smile

Добавлено через 3 минуты и 58 секунд
Как перенести кириллицу из *.pas (т.е. из-под MSDOS) сюда (т.е. в Windows)?
PM MAIL   Вверх
THandle
Дата 22.5.2008, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 30
Всего: 372



KasMP, прикрепи сам файл smile 
PM   Вверх
KasMP
Дата 22.5.2008, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Так не все будут качать... Кто-то по ссылке до статьи дойти не может, а тут тем более...



Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  Polyhedron.rar 8,66 Kb
PM MAIL   Вверх
KasMP
Дата 22.5.2008, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

Репутация: 1
Всего: 30



Там 5 файлов: модуль с комментариями и без, программа с комментариями и без, формула для площади многоугольника.

Добавлено через 7 минут и 44 секунды
Я вспомнила, что забыла очистить память!!!!!!
Добавлю потом... Считайте, что память очищена smile .

Добавлено через 10 минут и 54 секунды
Да, кстати, вам потребуется файл входных данных. Можете взять этот:
Цитата

4 -6 0 -6 2 -4 3 -4 -2
3 0 0 0 -3 -2 0
5 2 1 2 5 4 5 4 1 3 3
6 2 -3 5 -3 5 -4 7 -4 5 -5 3 -5


Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  Polyhedron.rar 8,66 Kb
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0822 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.