Здравствуйте Уважаемые Специалисты. Пытаюсь построить алгоритм расчёта и построения графика. Сейчас всё застопорилось на поиске команды похожей по функционалу на Gosub из Бейсика. Код (Text): // Исходные данные $pi = 3.14159; $f = 16.3168; // Построение графика CL for (; $x <= 650; $x++) { $f = $f * pow(2, 1 / 64.); $w = (2 * $pi * $f); $A1 = $Rl21; $B1 = $w * $L21; $A2 = $Rd2; $B2 = 0; $y = $w / $C21; imageSetPixel($img, 20 + $x, 600 - $y, $black); } // Сложение $A3 = $A1 + $A2; $B3 = $B1 + $B2; Надо в строчке 14 написать команду аналогичную Gosub, отправиться на строчку 19 и после вычислений строки 20 вернуться обратно. Потом сделать ещё вычисление и выполнить ещё такую же команду с отправкой на другую строчку, потом снова возврат и т.д., т.е. посылов будет несколько в одном цикле. Всего будет несколько разных циклов с включением в их алгоритм одинаковых блоков аналогичных строкам 19, 20. Поиск в интернете не нашёл ни одного подходящего случая. Все пишут, что команды типа Goto используют только начинающие, потому что это легко описывается каким-то формулами, только никто не сообщает какими. Нашёл команду break, но правильно её прописать не получилось. И ещё вопрос: можно ли записывать два действия в одну строку, например строки 10 и 11? Чисто для удобства восприятия.
Надо переписать алгоритм, под PHP, так думаю будет лучше. Даже в официальной документации PHP есть смешные комиксы про goto/gosub https://secure.php.net/manual/ru/control-structures.goto.php
Страницу что по ссылке я видел. Вопрос как раз в том: что переписать и как. Вот код целиком. PHP: <?php // получим координаты из GET запроса, это то, что добавляется к адресу после знака ?, например: ?x1=40&x2=100&y1=50&y2=200 if (isset($_GET["U"])) $U = $_GET["U"]; else $U = 0; if (isset($_GET["C21"])) $C21 = $_GET["C21"]; else $C21 = 0; if (isset($_GET["L21"])) $L21 = $_GET["L21"]; else $L21 = 0; if (isset($_GET["Rl21"])) $Rl21 = $_GET["Rl21"]; else $Rl21 = 0; if (isset($_GET["Rd2"])) $Rd2 = $_GET["Rd2"]; else $Rd2 = 0; // сделать белый фон создаваемой картинки $img = imagecreate(718, 620); $white = imagecolorallocate ($img, 255, 255, 255); imagejpeg($img, "pic.jpg"); // определяем цвет для рисования ( черный в данном случае ) и идентификатор изображения не $im а $img ! $red = imagecolorallocate($img, 255, 0, 0); $white = imagecolorallocate($img, 255, 255, 255); $black = ImageColorAllocate($img, 0, 0, 0); // рисуем оси координат ImageLine($img, 19, 0, 19, 605, $black); ImageLine($img, 16, 601, 693, 601, $black); // установка стиля линии (пунктир) 4 белых пикселя, 4 черных $style = array($black, $black, $black, $black, $white, $white, $white, $white); imagesetstyle($img, $style); // рисуем горизонтальные пунктирные линии ImageLine($img, 16, 1, 687, 1, IMG_COLOR_STYLED); ImageLine($img, 16, 60, 687, 60, IMG_COLOR_STYLED); ImageLine($img, 16, 120, 687, 120, IMG_COLOR_STYLED); ImageLine($img, 16, 180, 687, 180, IMG_COLOR_STYLED); ImageLine($img, 16, 240, 687, 240, IMG_COLOR_STYLED); ImageLine($img, 16, 300, 687, 300, IMG_COLOR_STYLED); ImageLine($img, 16, 360, 687, 360, IMG_COLOR_STYLED); ImageLine($img, 16, 420, 687, 420, IMG_COLOR_STYLED); ImageLine($img, 16, 480, 687, 480, IMG_COLOR_STYLED); ImageLine($img, 16, 540, 687, 540, IMG_COLOR_STYLED); // рисуем вертикальные пунктирные линии ImageLine($img, 81, 2, 81, 609, IMG_COLOR_STYLED); ImageLine($img, 145, 2, 145, 609, IMG_COLOR_STYLED); ImageLine($img, 209, 2, 209, 609, IMG_COLOR_STYLED); ImageLine($img, 273, 2, 273, 609, IMG_COLOR_STYLED); ImageLine($img, 337, 2, 337, 609, IMG_COLOR_STYLED); ImageLine($img, 401, 2, 401, 609, IMG_COLOR_STYLED); ImageLine($img, 465, 2, 465, 609, IMG_COLOR_STYLED); ImageLine($img, 529, 2, 529, 609, IMG_COLOR_STYLED); ImageLine($img, 593, 2, 593, 609, IMG_COLOR_STYLED); ImageLine($img, 657, 2, 657, 609, IMG_COLOR_STYLED); ImageLine($img, 686, 2, 686, 609, IMG_COLOR_STYLED); // расставляем цифры по сетке ImageString($img, 5, 2, 3, "P, W", $black); ImageString($img, 4, 5, 53, "9", $black); ImageString($img, 4, 5, 113, "8", $black); ImageString($img, 4, 5, 173, "7", $black); ImageString($img, 4, 5, 233, "6", $black); ImageString($img, 4, 5, 293, "5", $black); ImageString($img, 4, 5, 353, "4", $black); ImageString($img, 4, 5, 413, "3", $black); ImageString($img, 4, 5, 473, "2", $black); ImageString($img, 4, 5, 533, "1", $black); ImageString($img, 4, 5, 593, "0", $black); ImageString($img, 4, 0, 607, ".016", $black); ImageString($img, 4, 61, 607, ".031", $black); ImageString($img, 4, 125, 607, ".062", $black); ImageString($img, 4, 189, 607, ".125", $black); ImageString($img, 4, 258, 607, ".25", $black); ImageString($img, 4, 326, 607, ".5", $black); ImageString($img, 4, 397, 607, "1", $black); ImageString($img, 4, 461, 607, "2", $black); ImageString($img, 4, 525, 607, "4", $black); ImageString($img, 4, 589, 607, "8", $black); ImageString($img, 4, 649, 607, "16", $black); ImageString($img, 4, 678, 607, "22", $black); ImageString($img, 5, 665, 582, "F, kHz", $black); ImageString($img, 5, 695, 95, "E", $black); ImageString($img, 4, 687, 112, "+90", $black); ImageString($img, 4, 692, 292, "0", $black); ImageString($img, 4, 687, 472, "-90", $black); // Исходные данные $pi = 3.14159; $f = 16.3168; // Построение графика CL for (; $x <= 650; $x++) { $f = $f * pow(2, 1 / 64); $w = (2 * $pi * $f); $A1 = $Rl21; $B1 = $w * $L21; $A2 = $Rd2; $B2 = 0; $y = $w / $C21 - $Rd2; imageSetPixel($img, 20 + $x, 600 - $y, $black); } // Сложение $A3 = $A1 + $A2; $B3 = $B1 + $B2; // Отправляем заголовак браузеру, непосредственно перед выводом в него картинки header ("Content-type: image/png"); // Выводим изображение в браузер imagepng($img); ?> Набраны пока только начало одного простого цикла, из действий с комплексными числами только сложение. Дописать - дело техники. Сейчас надо с аналогом gosub-а разобраться.
Алгоритм простой: различным данным присваиваются значения А1, А2, В1, В2 (строчки 94...97), в 98-ю строку надо написать аналог Gosub, отправляющий на строку 104, там вычисляются А3 и В3 и возвращаются обратно для дальнейшего вычисления. Весь алгоритм сложный, его выкладывать не имеет смысла, циклов несколько десятков, а действий как //Сложение всего 6. В примитиве все действия прописывались каждый раз, но это сильно раздувало расчёт, поэтому с освоением Бейсика была найдена команда Gosub. Предполагаю, что за последующие 25 лет произошло какое-то развитие языков программирования. Особенно обнадёживают приколы и карикатуры, видимо такие древние способы (goto/gosub) сейчас не популярны и эти задачи решаются проще. Вот только найти хоть какой-то пример пока не получилось.
Gosub, насколько мне помнится, вызывала подпрограмму фактически в древних бейсиках. После неё даже ретурн был. Так что сделай функцию --- Добавлено --- Хотя для двух строчек - зачем куда-то прыгать, что-то вызывать, почему не прописать прямо в цикле? --- Добавлено --- При этом, лично я не противник применять goto ограниченно (хотя в моих программах его почти и не найти, что и значит "ограниченно"). Просто здесь, ради двух строчек - смысла нет. Если строчек будет больше - ну вынеси в функцию, в древних бейсиках не было функций, не было циклов, поэтому применялись goto, gosub и прочее. (Помню, поскольку в ташкентской школе у нас были "компьютеры" Правец-8А, вот там весело было, только бейсик и противный зелёный экран)
Да, там действительно был ретурн. И цикл тоже был. Для этих двух строчек может быть и нет смысла делать ссылку, да другие действия несколько сложнее. Но главное в том, что действий всего 6, а ссылок на них бесконечно. Составление цикла - простая последовательная задача, состоящая из перебора стандартных операций (присвоение различным постоянным или введённым пользователем значений индексов А1...В2) и выполнение соответствующего действия, ранее решавшегося при помощи gosub. Если записывать по два действия в одну строчку, например 94 и 95, 96 и 97, и подписать комментарием каждый такой блок (две строки по два действия), а рядом с gosub естественно написано какое действие будет выполнено, то восприятие алгоритма станет элементарным. Странная ситуация: все прикалываются над gosub, но предлагают отказаться вообще от такой функции, сделать не шаг вперёд, а назад, т.е. раздуть алгоритм вместо его упрощения. Что такое: "сделать функцию"? Можно пример?
Да можно хоть 20 операторов в одну строку записать, через точку с запятой. Но это плохой стиль программирования в php.
Да, я знаю. Это говорили ещё про Бейсик. Но так удобно действия и с A и с B в одну строку писать. Может поможете встроить функции? А то я пока методом тыка подбираю работающие коды недели проходят. PHP: // Построение графика CL for (; $x <= 650; $x++) { $f = $f * pow(2, 1 / 64); $w = (2 * $pi * $f); $A1 = $Rl21; $B1 = $w * $L21; $A2 = $Rd2; $B2 = 0; $V1 = $A3; $Z1 = $B3; $A1 = $Rc21; $B1 = -1 / $w / $C21; $A2 = $V1; $B2 = $Z1; $y = $w / $C21 - $Rd2; imageSetPixel($img, 20 + $x, 600 - $y, $black); } // Сложение $A3 = $A1 + $A2; $B3 = $B1 + $B2; // Вычитание $A3 = $A1 - $A2; $B3 = $B1 - $B2; После строки 8 нужно выполнить //Сложение, а после строки 13 //Вычитание. Потом, когда алгоритм будет полностью работоспособным, можно будет сократить промежуточные вычисления, например строку 10.
Ну достаточно потратить неделю на чтение официального руководства по php, или любой книги, и не нужен будет метод тыка Код (PHP): // Куда-нибудь в пределах файла, но лучше в самый верх или самый низ для порядку function sum($a1, $a2, $b1, $b2) { return [$a1 + $a2, $b1 + $b2]; } function diff($a1, $a2, $b1, $b2) { return [$a1 - $a2, $b1 - $b2]; } // После строки 12 list($A3, $B3) = sum($A1, $A2, $B1, $B2); // После строки 13 list($A3, $B3) = diff($A!, $A2, $B1, $B2); Код рассчитан на php 5.4+, если пользуетесь более древней, то нужно будет использовать полный синтаксис массивов (вместо [] писать array ()) --- Добавлено --- Кстати, в php есть константа M_PI, и функция pi(), позволяющие получить куда больше знаков после запятой
Книг скачал семь штук и купил ещё две бумажных. За неделю там найти ответ на пару вопросов нереально, а выучить - и думать нечего. В смысле похожий пример-то найдётся, но как его адаптировать к конкретной задаче - непонятно. Чаще всего не работает и всё. Что не так - неизвестно. Про пи знаю, потом сделаю. Там точность и так достаточная. На квадратные скобки дримвивер ругается, написал так: function sum($a1, $a2, $b1, $b2) { return array($a1 + $a2, $b1 + $b2); } Правильно? Большие и маленькие буквы переменных - это так и должно быть? Обязательно нужно перечислять все переменные и при ссылке на функцию и в самой функции?
Я вам ссылку дал. Почитайте. --- Добавлено --- Надо понять специфику языка, а не искать "похожие примеры"
Последний месяц только этим и занимаюсь. Дело в том, что цели стать программистом на РНР у меня нет. Другая профессия уже имеется - это инженер-акустик. Программирование даже не хобби, а необходимость решить определённую задачу. Если бы Вам поручили сделать страничку с графическим калькулятором электрических фильтров, то Вам пришлось бы вникнуть в теорию четырёхполюсников, а Вы (при всём уважении) её скорее всего вообще не знаете. Там этой теории целый том, какую конкретно страницу открыть и какой блок формул использовать догадаться невозможно, только для того, чтобы выбрать нужный раздел надо серьёзно подучится. Самое главное что не известно правильный ли результат получится в конце. Чтобы это понять нужно знать основы электроакустики, которую надо изучать по совершенно другим книжкам. А Вы всего лишь программист на РНР. И Вы обратитесь на профильный форум. Там Вам дадут несколько подсказок, ссылки на те же самые статьи (книги), которые Вы уже читали, и предложат изучать теорию. В то время, когда Вам нужен всего один совет, только конкретный, потому что без него не запускается алгоритм.
@dm_rut моя функция addVertex рисует отрезок до заданных координат от места, где закончился предыдущий (там еще разделение разных линий (полигонов) по именам и поправка на масштаб, но принцип такой), https://php.ru/forum/threads/generator-diagramm-grafikov-gotovoe-reshenie.33280/
Если бы Вы ко мне обратились как заказчик, я бы просто потребовал от вас написать мне алгоритм работы на русском языке, плюс формулы, в которых бы я не стал особо разбираться, а просто слово в слово перевёл бы на php. Я делал, к примеру, проект, в котором требовалось рассчитывать расстояние по географическим координатам, но понятия не имею, как выводится используемая там формула
Спасибо [vs], буду изучать. Простую кривулину я уже научился рисовать. (не знаю можно ли тут давать ссылки на сторонние сайты) mkramer, потребовать у заказчика любой может. Он скажет так же, как Вы чуть выше: "Я вам ссылку дал. Почитайте". А там теория. И в ней все необходимые формулы есть (на самом деле). Как посоветуете ответить?
Ссылка туда, где делается этот калькулятор. Пока рисуется просто произвольный график, как только завершу первый алгоритм - одна схема станет рабочей. Другие - дело техники. Потом ещё надо будет организовать выбор схем по желанию пользователя и др. сервисные функции. Возможно возникнут вопросы. Чтобы кривая нарисовалась надо нажать "Считать". Изменяя значения в двух окнах под нижней схемой можно менять форму кривой, другие пока не функциональны. Собственно в этом и есть суть функционирования этой страницы. Пока кривая бессмысленная и большинство окон ввода неактивны.
На этом я его пошлю, поскольку заказчик обязан описать мне что ему надо от и до, и предоставить все необходимые формулы в конечном варианте, в формате: "Тебе придут такие данные, ты их подставишь вот в эту формулу, и готово". А я в его предметной области разбираться не обязан, так же как и он в php.
Вот и я не обязан разбираться в РНР. Хотя "обязан" тут не подходит, скорее я не достаточно в нём разбираюсь. После Вашего предсказуемого ответа, Ваши пути с этим конкретным заказчиком разойдутся, он найдёт другого программиста, который не будет вставать в позу, а задаст вопросы на нужных форумах, ему подскажут и программа будет написана. Смысл в том, что получив готовый алгоритм, его можно вкорячить в код не зная как он работает. Можно зная и понимая алгоритм заказать код у программиста и не понимать что он там накропал. В обоих случаях за конечный результат никто не отвечает, потому что разбирается только в своей части. А я хочу понимать всё. поэтому здесь и задаю вопросы. Благодаря Вашим ответам код совершенствуется и завершение очередного этапа приближается.
Если вы спец в своей области, вы заметите, если программа посчитает результат неверно, или дадите контрольные расчёты, по которым это может проверить программист. А в принципе, именно среди php-программистов не многие способны разобраться в такой математике. А если вы пишите в этот раздел, вам как раз нужно разбираться в PHP. Вы, на мой взгляд, теряете время, поскольку вместо того, чтобы прочитать одну-две несложные книжки (при том, что опыт программирования в целом у вас был), предпочитаете методом тыка по неделе пытаться что-то сделать.
Кол-во времени отпущенное каждому человеку примерно одинаково. Можно потратить его на изучение одной специальности и стать классным специалистом. Можно поизучать всё понемногу и стать продвинутым дилетантом. К сожалению последних подавляющее большинство. Это как раз такие изучатели теорий. Часто приходится предлагать им забыть всё, что они прочитали на просторах интернета и начать изучать заново (это в другой области, не в программировании). Надеюсь сегодня доделаю один цикл, и получится построить первый график. Сообщу.
Чем дальше занимаюсь РНР, тем больше офигеваю от "гениальности" авторов РНР. Если бы не было с чем сравнивать, то степень этого ощущения была бы видимо меньше, но я когда то занимался Бейсиком. Сравниваем. Код в Бейсике: (алгоритм) GOSUB "Сложение" (продолжение алгоритма) ..... "Сложение" (формулы) RETURN Теперь это считается старьём, так никто не делает, все реальные программисты пользуют такой метод: Код РНР: (алгоритм) list($A3, $B3) = sum($A1, $A2, $B1, $B2); (продолжение алгоритма) ..... function sum($А1, $А2, $В1, $В2) { return array(формулы); } Зачем так усложнять и два раза перечислять все участвующие в формулах элементы - непонятно. Т.е. понятно, что это язык программирования такой "гениальный", не чета Бейсику, но два раза то зачем. А если элементов полтора десятка - все перечислять два раза? А что делать в случае, когда формулы такие: B3=A1*A2+B1*B2 A3=(A1*A2+B1*А2)/B3 B3=(A2*B1-A1*B2)/B3 куда записывать В3 после list или после sum или и туда и туда? А после function sum В3 писать? Неужели проще нельзя придумать, тем более, что всё придумано уже давным-давно. Педъугадывая совет изучать теорию и специфику языка хочется спросить: где об этом написано? У меня не получилось найти. В любом случае методом тыка быстрее подобрать получится. Там есть ещё более сложный случай, который в Бейсике элементарно решается простым арифметическим способом, а при использовании РНР всё превращается в ребус. Очень трудно поверить, что всё так и должно быть и РНР придумали комсомольцы, которые изобрели код находясь в гамаке.