Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: В чем ошибка построения касательной?
 
 автор: OLi   (01.04.2012 в 22:40)   письмо автору
 
 

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


<?
$i
=1;
$x1=20;
$x2=40;

while (
$i<=count($array['x'] )) {
  
$Fx=sqrt(pow($r,2)-pow($array['x'][$i],2)); //Функция окружности
$Fxh=1/(2*sqrt(pow($r,2)-pow($array['x'][$i],2)));  //Производная

$yk1=$array['x'][$i]+$Fxh*($x1-$array['x'][$i]); // График касательной со значением $x1 и $y1
$yk2=$array['x'][$i]+$Fxh*($x2-$array['x'][$i]);

imageline($img,$x1,$yk1,$x2,$yk2,$red); // вывод линии по 2 точкам


 
$i++;
  
  
  }
?>

  Ответить  
 
 автор: cheops   (02.04.2012 в 17:02)   письмо автору
 
   для: OLi   (01.04.2012 в 22:40)
 

$array['x'] - это что такое?

  Ответить  
 
 автор: OLi   (07.04.2012 в 21:17)   письмо автору
 
   для: cheops   (02.04.2012 в 17:02)
 

Это массив из координат x. это точки на окружности

  Ответить  
 
 автор: cheops   (08.04.2012 в 10:51)   письмо автору
 
   для: OLi   (07.04.2012 в 21:17)
 

Погодите, а не проще касательную вычислить аналитически, ориентируясь на радиус окружности?

  Ответить  
 
 автор: OLi   (08.04.2012 в 11:23)   письмо автору
 
   для: cheops   (08.04.2012 в 10:51)
 

В таком случае она будет перпендикулярна. Уравнение прямой(радиуса) - можно вывести - а вот уравнение прямой (касательной)?
Аналитически - по вашему это как?

  Ответить  
 
 автор: Киналь   (08.04.2012 в 11:30)   письмо автору
 
   для: OLi   (08.04.2012 в 11:23)
 

Так касательная всегда перпендикулярна радиусу, проведённому в точку касания.

  Ответить  
 
 автор: OLi   (08.04.2012 в 11:43)   письмо автору
 
   для: Киналь   (08.04.2012 в 11:30)
 

Я не утверждал обратное - вопрос в корне тот же

  Ответить  
 
 автор: Киналь   (08.04.2012 в 11:58)   письмо автору
 
   для: OLi   (08.04.2012 в 11:43)
 

Уравнение прямой, содержащей радиус: y = kx + b. Перпендикуляр к этой прямой будет описываться уравнением y = (-1/k)x + d. Зная координаты центра окружности и точки касания, можно найти k, b и d. Единственно что нужно сначала проверить, не параллелен ли радиус оси абсцисс, это особый случай (k равно бесконечности).

  Ответить  
 
 автор: OLi   (08.04.2012 в 12:17)   письмо автору
 
   для: Киналь   (08.04.2012 в 11:58)
 

Что такое k b d?
k - это вроде производная функции в начальное точке или тангенс угла

  Ответить  
 
 автор: Киналь   (08.04.2012 в 12:43)   письмо автору
 
   для: OLi   (08.04.2012 в 12:17)
 

Эм. Это коэффициенты в уравнениях, которые описывают прямую, содержащую радиус, и касательную.
Или давайте с самого начала. Вот у вас есть окружность и есть точка касания. Радиус их соединяет, то есть вы знаете координаты двух точек прямой, содержащей радиус. Зная координаты этих двух точек и зная уравнение прямой (y = kx + b), вы можете найти коэффициенты k и b?

  Ответить  
 
 автор: OLi   (08.04.2012 в 12:52)   письмо автору
 
   для: Киналь   (08.04.2012 в 12:43)
 

Можно из этих двух уравнений выразить x и приравнять из, т-к точка общая. А от туда находить все коэффициенты.
Дело в том, что я не знаю координаты центра окружности (надо вспомнить)..

  Ответить  
 
 автор: Киналь   (08.04.2012 в 13:05)   письмо автору
 
   для: OLi   (08.04.2012 в 12:52)
 

Кхм. Так. Тогда от самого начала=) Вот вы пишете:

<?php
$Fx
=sqrt(pow($r,2)-pow($array['x'][$i],2)); //Функция окружности
?>

Это вам даст окружность радиуса $r с центром в начале координат. Точнее, положительную полуокружность (sqrt() даёт только положительный результат). А если будете рисовать это с помощью GDlib, то и вовсе четверть окружности в левом верхнем углу — координаты точек могут быть только положительные.

Общее уравнение окружности выглядит так:
(x - x0)^2 + (y - y0)^2 = R^2,
где (x0, y0) — координаты центра.

Вот отсюда и давайте плясать. У вас в формуле нет ни x0, ни y0, отсюда я и заключаю, что они равны нулю и центр находится в начале координат. Если вам нужно иное, исправьте свою формулу=) В общем виде она будет выглядеть так:

y(x) = sqrt(R^2 - (x - x0)^2) + y0.

Пока всё понятно?
Если да, то вопрос к вам: как вы задаёте точку касания?

  Ответить  
 
 автор: OLi   (08.04.2012 в 13:12)   письмо автору
 
   для: Киналь   (08.04.2012 в 13:05)
 

Да - все ясно. Точка касания - это точка на окружности с координатами x,y - те, которые высчитываются у меня в коде и заносятся в массив.

  Ответить  
 
 автор: Киналь   (08.04.2012 в 13:16)   письмо автору
 
   для: OLi   (08.04.2012 в 13:12)
 

А почему в массив? У вас их много, что ли, касательных?

  Ответить  
 
 автор: OLi   (08.04.2012 в 13:22)   письмо автору
 
   для: Киналь   (08.04.2012 в 13:16)
 

Да. я равномерно расставил точки по окружности, как циферблат часов 12 3 6 9 часов, которые и занес в массив. Задача изначальная - нарисовать колесо. Касательные в данном случае к этим точкам будет одна из сторон прямоугольника (шип колеса)

  Ответить  
 
 автор: Киналь   (08.04.2012 в 13:25)   письмо автору
 
   для: OLi   (08.04.2012 в 13:22)
 

Так это же будет квадрат, описанный вокруг окружности, разве нет?
UPD Если вас не затруднит, нарисуйте, пожалуйста, желаемый конечный результат и прикрепите. Думаю, тогда будет проще обсуждать)

  Ответить  
 
 автор: OLi   (08.04.2012 в 13:33)   письмо автору
729.8 Кб
 
   для: Киналь   (08.04.2012 в 13:25)
 

Вот рисунок:

  Ответить  
 
 автор: Киналь   (08.04.2012 в 13:47)   письмо автору
 
   для: OLi   (08.04.2012 в 13:33)
 

О! Прекрасно.
Так. Ну, с «шипами» на 3, 6, 9 и 12 часов, думаю, и так всё понятно, теперь с промежуточными.

Пока рассуждаем в привычных декартовых координатах, для GDLib потом перевернём.
Возьмём для примера точку между 12 и 3. Её координаты будут (R/sqrt(2) + x0, R/sqrt(2) + y0), если я правильно понимаю. Не будем пользоваться тем, что это 45 градусов, а решим в общем виде. Обозначим для простоты эти координаты так: (x1, y1). Тогда можно записать систему уравнений:

y0 = k * x0 + b
y1 = k * x1 + b

Отсюда находим k и b. Впрочем, b нас не интересует, ну да и фиг с ним.

Теперь. Мы знаем, что искомая касательная проходит через точку (x1, y1), и она перпендикулярна радиусу. Из условия перпендикулярности следует, что её уравнением будет

y = (-1/k) * x + d,

где d мы не знаем. Но мы знаем, что она проходит через точку (x1,y1), а значит, справедливо равенство

y1 = (-1/k) * x1 + d.

Отсюда находим d. У нас есть всё, чтобы построить касательную, что мы и делаем)

Осталось только «перевернуть» это под систему координат GDLib и записать на языке PHP=)

Как говориться, прошу вопросы.

  Ответить  
 
 автор: OLi   (08.04.2012 в 16:45)   письмо автору
 
   для: Киналь   (08.04.2012 в 13:47)
 

Я не понял - почему (R/sqrt(2) + x0, R/sqrt(2) + y0) ?

  Ответить  
 
 автор: Киналь   (08.04.2012 в 16:58)   письмо автору
 
   для: OLi   (08.04.2012 в 16:45)
 

Потому что (R*cos(45 град), R*sin(45 град)). У вас же это тачка строго посередине между 12 и 3? Значит, её радиус-вектор как раз под 45 градусов и будет направлен.

  Ответить  
 
 автор: OLi   (08.04.2012 в 17:16)   письмо автору
 
   для: Киналь   (08.04.2012 в 16:58)
 

Т-е X=(R*cos(45 град)
Хорошо - а как быть для угла в 120 градусов?)

  Ответить  
 
 автор: Киналь   (08.04.2012 в 17:30)   письмо автору
 
   для: OLi   (08.04.2012 в 17:16)
 

Э-э... Извините за бестактность, но вы знакомы со школьным курсом тригонометрии? Если нет, то настоятельно рекомендую сначала его изучить.

  Ответить  
 
 автор: OLi   (08.04.2012 в 17:32)   письмо автору
 
   для: Киналь   (08.04.2012 в 17:30)
 

Да - знаком с тригонометрией, идею понял

  Ответить  
 
 автор: Киналь   (08.04.2012 в 17:33)   письмо автору
 
   для: OLi   (08.04.2012 в 17:32)
 

Прекрасно) Если что, обращайтесь)

  Ответить  
 
 автор: OLi   (08.04.2012 в 18:16)   письмо автору
 
   для: Киналь   (08.04.2012 в 17:33)
 

Размышляю:

Т-е y1 = (-1/k) * x1 + d есть уравнение касательной, при этом мы знаем 1 точку x1 y1, следовательно находим d.

Затем берем произвольную вторую точку и подставляем в это же уравнение - получаем прямую - касательную! Верно?

  Ответить  
 
 автор: Киналь   (08.04.2012 в 18:44)   письмо автору
 
   для: OLi   (08.04.2012 в 18:16)
 

Прямая у вас есть уже в тот момент, когда вы получили её уравнение. Подставляя в это уравнение любой X, вы получите соответствующий ему Y.

  Ответить  
 
 автор: OLi   (08.04.2012 в 18:56)   письмо автору
 
   для: Киналь   (08.04.2012 в 18:44)
 

Т-е я правильно рассуждаю

  Ответить  
 
 автор: Киналь   (08.04.2012 в 19:12)   письмо автору
 
   для: OLi   (08.04.2012 в 18:56)
 

Да.
Кстати, тригонометрия вам ещё понадобится — вычислять координаты углов «шипов».

  Ответить  
 
 автор: OLi   (08.04.2012 в 19:15)   письмо автору
16.5 Кб
 
   для: Киналь   (08.04.2012 в 19:12)
 

Вот что сделал:
В цикле по кол-ву точек на окружности, к которым надо провести касательную:


<?
$d
=-1*($array['y'][$i])-(-1/2)*$array['x'][$i];

$y1 = (-1/2) * $array['x'][$i]+100  $d

imageline($img,$array['x'][$i], $array['y'][$i], $array['x'][$i]+100$y1,$red);

?>


Результат на скрине.

  Ответить  
 
 автор: Киналь   (08.04.2012 в 19:24)   письмо автору
 
   для: OLi   (08.04.2012 в 19:15)
 

То есть
d = -y + x/2.

Почему так?

  Ответить  
 
 автор: OLi   (08.04.2012 в 19:26)   письмо автору
 
   для: Киналь   (08.04.2012 в 19:24)
 

Потому что перенес все в одну часть и поменял знаки.

Было так:

$y1 = (-1/2) * $array['x'][$i] + $d;  

Стало:

$d=-$y1+1/2*$array['x'][$i]

  Ответить  
 
 автор: Киналь   (08.04.2012 в 19:28)   письмо автору
 
   для: OLi   (08.04.2012 в 19:26)
 


$y1 = (-1/2) * $array['x'][$i] + $d;


А почему -1/2? Должно быть -1/k, а k для каждого случая нужно высчитывать.

  Ответить  
 
 автор: OLi   (08.04.2012 в 19:36)   письмо автору
 
   для: Киналь   (08.04.2012 в 19:28)
 

k брать как sin(y)/cos(x)?

  Ответить  
 
 автор: Киналь   (08.04.2012 в 19:52)   письмо автору
 
   для: OLi   (08.04.2012 в 19:36)
 

Нет. Находить из системы, как я написал выше. И не забывайте, что координаты "перевёрнуты".

  Ответить  
 
 автор: OLi   (08.04.2012 в 20:18)   письмо автору
 
   для: Киналь   (08.04.2012 в 19:52)
 

Из уравнения y0 = k * x0 + b следует, что y0 и x0 это координаты точки на окружности, b=0
Отсюда k= y0/x0

  Ответить  
 
 автор: Киналь   (08.04.2012 в 20:28)   письмо автору
 
   для: OLi   (08.04.2012 в 20:18)
 

Нет, это координаты центра окружности.

  Ответить  
 
 автор: OLi   (08.04.2012 в 20:34)   письмо автору
 
   для: Киналь   (08.04.2012 в 20:28)
 

Ах да - ну центр всегда один и тот же - значит и k равно const

  Ответить  
 
 автор: Киналь   (08.04.2012 в 20:52)   письмо автору
 
   для: OLi   (08.04.2012 в 20:34)
 

Я, пожалуй, повторю свой бестактный вопрос...
k — это тангенс угла наклона прямой, и из постоянства центра никак не следует постоянство этого тангенса.

  Ответить  
 
 автор: OLi   (08.04.2012 в 21:35)   письмо автору
 
   для: Киналь   (08.04.2012 в 20:52)
 

Да уж - вспоминая элементарное - уносит в в сторону. Может брать тогда производную от функции в точке?

  Ответить  
 
 автор: Киналь   (08.04.2012 в 21:43)   письмо автору
 
   для: OLi   (08.04.2012 в 21:35)
 

Можно всё, только чем вам не нравиться тот способ, что я описал выше?

  Ответить  
 
 автор: OLi   (08.04.2012 в 21:48)   письмо автору
 
   для: Киналь   (08.04.2012 в 21:43)
 

Нужен пример на числах для тангенса угла- и думаю тему можно закрывать.

  Ответить  
 
 автор: Киналь   (08.04.2012 в 21:56)   письмо автору
 
   для: OLi   (08.04.2012 в 21:48)
 

Если координаты точки на окружности — (82, 75), а координаты центра окружности — (10, 20), то тангенс наклона прямой, их соединяющей, будет (80-10) / (75-20).

  Ответить  
 
 автор: OLi   (08.04.2012 в 22:09)   письмо автору
 
   для: Киналь   (08.04.2012 в 21:56)
 

В моем случае это будет отношение x/y т-к x0=y0=0
При таком раскладе - у меня скрипт уходит в бесконечные раздумья
$k=$array['x'][$i]/$array['y'][$i];

$d=-1*($array['y'][$i])-(-1/$k)*$array['x'][$i];

  Ответить  
 
 автор: Киналь   (08.04.2012 в 22:24)   письмо автору
 
   для: OLi   (08.04.2012 в 22:09)
 

Прошу прощения — не x/y, а y/x, конечно. Видимо, поэтому он и «задумывается».
Так что советую вам перепроверить все мои выкладки. Меня всегда в школе ругали за невнимательность, мог и сейчас что-нибудь спутать)

  Ответить  
 
 автор: OLi   (08.04.2012 в 22:29)   письмо автору
 
   для: Киналь   (08.04.2012 в 22:24)
 

Ох. не выдает изображение в браузер:
<?
  
while ($i<=count($array['x'] )) {
  


$d=-1*($array['y'][$i])-(-1/($array['y'][$i]/$array['x'][$i]))*$array['x'][$i];

$y1 = (-1/$array['x']/($array['y'][$i]/$array['x'][$i])) * $array['x'][$i]+100  $d

imageline($img,$array['x'][$i], $array['y'][$i], $array['x'][$i]+100$y1,$red);




  
imagerectangle($img,$array['x'][$i],$array['y'][$i],($array['x'][$i]+30),($array['y'][$i]+20),$red);
  
$i++;
  
  
  }
?>

  Ответить  
 
 автор: Киналь   (08.04.2012 в 22:34)   письмо автору
 
   для: OLi   (08.04.2012 в 22:29)
 

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

  Ответить  
 
 автор: OLi   (08.04.2012 в 23:09)   письмо автору
 
   для: Киналь   (08.04.2012 в 22:34)
 

ох - по-моему, приехал..ошибки из-за деления на 0.
Вот это echo $array['x'][$i]/$array['y'][$i]/$array['x'][$i].'<br>';
дает:
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
-4.65661308992E-10
4.65661265624E-10
0.00671140939597
0.0196078431373
0.00502512562814
1

в массиве x и y все хорошо - значения как отрицательные так и положительные без 0

  Ответить  
 
 автор: Киналь   (08.04.2012 в 23:17)   письмо автору
 
   для: OLi   (08.04.2012 в 23:09)
 

Проверяйте мои выкладки, проверяйте свои исходные данные. Больше я вам ничем не могу помочь. Не писать же за вас)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования