<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: Узнать знак поворота.]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=17565</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17565&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: Узнать знак поворота.».]]></description>
		<lastBuildDate>Thu, 19 Jan 2023 14:58:51 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156445#p156445</link>
			<description><![CDATA[<p>Коллеги, благодарю!<br />Правда я зарегистрировался в chat.open.ai и заморочил по этому поводу ChatGPT.<br />Вот дополненный вариант:<br /></p><div class="codebox"><pre><code>
Cond(reason_num) {	; -&gt; string
	if (!reason_num)
		return &quot;без поворота&quot;
	return reason_num &gt; 0 ? &quot;против часовой стрелки&quot; : &quot;по часовой стрелке&quot;
}

class Point {
	__New(x, y) {
		this.x := x
		this.y := y
	}
	
	Dot(other_point) {		; -&gt; float
		return this.x * other_point.x + this.y * other_point.y
	}
	
	Distance(other_point) { ; -&gt; float
		diff_x := this.x - other_point.x
		diff_y := this.y - other_point.y
		return Sqrt(diff_x**2 + diff_y**2)
	}
}

class Vec {
	__New(start_point, end_point) {
		this.start := start_point
		this.end := end_point
	}
	
	CrossProd(other_vec) {	; -&gt; number
		r1 := (this.end.x - this.start.x) * (other_vec.end.y - this.start.y)
		r2 := (this.end.y - this.start.y) * (other_vec.end.x - this.start.x)
		return r1 - r2
	}
	
	DiffPoint() {			; -&gt; Point
		s := this.start
		e := this.end
		return new Point(e.x - s.x, e.y - s.y)
	}
	
	Angle(other_vec) {		; -&gt; float
		dp1 := this.DiffPoint()
		dp2 := other_vec.DiffPoint()
		return ACos(dp1.Dot(dp2) / dp1.Dot(dp1)**0.5 / dp2.Dot(dp2)**0.5) * 57.29578
	}
}

src_point  := new Point(0, 0)
dest_point := new Point(-2, -1)
anotnter_same_point := new Point(2, -1)
perpendicular_point := new Point(-2, 0)
other_perpend_point := new Point(2, 0)
in_src_vec_point := new Point(0, 7)
reverse_src_vec_point := new Point(0, -7)

; Вектор произвольной длины по оси Y в текущем направлении
vec1 := new Vec(src_point, new Point(0, 1))

vec2 := new Vec(src_point, dest_point)
vec3 := new Vec(src_point, anotnter_same_point)
vec4 := new Vec(src_point, perpendicular_point)
vec5 := new Vec(src_point, other_perpend_point)
vec6 := new Vec(src_point, in_src_vec_point)
vec7 := new Vec(src_point, reverse_src_vec_point)


MsgBox,0x40,dest_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec2)
				, src_point.Distance(dest_point)
				, Cond(vec1.CrossProd(vec2)))
				
MsgBox,0x40,anotnter_same_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec3)
				, src_point.Distance(anotnter_same_point)
				, Cond(vec1.CrossProd(vec3)))
				
MsgBox,0x40,perpendicular_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec4)
				, src_point.Distance(perpendicular_point)
				, Cond(vec1.CrossProd(vec4)))
				
MsgBox,0x40,other_perpend_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec5)
				, src_point.Distance(other_perpend_point)
				, Cond(vec1.CrossProd(vec5)))
				
MsgBox,0x40,in_src_vec_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec6)
				, src_point.Distance(in_src_vec_point)
				, Cond(vec1.CrossProd(vec6)))
				
MsgBox,0x40,reverse_src_vec_point,% Format(&quot;Угол: {} | расстояние: {} | поворот: {}&quot;
				, vec1.Angle(vec7)
				, src_point.Distance(reverse_src_vec_point)
				, Cond(vec1.CrossProd(vec7)))
</code></pre></div><p>Если интересно, так мы с ним поболтали, потом у меня кончился лимит на количество запросов в час, но я уже всё выяснил к тому моменту.<br /><a href="https://ibb.co/jgB0DS7"><span class="postimg"><img src="https://i.ibb.co/jgB0DS7/ChatGPT.jpg" alt="https://i.ibb.co/jgB0DS7/ChatGPT.jpg" /></span></a></p>]]></description>
			<author><![CDATA[null@example.com (KusochekDobra)]]></author>
			<pubDate>Thu, 19 Jan 2023 14:58:51 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156445#p156445</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156444#p156444</link>
			<description><![CDATA[<p><strong>KusochekDobra</strong><br />Да, вы правы в том, что подход, который я описал ранее, будет работать только для определенного направления от А до В и не будет применим для других точек.<br />Что касается скалярного произведения, да, это сумма произведений соответствующих компонентов двух векторов. И в этом случае метод Point.Dot() вычисляет точечное произведение двух векторов, заданных координатами их конечных точек. Это эквивалентно скалярному произведению двух векторов.<br />Извиняюсь, я перепутал произведения. Для нахождения направления вращения от A до B лучше использовать векторное произведение двух векторов. Оно будет положительным, если угол между двумя векторами направлен против часовой стрелки, и отрицательным, если он направлен по часовой стрелке.</p>]]></description>
			<author><![CDATA[null@example.com (Madmer)]]></author>
			<pubDate>Thu, 19 Jan 2023 13:14:47 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156444#p156444</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156443#p156443</link>
			<description><![CDATA[<p>Вот <a href="https://habr.com/ru/post/148325/">тут</a> не то, что нужно?</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Thu, 19 Jan 2023 10:21:45 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156443#p156443</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156442#p156442</link>
			<description><![CDATA[<p>Прошу прощения, за 20 с лишним лет не довелось воспользоваться тригонометрией ни разу, так что всё поистёрлось в памяти.</p><p>Можно представить, что машина расположена в координатах[0: 0] и она направлена на север, обозначая свой угол по отношению к началу отсчёта равным 90 градусов. Навигатору поступила команда прибыть в точку [-2: -1], для чего он вычисляет имеющимися средствами угол поворота(116.56505117707799) и дистанцию(2.23606797749979). Для наблюдателя рисунка, очевидно, что к текущему углу нужно прибавить положительное значение угла, чтобы поворот оказался верным. Вот только до точки [2: -1] возвращается тот же угол и дистанция.<br />Несколько упростил код расчёта угла между векторами <a href="https://stackoverflow.com/questions/28260962/calculating-angles-between-line-segments-python-with-math-atan2/28261304#28261304">отсюда</a>.<br /></p><div class="codebox"><pre><code>
class Point {
	__New(x, y) {
		this.x := x
		this.y := y
	}
	
	Dot(other_point) {		; -&gt; float
		return this.x * other_point.x + this.y * other_point.y
	}
	
	Distance(other_point) { ; -&gt; float
		diff_x := this.x - other_point.x
		diff_y := this.y - other_point.y
		return Sqrt(diff_x**2 + diff_y**2)
	}
}

class Vec {
	__New(start_point, end_point) {
		this.start := start_point
		this.end := end_point
	}
	
	DiffPoint() {			; -&gt; Point
		s := this.start
		e := this.end
		return new Point(e.x - s.x, e.y - s.y)
	}
	
	Angle(other_vec) {		; -&gt; float
		dp1 := this.DiffPoint()
		dp2 := other_vec.DiffPoint()
		return ACos(dp1.Dot(dp2) / dp1.Dot(dp1)**0.5 / dp2.Dot(dp2)**0.5) * 57.29578
	}
}

src_point  := new Point(0, 0)
dest_point := new Point(-2, -1)
anotnter_same_point := new Point(2, -1)
perpendicular_point := new Point(-2, 0)

; Вектор произвольной длины по оси Y в текущем направлении
vec1 := new Vec(src_point, new Point(0, 1))

vec2 := new Vec(src_point, dest_point)
vec3 := new Vec(src_point, anotnter_same_point)
vec4 := new Vec(src_point, perpendicular_point)

MsgBox % &quot;Угол: &quot; . vec1.Angle(vec2) . &quot; | расстояние: &quot; . src_point.Distance(dest_point)
MsgBox % &quot;Угол: &quot; . vec1.Angle(vec3) . &quot; | расстояние: &quot; . src_point.Distance(anotnter_same_point)
MsgBox % &quot;Угол: &quot; . vec1.Angle(vec4) . &quot; | расстояние: &quot; . src_point.Distance(perpendicular_point)
</code></pre></div><div class="quotebox"><cite>Madmer пишет:</cite><blockquote><p>Чтобы определить направление поворота из точки A в точку B, вам нужно сравнить угол между вектором от A до B и вектором от A до положительной оси X (которая имеет угол 90 градусов по отношению к A). Если угол между двумя векторами находится в диапазоне [0,90], то поворот происходит вправо. ...</p></blockquote></div><p>Но потом, например, вектор будет иметь направление A -&gt; B и находиться в точке B и для следующей произвольной точки, например в [-3: 2], это уже не сработает.</p><div class="quotebox"><cite>Madmer пишет:</cite><blockquote><p>Также можно использовать скалярное произведение. Скалярное произведение двух векторов будет положительным, если угол между ними против часовой стрелки, и отрицательным  по часовой.</p></blockquote></div><p>Простите, если путаю, но при гуглении, под векторами мне всё время предстают последовательности чисел, аля [1, 3, 5] и так далее и скалярное произведение двух векторов выглядит как сумма последовательно перемноженных членов этих векторов. А тут вектор — это последовательность точек. Если я правильно <a href="https://www.yaklass.ru/p/geometria/9-klass/sootnosheniia-mezhdu-storonami-i-uglami-treugolnika-skaliarnoe-proizvedeni_-9222/skaliarnoe-proizvedenie-vektorov-svoistva-9526/re-4c246f69-ab7f-4efb-8d1f-5c49e95d1c06">понимаю &quot;Скалярное произведение векторов, заданных координатами&quot;</a>, то метод Point.Dot() делает как раз это. Но для двух разных точек они эквивалентны:<br /></p><div class="codebox"><pre><code>
p1 := new Point(0, 0)
p2 := new Point(0, 1)   ; Произвольная точка на векторе
p3 := new Point(2, -1)
p4 := new Point(-2, -1)

MsgBox % p2.Dot(p3)
MsgBox % p2.Dot(p4)
</code></pre></div><p>Я несомненно что-то упускаю и не могу понять, что.</p>]]></description>
			<author><![CDATA[null@example.com (KusochekDobra)]]></author>
			<pubDate>Thu, 19 Jan 2023 09:49:36 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156442#p156442</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156438#p156438</link>
			<description><![CDATA[<p><strong>KusochekDobra</strong><br />Чтобы определить направление поворота из точки A в точку B, вам нужно сравнить угол между вектором от A до B и вектором от A до положительной оси X (которая имеет угол 90 градусов по отношению к A). Если угол между двумя векторами находится в диапазоне [0,90], то поворот происходит вправо. Если угол находится в диапазоне [90,180], то поворот осуществляется влево.<br />Вы можете использовать функцию, которая вычисляет угол между двумя векторами, чтобы определить это. Если возвращаемый угол меньше 90, вы можете добавить его к текущему углу A -&gt; [0: любое значение Y]. Если угол больше 90, вы должны вычесть его из текущего угла.<br />Также можно использовать скалярное произведение. Скалярное произведение двух векторов будет положительным, если угол между ними против часовой стрелки, и отрицательным&nbsp; по часовой.</p>]]></description>
			<author><![CDATA[null@example.com (Madmer)]]></author>
			<pubDate>Thu, 19 Jan 2023 00:03:50 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156438#p156438</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156434#p156434</link>
			<description><![CDATA[<p>Судя по картинке, задача простая. Но, когда начинаешь читать текст, ничего не понятно.</p><p>Добавлено:<br />Точки принято обозначать заглавными латинскими буквами, а углы - греческими.</p>]]></description>
			<author><![CDATA[null@example.com (ypppu)]]></author>
			<pubDate>Wed, 18 Jan 2023 19:10:03 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156434#p156434</guid>
		</item>
		<item>
			<title><![CDATA[AHK: Узнать знак поворота.]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=156426#p156426</link>
			<description><![CDATA[<p>Всем добра!</p><p>Коллеги, подскажите пожалуйста, как узнать знак поворота, отталкиваясь лишь от следующего:<br />Известно положение точки &quot;A&quot; в координатах [0, 0] и, что вектор всех точек направленных от неё имеет угол 90 градусов по отношению к оси &quot;X&quot;.<br />Известно положение точки &quot;B&quot; в координатах [-2, -1].<br />Функция, вычисляющая угол между двумя векторами возвращает положительное значение градусов в диапазоне [0: 180] включительно.</p><p>То есть:<br /></p><div class="codebox"><pre><code>
A-&gt;B и A-&gt;[0: любое значение Y] == (~116,57 градусов) == A-&gt;[0: любое значение Y] и [2: -1]
</code></pre></div><p>Как вычислить, следует результат функции вычитать из текущего значения угла, или прибавлять, чтобы развернуть вектор по направлению из &quot;A&quot; в &quot;B&quot;, а не в другую сторону?</p><p><a href="https://imgbb.com/"><span class="postimg"><img src="https://i.ibb.co/hMp9gxW/shot.jpg" alt="https://i.ibb.co/hMp9gxW/shot.jpg" /></span></a></p>]]></description>
			<author><![CDATA[null@example.com (KusochekDobra)]]></author>
			<pubDate>Wed, 18 Jan 2023 11:29:46 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=156426#p156426</guid>
		</item>
	</channel>
</rss>
