|
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Зачем вы так сложно делаете все? Углы вообще считать не нужно нигде!
Все. Точка D лежит на биссектрисе AD угла CAB. Можно еще координаты DR пополам поделить (если не понятно, что оно вообще вычисляет). Единственное исключение. Если DR получилась (0, 0) (т.е. угол развернутый), можно просто вручную повернуть на 90 градусов любую нормаль и получить DR. |
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
D.x = A.x + (lengthHypotenuseAD * cos(angleBAC)) D.y = A.y + (lengthHypotenuseAD * sin(angleBAC)) Цитата:
|
|
|||||
[+1 16.07.13]
[+4 16.07.13] Регистрация: Oct 2005
Сообщений: 217
|
maxkar по Вашему примеру получается, чем меньше угол, тем длиннее биссектриса получается, хотя должно быть наоборот, ведь вписываемая окружность уменьшается и ее центр далек от координат точки D.
|
|
|||||
Цитата:
maxkar, ваш метод нахождения биссектрисы работает почему то только для прямого угла, а для других он как то криво считает - я выводил на экран ради интереса Короче в итоге получилось что-то такое, не знаю насколько эффективен код, но по крайней мере все по полочкам и все понятно: 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); } } } Последний раз редактировалось KumoKairo; 03.09.2013 в 22:47. |
|
|||||
углы нужны, дугу же надо как-то рисовать
такой вот вариант (по схеме, что Wolsh нарисовал в #10) 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); } } } |
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Ну почему у Вас у всех с поинтами?) Это как геометрию учить глядя на портрет Архимеда.
я не понимаю почему там так.. или так... Лично у меня нет цели сделать треугольник с скруглёными углами, его и так нарисовать можно. я взялся учить это для того, чтобы вернуться в тему с линиями в виде ростков, со знаниями, чтобы взять под контроль угол и его направление. Вот крутится что то в голове, а не пойму как это назвать. Пойду ещё учить.) |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Ну правильно. В ваших формулах вы совсем не тот угол и не от того считаете. Или нужно считать все углы от оси ox (с соответствующими коррекциями). Или для ваших синусов брать в качестве базового вектора одну из сторон и делать второе преобразование. Ну и еще помучаться с направлением вращения (потому что можно по пьяни с коррекциями построить и биссектрису внешнего угла в некоторых случаях).
Цитата:
Чтобы учиться, я бы рекомендовал почитать сначала учебник по линейной алгебре (для первых курсов). Там ничего такого недоступного нет. Затем порешать задачки на простую геометрию (без стереометрии). Для закрепления навыков можно школьные учебники по стереометрии взять и порешать задачи оттуда. В большинстве случаев там афинные вычисления или просто вычисления в координатах (собственно, афинные вычисления - варианты на тему неортонормированных базисов). Тригонометрия на практике нужна, но достаточно редко. В векторах и матрицах трансформации большинство задач решать проще. belv, KumoKairo Да, я про исходную задачу забыл. Если хочется нужный радиус окружности, то нужно DR нормировать. Но это просто. Если DR векторно умножить на norm1 (или norm2) то с точностью до знака получится 2*sin(CAB/2). Ну а дальше считаем нужный нормирующий коэффициент. P.S. А в углах лучше уже потом на местности ориентироваться. Вычислить все точки касания (без углов!). И затем уже из центра окружности смотреть, под какими углами видны точки дуги. |
|
|||||
Цитата:
к слову, что-то и сообразить сходу не могу как можно вычислить все точки касания (без углов!) |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Цитата:
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, время: 11:53. |
|
« Предыдущая тема | Следующая тема » |
|
|