Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 03.09.2013, 20:25
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 31  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Зачем вы так сложно делаете все? Углы вообще считать не нужно нигде!

Код AS3:
const A:Point = ...;
const B:Point = ...;
const C:Point = ...;
 
const norm1 : Point = B.subtract(A);
norm1.normalize(1);
const norm2 : Point = C.subtract(A);
norm2.normalize(1);
const DR : Point = norm1.add(norm2);
const D:Point = A.add(DR);
Все. Точка D лежит на биссектрисе AD угла CAB. Можно еще координаты DR пополам поделить (если не понятно, что оно вообще вычисляет). Единственное исключение. Если DR получилась (0, 0) (т.е. угол развернутый), можно просто вручную повернуть на 90 градусов любую нормаль и получить DR.

Старый 03.09.2013, 21:33
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 32  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Цитата:
Зная угол и начало координат можно определить проекции это и будут координаты.
Как? После того, как я нахожу угол альфа, и делю его пополам ( получается биссектриса ), то я представляю отрезок AD как гипотенузу треугольника ADE1,ADE2 ( или можно сказать, что этот отрезок - обрезанная биссектриса ) и координаты точки D я ищу по формуле
Код AS3:
D.x = A.x + (lengthHypotenuseAD * cos(angleBAC))
D.y = A.y + (lengthHypotenuseAD * sin(angleBAC))
но в этой формуле не хватает направления. я буду рад любой помощи!)
Цитата:
Зачем вы так сложно делаете все? Углы вообще считать не нужно нигде!
я не понимаю, как это не нужно?) Мне очень нужно, я только учусь и мне хочется все самому поделать, что бы понять как тут все устроенно.

Старый 03.09.2013, 22:07
belv вне форума Посмотреть профиль Отправить личное сообщение для belv Найти все сообщения от belv
  № 33  
Ответить с цитированием
belv
[+1 16.07.13]
[+4 16.07.13]

Регистрация: Oct 2005
Сообщений: 217
maxkar по Вашему примеру получается, чем меньше угол, тем длиннее биссектриса получается, хотя должно быть наоборот, ведь вписываемая окружность уменьшается и ее центр далек от координат точки D.
Вложения
Тип файла: swf bisector1.swf (1.1 Кб, 20 просмотров)

Старый 03.09.2013, 22:15
KumoKairo вне форума Посмотреть профиль Отправить личное сообщение для KumoKairo Найти все сообщения от KumoKairo
  № 34  
Ответить с цитированием
KumoKairo
 
Аватар для KumoKairo

Регистрация: Jan 2013
Сообщений: 550
Записей в блоге: 1
Цитата:
Хочу поинтересоваться почему так?
Потому что там косинус получался больше 1 в одном месте - забыл квадрат в формуле числителя ;D

maxkar, ваш метод нахождения биссектрисы работает почему то только для прямого угла, а для других он как то криво считает - я выводил на экран ради интереса

Короче в итоге получилось что-то такое, не знаю насколько эффективен код, но по крайней мере все по полочкам и все понятно:
Код AS3:
package  
{
	import flash.display.Sprite;
	import flash.geom.Point;
 
	public class VectorRotate extends Sprite
	{
 
		public function VectorRotate() 
		{
			//Двигаем весь спрайт вниз и вправо, для наглядности
			x = 150;
			y = 500;
 
			//Переворачиваем картинку вверх ногами, потому что флеш рисует сверху вниз
			scaleY = -1;
 
			//Вспомогательный множитель, увеличивает размер начальных векторов
			var helpingScale:Number = 1000;
 
			var pointA:Point = new Point(1 * helpingScale, 1 * helpingScale);
			var pointB:Point = new Point(1.1 * helpingScale, 2 * helpingScale);
			var pointC:Point = new Point(2 * helpingScale, 1.2 * helpingScale);
			var radius:Number = 50;
 
			//Двигаем вектор B к началу координат
			var movedB: Point = pointB.subtract(pointA);
			//Запоминаем фактор нормировки вектора (потом пригодится);
			var normalizeFactorB:Number = Math.sqrt(pointB.x * pointB.x + pointB.y + pointB.y);
			//Нормируем вектор
			movedB.normalize(1);
 
			//По примеру с верхним, один в один
			var movedC: Point = pointC.subtract(pointA);
			var normalizeFactorC:Number = Math.sqrt(pointC.x * pointC.x + pointC.y + pointC.y);
			movedC.normalize(1);
			//===
 
			//Векторы - перпендикуляры
			var vectorBD:Point = new Point(movedB.y, - movedB.x);
			var vectorCD:Point = new Point(- movedC.y, movedC.x);
 
			//Числитель формулы нахождения угла между векторами
			var numerator: Number = movedB.x * movedC.x + movedB.y * movedC.y;
			//Знаменатель формулы нахождения угла между векторами
			var divisor: Number = Math.sqrt(movedB.x * movedB.x + movedB.y * movedB.y) * Math.sqrt(movedC.x * movedC.x + movedC.y * movedC.y);
			//Половина угла между векторами
			var angle: Number = Math.acos(numerator / divisor) / 2;
 
			//Длина отрезков AB и AC
			var tangent:Number = radius / Math.tan(angle);
 
			//"Отрезаем" от векторов отрезки полученной на предыдущем этапе длины
			var vectorAB:Point = new Point(movedB.x * tangent, movedB.y * tangent);
			var vectorAC:Point = new Point(movedC.x * tangent, movedC.y * tangent);
 
			//Находим центр окружности
			//Для этого возьмем один из перпендикуляров
			var centerOfCircle:Point = vectorBD.clone();
			//Нормируем его
			centerOfCircle.normalize(1);
			//Находим новую длину
			centerOfCircle.x = centerOfCircle.x * radius + vectorAB.x;
			centerOfCircle.y = centerOfCircle.y * radius + vectorAB.y;
 
			//Рисуем линии
			graphics.lineStyle(1, 0xff0000);
			graphics.moveTo(0, 0);
			graphics.lineTo(movedB.x * normalizeFactorB, movedB.y * normalizeFactorB);
 
			graphics.lineStyle(1, 0xff0000);
			graphics.moveTo(0, 0);
			graphics.lineTo(movedC.x * normalizeFactorC, movedC.y * normalizeFactorC);
 
			graphics.lineStyle(1, 0x00ff00);
			graphics.moveTo(vectorAB.x, vectorAB.y);
			graphics.lineTo(vectorBD.x * normalizeFactorB + vectorAB.x, vectorBD.y * normalizeFactorB + vectorAB.y);
 
			graphics.moveTo(vectorAC.x, vectorAC.y);
			graphics.lineTo(vectorCD.x * normalizeFactorC + vectorAC.x, vectorCD.y * normalizeFactorC + vectorAC.y);
 
			graphics.lineStyle(1, 0x0000ff);
			graphics.moveTo(centerOfCircle.x, centerOfCircle.y);
			graphics.drawCircle(centerOfCircle.x, centerOfCircle.y, radius);
		}
 
	}
 
}
Название: 1.png
Просмотров: 653

Размер: 7.3 КбНазвание: 2.png
Просмотров: 633

Размер: 7.1 КбНазвание: 3.png
Просмотров: 590

Размер: 6.6 Кб


Последний раз редактировалось KumoKairo; 03.09.2013 в 22:47.
Старый 03.09.2013, 22:16
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 35  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
углы нужны, дугу же надо как-то рисовать
такой вот вариант (по схеме, что Wolsh нарисовал в #10)
Код AS3:
package
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Point;
 
	public class Main extends Sprite
	{
 
		public function Main():void
		{
			var a:Point = new Point(150, 50);
			var b:Point = new Point(250, 200);
			var c:Point = new Point(100, 300);
			var d:Point = new Point(50, 150);
			var e:Point = new Point(150, 200);
			var f:Point = new Point(150, 150);
 
			var points:Vector.<Point> = Vector.<Point>([a, b, c]);
			//var points:Vector.<Point> = Vector.<Point>([a, f, b, e, c, d]);
			//var points:Vector.<Point> = Vector.<Point>([a, d, c, b]);
 
			graphics.lineStyle(0, 0x808080);
			drawRoundedPoly(graphics, points);
			graphics.lineStyle(0, 0xFF0000);
			drawRoundedPoly(graphics, points, 20);
		}
 
		public static function drawRoundedPoly(g:Graphics, points:Vector.<Point>, radius:Number = 0, tol:Number = 0.1):void
		{
 
			var len:int = points.length;
			for (var i:int = 0; i < len; i++)
			{
				var p0:Point = points[i];
				var p1:Point = points[(i + 1) % len];
				var p2:Point = points[(i + 2) % len];
 
 
				var d1:Point = p1.subtract(p0);
				var d2:Point = p1.subtract(p2);
				//  углы лучей
				var a1:Number = Math.atan2(d1.y, d1.x);
				var a2:Number = Math.atan2(d2.y, d2.x);
 
				// направление обхода
				var cw:Boolean = (p1.x - p0.x) * (p2.y - p1.y) - (p1.y - p0.y) * (p2.x - p1.x) > 0;
 
				// расстояние до центра дуги
				var dist:Number = radius / Math.sin(0.5 * (a2 - a1));
				// биссектриса
				var dir:Number = 0.5 * (a1 + a2);
				if (!cw) dir += Math.PI;
				// центр дуги
				var cX:Number = p1.x + dist * Math.cos(dir);
				var cY:Number = p1.y + dist * Math.sin(dir);
 
				// углы дуги
				a1 += (cw ? -0.5 : 0.5) * Math.PI;
				a2 += (cw ? 0.5 : -0.5) * Math.PI;
 
				// избыточный виток, если есть
				while (a2 - a1 > 2 * Math.PI) a2 -= 2 * Math.PI;
				while (a1 - a2 > 2 * Math.PI) a1 -= 2 * Math.PI;
 
				// рисуем
				var n:int = Math.abs(a2 - a1) / tol;
				var da:Number = (a2 - a1) / n;
				for (var j:int = 0; j < n; j++)
				{
 
					var a:Number = a1 + j * da;
					var rX:Number = cX + radius * Math.cos(a);
					var rY:Number = cY + radius * Math.sin(a);
 
					if (!i && !j)
					{
						// самая первая точка
						var tX0:Number = rX;
						var tY0:Number = rY;
						g.moveTo(rX, rY);
					}
					else
					{
						g.lineTo(rX, rY);
					}
 
				}
 
			}
			//замыкаем на первую точку
			g.lineTo(tX0, tY0);
 
		}
 
	}
 
}

Старый 03.09.2013, 22:27
Akopalipsis вне форума Посмотреть профиль Найти все сообщения от Akopalipsis
  № 36  
Ответить с цитированием
Akopalipsis
Banned
[+4 24.02.14]
[+4 07.11.13]
[+ 13.03.14]

Регистрация: Mar 2013
Сообщений: 1,864
Ну почему у Вас у всех с поинтами?) Это как геометрию учить глядя на портрет Архимеда.
я не понимаю почему там так.. или так... Лично у меня нет цели сделать треугольник с скруглёными углами, его и так нарисовать можно. я взялся учить это для того, чтобы вернуться в тему с линиями в виде ростков, со знаниями, чтобы взять под контроль угол и его направление. Вот крутится что то в голове, а не пойму как это назвать. Пойду ещё учить.)

Старый 03.09.2013, 22:29
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 37  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Ну правильно. В ваших формулах вы совсем не тот угол и не от того считаете. Или нужно считать все углы от оси ox (с соответствующими коррекциями). Или для ваших синусов брать в качестве базового вектора одну из сторон и делать второе преобразование. Ну и еще помучаться с направлением вращения (потому что можно по пьяни с коррекциями построить и биссектрису внешнего угла в некоторых случаях).

Цитата:
я не понимаю, как это не нужно?) Мне очень нужно, я только учусь и мне хочется все самому поделать, что бы понять как тут все устроенно.
А зачем там углы? Ну кроме как в определении биссектрисы? Я вам с использованием простейших действий построил точку на биссектрисе. Никакой тригонометрии нет. Могу даже точку на противоположной стороне треугольника построить. Там нужно вспомнить, в каком отношении биссектриса делит противоположную сторону. Причем, что характерно, для той теоремы и для вычислений тоже не нужно никакой тригонометрии.

Чтобы учиться, я бы рекомендовал почитать сначала учебник по линейной алгебре (для первых курсов). Там ничего такого недоступного нет. Затем порешать задачки на простую геометрию (без стереометрии). Для закрепления навыков можно школьные учебники по стереометрии взять и порешать задачи оттуда. В большинстве случаев там афинные вычисления или просто вычисления в координатах (собственно, афинные вычисления - варианты на тему неортонормированных базисов). Тригонометрия на практике нужна, но достаточно редко. В векторах и матрицах трансформации большинство задач решать проще.

belv, KumoKairo
Да, я про исходную задачу забыл. Если хочется нужный радиус окружности, то нужно DR нормировать. Но это просто. Если DR векторно умножить на norm1 (или norm2) то с точностью до знака получится 2*sin(CAB/2). Ну а дальше считаем нужный нормирующий коэффициент.

P.S. А в углах лучше уже потом на местности ориентироваться. Вычислить все точки касания (без углов!). И затем уже из центра окружности смотреть, под какими углами видны точки дуги.

Старый 03.09.2013, 22:32
KumoKairo вне форума Посмотреть профиль Отправить личное сообщение для KumoKairo Найти все сообщения от KumoKairo
  № 38  
Ответить с цитированием
KumoKairo
 
Аватар для KumoKairo

Регистрация: Jan 2013
Сообщений: 550
Записей в блоге: 1
Akopalipsis, пойнт - это вектор с началом в точке (0, 0), это уже обсуждали в этой теме

Старый 03.09.2013, 22:41
silin вне форума Посмотреть профиль Посетить домашнюю страницу silin Найти все сообщения от silin
  № 39  
Ответить с цитированием
silin
 
Аватар для silin

блогер
Регистрация: Mar 2003
Адрес: Моск. обл.
Сообщений: 5,269
Записей в блоге: 6
Цитата:
Сообщение от maxkar Посмотреть сообщение
А в углах лучше уже потом на местности ориентироваться. Вычислить все точки касания (без углов!). И затем уже из центра окружности смотреть, под какими углами видны точки дуги.
дело хозяйское, конечно, но мне кажется проще точки касания из углов получить, а не наоборот
к слову, что-то и сообразить сходу не могу как можно вычислить все точки касания (без углов!)

Старый 03.09.2013, 22:52
maxkar вне форума Посмотреть профиль Отправить личное сообщение для maxkar Найти все сообщения от maxkar
  № 40  
Ответить с цитированием
maxkar

Регистрация: Nov 2010
Сообщений: 497
Цитата:
к слову, что-то и сообразить сходу не могу как можно вычислить все точки касания (без углов!)
В тех же обозначениях, что выше (и r - требуемый радиус окружности):
Код AS3:
const normRatio : Number = r / Math.abs(DR.x * norm1.y - DR.y * norm1.x);
DR.x *= normRatio;
DR.y *= normRatio;
const center : Point = A.add(DR);
const touchRatio : Number = DR.x * norm1.x + DR.y * norm1.y;
const touch1 : Point = new Point(A.x + touchRatio * norm1.x, A.y + touchRatio * norm1.y);
const touch2 : Point = new Point(A.x + touchRatio * norm2.x, A.y + touchRatio * norm2.y);
И ни одного явного угла Все в радикалах.

Создать новую тему Ответ Часовой пояс GMT +4, время: 16:52.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 16:52.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.