Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисовать функции... 
:(
    Опции темы
Muerto
Дата 9.9.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Хотел бы создать некий класс который бы рисовал мне функции...

К примеру даю ему y=3x^2+2x+345

И он мне рисует...

размер листа 1000 на 1000...

Все вроде бы просто... в любую функцию подставляем X получаем Y и рисуем....

Но блин... лист то у нас начинается с 0,0 и до 1000,1000...

Как так можно рисовать то?

Я сделал середину 500,500 которая на самом деле симфолезирует x,y

И просчитал какая же у нас функция нарисуется у которой низ в 500,500 ... 

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

0,0
500,-500
1000,0

Ну эт парабола

Считал считал на бумаге... вышло y=x^2-2x

Код

$y=0.002*pow($x,2)-2*$x;


Нарисовать такое простым циклом не возможно... пришлось делать
Код

$y=(int)$y;
$y=abs($y);


Но не серьёзно ведь так работать...

Может у кого получше идеи будут...

Цель -  методом get дают функцию, и комп её рисует...

Вот парабола которую я указал выше, так как мой скрипт её нарисовал:

user posted image

Это сообщение отредактировал(а) Muerto - 9.9.2010, 13:25


--------------------
user posted image
PM MAIL   Вверх
Muerto
Дата 9.9.2010, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Мне нужно как бы что бы было так:
Реал(x,y) => на картинке(x,y) 

(0,0) => (500,500)
(-500,500) => (0,0)
(-500,-500) => (0,1000)
(500,-500) => (1000,1000)
(500,500) => (1000,0)


Но где же тут закономерность??? чет не вижу


(-255,255) => (255,255)
(-255,-255) => (255,750)
(255,-255) => (750,750)
(255,255) => (750,255)


Это сообщение отредактировал(а) Muerto - 9.9.2010, 13:57


--------------------
user posted image
PM MAIL   Вверх
Dastan
Дата 9.9.2010, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 9.9.2010

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



Код

$x = $width / 2 + $real_x;
$y = $height / 2 - $real_y;


Это сообщение отредактировал(а) Dastan - 9.9.2010, 13:53
PM MAIL   Вверх
Muerto
Дата 9.9.2010, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Цитата(Dastan @ 9.9.2010,  13:49)
Код

$x = $width / 2 + $real_x;
$y = $height / 2 - $real_y;

Супер!!!

Вот только как вы это просчитали ?




--------------------
user posted image
PM MAIL   Вверх
Dastan
Дата 9.9.2010, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 9.9.2010

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



Цитата(Muerto @  9.9.2010,  13:21 Найти цитируемый пост)
лист то у нас начинается с 0,0 и до 1000,1000...

=> центр(width/2, height/2)

ось OX в обоих случаях направлена вправо =>
Код

$x = $width/2 + $real_x;


ось OY для “экранной” системы координаты  направлена вниз =>
Код

$y = $height/2 + (-$real_y); // меняем направление


PM MAIL   Вверх
Muerto
Дата 9.9.2010, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Рисует все отлично теперь когда точно расчитываю мой фальшивый X и Y!

Мне бы хотелось что бы такая аппликация была доступна как бы студентам...
Что бы человек ввел к примеру

pattern=3*x^2+2x+3

И нарисовало функцию...

'3*x^2+2*x+3' 
На пхп выглядит вот так:

$y=3*pow($x,2)+2*$x+3;

Сейчас вот играюсь... пока пытаюсь через exlode('x' что то сотворить...

Уже вижу что сверху "+" не передается как следует

МОжет тупо взять выбор наставить... типа формы?

размер таблицы...
и дальше паттерны...
вот только я туда все не запихаю полюбому




Это сообщение отредактировал(а) Muerto - 9.9.2010, 16:29


--------------------
user posted image
PM MAIL   Вверх
Dastan
Дата 9.9.2010, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 9.9.2010

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



Цитата(Muerto @  9.9.2010,  16:23 Найти цитируемый пост)
Мне бы хотелось что бы такая аппликация была доступна как бы студентам...

3*x^2+2x+3
PM MAIL   Вверх
Muerto
Дата 9.9.2010, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Dastan, А технологию не подскажите? засчет чего у них пере конвертировалось в 3*x^2%2B2x%2B3 ?
htaccess какой то?


Это сообщение отредактировал(а) Muerto - 9.9.2010, 16:44


--------------------
user posted image
PM MAIL   Вверх
ksnk
Дата 9.9.2010, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



Muerto, вероятно, нужно автоматически считать границы графика. 

К примеру, нужно вывести график по X от -100 до +100. Можно верить в то, что график гладкий и не особенно дергается и просчитать набор точек по X с шагом 10. получится ~20 значений. Из них выбрать минимальные и максимальные значения Y и по ним уже посчитать нужную высоту получившейся картинки. Если высота сразу зашкаливает за габариты Y, можно уменьшить габариты X и так далее... Так можно выводить картинку меньшего размера - экономить трафик юзера.
Можно вспомнить начала матанализа и приближенно. численными методами посчитать "точки перегиба" функции, чтобы более надежно определить экстремальные значения графика.

Так, например график из первого поста "сдвинется" вниз и ненужная пустая сетка не будет выводится.


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Muerto
Дата 9.9.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Я ща выложу то что есть, и сразу ясно станет чего ещё не хватает

http://learn-php.ru/graph.php?h=1000&w...rn=3*x^2+2*x+30

То что после patter я просто так вставил... на данный момент он рисует эту функцию потому что я вбил  $y=3*pow($x,2)+2*$x+30;

Осталось придумать как пере-конвертировать 

3*x^2+2*x+30 в 3*pow($x,2)+2*$x+30

Есть функции вроде eval к примеру... через которую если закинуть 'return 3*pow($x,2)+2*$x+30'
То думаю будет то что надо... но так ли это стоит решать? здесь ещё вопрос безопасности оч серьёзный есть...

Это сообщение отредактировал(а) Muerto - 9.9.2010, 16:51


--------------------
user posted image
PM MAIL   Вверх
ksnk
Дата 9.9.2010, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



Цитата(Muerto @  9.9.2010,  16:43 Найти цитируемый пост)
 засчет чего у них пере конвертировалось в 3*x^2%2B2x%2B3 

urlencode нужно применять. 
символ + в адресной строке имеет сакральный смысл. Он в некоторых случаях, в стародавние времена, использовался как заменитель пробела, по этому с ним обращаются странно...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Dastan
Дата 9.9.2010, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 9.9.2010

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



Кодирование URL

P. S. пользуемся поиском  smile 
PM MAIL   Вверх
ksnk
Дата 9.9.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



Цитата(Muerto @  9.9.2010,  16:45 Найти цитируемый пост)
3*x^2+2*x+30 в 3*pow($x,2)+2*$x+30

простые функции, как эта - конвертировать просто. Достаточно ч заменить на $x и a^b заменить на pow(a,b)

а вот сложные, со скобками и разной странной математикой - уже сложнее. Нужно будет разбирать уравнение в обратную польскую форму, потом по этой форме склеивать php-выражение. Да и защита от злонамеренного хака сервера с помощью графикопостроителя совсем не помешает ;)

с выражением лучше делать create_function, вместо eval'а


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Muerto
Дата 9.9.2010, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Ага... сейчас налеплю то что надо...

Я немного подумал, и пришел к выводу что нужно использовать не $_GET['pattern'] на $_SERVER['REQUEST_URI']/$_SERVER['QUERY_STRING']

В таком случае плюсы не съедает, и можно получать граф, прямо через get method...

Это сообщение отредактировал(а) Muerto - 9.9.2010, 17:40


--------------------
user posted image
PM MAIL   Вверх
Muerto
Дата 9.9.2010, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Цитата(ksnk @ 9.9.2010,  17:18)
с выражением лучше делать create_function, вместо eval'а


Это с точки зрения безопасности?

Или так эффективней в плане, что я делаю выражение для 
$newfunc = create_function('$x', 'return sin($x)');

Это сообщение отредактировал(а) Muerto - 9.9.2010, 17:55


--------------------
user posted image
PM MAIL   Вверх
ksnk
Дата 9.9.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



Muerto, create_function, imho, эффективней eval'а, я вроде как даже когда-то проверял. Впрочем - несложно проверить еще раз. Польза create_function в том, что в результате получается именно функция, по которой можно вычислять значения, то есть сделать функцию нужно один раз, а eval можно захотеть вызывать в цикле построения графика.
Безопасность тут примерно одна и та-же. Если код небезопасен - не важно eval'ить его или функцией запускать ...


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Muerto
Дата 9.9.2010, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Увы похоже пытаюсь прыгнуть выше моего понимания...

Я построил серию регулярок return preg_replace($search,$replace,$data);
Они допустим из

pattern=x^2+2x+5+x*5-sinx через $_SERVER['QUERY_STRING'] и explode Беру...

Превращаю его в ->

pow($x,2)+2*$x+5+$x*5-sin($x)

Это у меня уже получилось...

ВОт только через create-function он мне выдает тупо мой же паттерн...

Код

  echo $pattern."<br/>";//

          $getx = create_function('$x,&$pattern', 'return "$pattern";');
          echo $getx($x,$pattern).'<br/>';


Выдаст pow($x,2)+2*$x+5+$x*5-sin($x)


--------------------
user posted image
PM MAIL   Вверх
ksnk
Дата 9.9.2010, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



Код

  echo $pattern."<br/>";//
          $getx = create_function('$x', 'return '.$pattern.';');
          echo $getx($x).'<br/>';


может так?

Это сообщение отредактировал(а) ksnk - 9.9.2010, 18:25


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Muerto
Дата 9.9.2010, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



ksnk, Ага спасибо, теперь работает=-) 
pattern=x^2[/URL]
x^2
pow($x,2)
9

Осталось немного о безопасности подумать... и добавить регулярки для самых распространенных выражений

Как бы вы обезопасили такой запрос?
очень страшно мне вставлять такое на публичное...

Надо придумать функцию чисти которая все отсеит...

Пока что перекодировал в 
Код

 $getx = create_function('$x', sprintf('return %s;',$pattern));

Но как мне кажется здесь разницы нету... это не в BD записывать...
Нужно фильтровать левые буквы...

Это сообщение отредактировал(а) Muerto - 9.9.2010, 18:38


--------------------
user posted image
PM MAIL   Вверх
Muerto
Дата 9.9.2010, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Все в общем... Готово...

Я вот ещё думаю может описание составить... но все же 

http://learn-php.ru/graph/1000~1000~p=tanx+x+4*x^3+2x+300


Я сделал что бы он записывал генерируемые картинки в папку кэша, и в след раз от туда читал... дабы меньше грузить сервер...
Да и любопытно что там люди нагенирируют=-)

Небольшое объяснение:

graph/1000~1000~p=tanx+x+4*x^3+2x+300

Первая 1000 это WIDTH
Вторая это HEIGHT
P Это ваш y!!!

Вот и все...


--------------------
user posted image
PM MAIL   Вверх
ksnk
Дата 10.9.2010, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 2
Всего: 386



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

include ('./nat2php.class.php');

class calc {
    
    private $calc;
    /**
     * функция скрипта - вызывается по конструкции time
     */
    function c_getTime(){
        return time();
    }
    
    /**
     * вывод ошибок пользователю
     */
    function error($s){
        echo $s;
    }

    function exec_script($script,$x=0){
        if(empty($this->calc)){
            $this->calc=new parser();
            $this->calc
                ->newOp2('- +',3)
                ->newOp2('* /',5)
                ->newOp2('|| && >> <<',4)
                ->newOp2('^',7,'pow(%s,%s)')
                ->newOp1('-','-%s')
                ->newOp1('-','-%s')
                ->newOp1('tan abs sin cos')
                ->newOpr('x','$x')
                ->newOpr('pi','pi()')
                ->newOpr('time','$self->c_getTime()')
            ;    
        }
        //compile it;
        $result = '';
        try{
            $this->calc->makelex($script);
            $result=$this->calc->mathcalc();
        } catch(Exception $e){
            $this->error($e->getMessage());
            //if($debug){
                echo '<pre>';print_r($this->calc);echo'</pre>';
            //}
            return null;
        }
        //execute it
        try {
            $fnc=create_function('&$self,$x','return '.$result.';');
            return $fnc($this,$x);
        } catch(Exception $e){
            $this->error($e->getMessage());
            return null;
        }
    }
}

$calculator= new calc();
$x=1.34;
echo $calculator->exec_script('tan(x)+x+4*x^3+2*x+300', $x);

echo tan($x)+$x+4*pow($x,3)+2*$x+300;


Добавлено @ 22:36
Настройка калькулятора производится в секции                
Код

                ->newOp2('- +',3)
                ->newOp2('* /',5)
                ->newOp2('|| && >> <<',4)
                ->newOp2('^',7,'pow(%s,%s)')
                ->newOp1('-','-%s')
                ->newOp1('-','-%s')
                ->newOp1('tan abs sin cos')
                ->newOpr('x','$x')
                ->newOpr('pi','pi()')
                ->newOpr('time','$self->c_getTime()')

Тут описываются бинарные, унарные операции и идентификаторы .
Бинарные операции newOp2(первый параметр) перечисляются через пробел, если все операции имеют один приоритет (второй параметр). Чем выше приоритет - тем раньше будет выполняться операция. В С с приоритетами все наоборот smile
Если бинарная операция не имеет описателя - она будет "заменятся" на саму себя. Если нужно другое толкование - нужно указать формат для sprintf'а с двумя параметрами.

newOp1 - первый параметр - операция или список через пробел, второй параметр - маска для подмены

newOpr - описание идентификаторов. (x, pi, time). При трансляци они подменяются своими эквивалентами.

Сама функция строится как функция от 2-х переменных create_function('&$self,$x', ... так что внутри текста функции можно пользоваться и $x и $self? что позволяет вызывать методы класса в нужное время.

Само выражение нечувствительно к регистру. Количество скобок, по идее, не ограниченно... Сообщения об ошибках маловразумительны, но зато они есть ;)

Это сообщение отредактировал(а) ksnk - 10.9.2010, 22:39

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  nat2php.class.php.gz 2,86 Kb


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Muerto
Дата 11.9.2010, 01:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: нет
Всего: 4



Спасибо вам большое, полезная вещь...
На свежую голову попытаюсь разобраться  smile 
Сложный вы класс написали...

Я вот задачку для себя решил вот так
Код

function rep($data){
                   $search = array(
                   '@|cookie|alert|include|script|;|"|\'@',
                   '@([.0-9]{1,})x@',
                    '@([.0-9x]{0,})\^([.0-9x]{0,})@',
                    '@([.0-9x()]{1,})(sin|cos|tan|asin|acos|atan|sqrt|abs)@',
                     '@(sin|cos|tan|asin|acos|atan|sqrt|abs)([.0-9x()]{0,})@',
                   '@x@',

                   );
                   $replace = array(
                   '',
                   '$1*x',
                   'pow($1,$2)',
                   '$1*$2',
                    '$1($2)',
                   '\$x',

                   );
                    return preg_replace($search,$replace,$data);
            }


Но так мне увы не удалось поймать все случая... хотя все стандартные варианты ловит...

Игрался немного сегодня пытался к примеру что бы делало такое (18+x)^2 но сложность была в том что когда я в регулярку добавлял что бы ловило () +-*/ оно считало верно (18+x)^2, и ставило pow(18+$x,2) но вот беда в том что если я писал (18+x)^2+2x
то Глючило... я в конце пока решил не портить что есть... 
Задание своей цели достигло... выучил я очень многое...

Вот кстати очень клевая функции 
http://learn-php.ru/graph/1000~1000~p=xtanxcosx
http://learn-php.ru/graph/1000~1000~p=xtanxatanx

Я вас кстати в Credits снизу справа добавил =-)

Это сообщение отредактировал(а) Muerto - 11.9.2010, 01:17


--------------------
user posted image
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Графика | Следующая тема »


 




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


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

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