Comments 65
Очень подробно и понятно. Что касается изометрики, не совсем мне кажется доступно описано.
Но так и потянуло открывать редактор и пробывать различные трансформации.
Но так и потянуло открывать редактор и пробывать различные трансформации.
0
Спасибо, очень познавательно. А про кривые безье будет статья?
+1
Кривые Безье — это намного проще, на статью не тянет. Глянем на MDC интерфейс:
Тут главное разобраться за какую точку отвечает каждый из аргументов. Вы можете использовать LibCanvas PathBuilder для экспериментов.
Оранжевая точка — это точка, из которой мы начинаем рисовать кривую, её положение показывает где закончился путь перед этим, например от аргумента moveTo или последняя точка предыдущего вызова bezierCurveTo.
Аргументы x, y отвечают за изменения положения жёлтой точки, которая указывает куда следует проложить кривую, аргументы cp1x, cp1y за изменения положения контрольной розовой точки, а cp2x, cp2y – контрольной голубой.
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
Тут главное разобраться за какую точку отвечает каждый из аргументов. Вы можете использовать LibCanvas PathBuilder для экспериментов.
Оранжевая точка — это точка, из которой мы начинаем рисовать кривую, её положение показывает где закончился путь перед этим, например от аргумента moveTo или последняя точка предыдущего вызова bezierCurveTo.
Аргументы x, y отвечают за изменения положения жёлтой точки, которая указывает куда следует проложить кривую, аргументы cp1x, cp1y за изменения положения контрольной розовой точки, а cp2x, cp2y – контрольной голубой.
+2
Извините за не энциклопедическое объяснение)
+1
Спасибо, понятно. Просто я уж коль вы разбираете в геометрических преобразованиях, хотел бы поинтересоваться как построить параллельную кривую, кривой бизье. Заданную 3мя точками. Надеюсь понятно что я имею в виду (например железнодорожные шпалы).
0
Для того, чтобы построить параллельную кривую необходимо сдвинуть на определённое значение х или у. Главное — сохранить растояние между всеми точками фигуры. К примеру, если Вам нужно построить параллельную кривую справа от первичной, то необходимо все иксы увеличить на N.
0
Можно, но таким образом мы получим не равноценные окончания отрезков. Ладно, без примера сложно объяснить. Там нужно вычислять новые точки. У меня есть идея, думал может еще, что подскажите. Спасибо. Будет интересно нарисую.
0
Мне интересно. Особенно про пункт «неполноценные окончания». Что вы имеете ввиду? Если так критично сделать клона кривой — почему бы ее на нарисовать в буфер, а потом из него — две кривых
+1
Буфер не нужен. Мне скорее требуется не клона, а кривую, которая будет полностью параллельна. Завтра я напишу комментарий тут, где приведу пример, и решение свое. Сегодня просто не успею.
0
Насколько я понял из описания, Вам нужна эквидистанта.
0
И так, у нас есть кривая, построенная по трем точкам.
Если мы просто сдвинем, то у нас получиться, что то такое.
На параллельные путь, ЖД не очень похоже.
Во что мне бы хотелось видеть.
Красная и синяя кривые.
Теперь опишу алгоритм как я это получаю.
Проводим отрезки АК и ВК в 3 точку кривой бизье.
Перпендик. им я строю прямые a и b. На этих прямых откладываю 2 равных отрезка AC и BD.
Это и будут новые точки кривой бизье. Но как найти 3ю точку.
Я провожу 2 параллельные прямые DF || BK и CF || AK.
И на их пересечении я нахожу точку F. Какая и является искомой. Вот так, я строю.
Сам алгорим я ещё не проверил(до этого я искал по другому, но оказалось ошибачно), может это и не правильно, или может есть ещё какой то более простой способ, поэтому и спрашиваю.
И ещё. Так как я не знаю как построить параллельные(может есть алгорим). То провожу перпендикулярные прямые, не только к точкам B и A. Но и в точку К я опускаю 2 перпендикуляра как к одной прямой так и к другой.
Если мы просто сдвинем, то у нас получиться, что то такое.
На параллельные путь, ЖД не очень похоже.
Во что мне бы хотелось видеть.
Красная и синяя кривые.
Теперь опишу алгоритм как я это получаю.
Проводим отрезки АК и ВК в 3 точку кривой бизье.
Перпендик. им я строю прямые a и b. На этих прямых откладываю 2 равных отрезка AC и BD.
Это и будут новые точки кривой бизье. Но как найти 3ю точку.
Я провожу 2 параллельные прямые DF || BK и CF || AK.
И на их пересечении я нахожу точку F. Какая и является искомой. Вот так, я строю.
Сам алгорим я ещё не проверил(до этого я искал по другому, но оказалось ошибачно), может это и не правильно, или может есть ещё какой то более простой способ, поэтому и спрашиваю.
И ещё. Так как я не знаю как построить параллельные(может есть алгорим). То провожу перпендикулярные прямые, не только к точкам B и A. Но и в точку К я опускаю 2 перпендикуляра как к одной прямой так и к другой.
0
Во-первых, у Вас на картинках изображена квадратичная кривая Безье, это на всякий случай.
Во-вторых, что изображено на рисунках, то и называется эквидистантой. К сожалению, я не программист, и даже не математик. Поэтому не могу помочь алгоритмом или формулой.
Но теперь, зная название, Вам будет гораздо проще найти информацию по предметной области. У меня, например, нашлась вот такая забавная статья.
Во-вторых, что изображено на рисунках, то и называется эквидистантой. К сожалению, я не программист, и даже не математик. Поэтому не могу помочь алгоритмом или формулой.
Но теперь, зная название, Вам будет гораздо проще найти информацию по предметной области. У меня, например, нашлась вот такая забавная статья.
0
Тут мне подсказывают, что кривая Безье второго порядка является сегментом параболы. Также нужно заметить, что эквидистанта к параболе не является параболой.
0
картинки не открываются
0
Приятно когда девушки пишут такие статьи. Спасибо, только начал вникать в Canvas, будет полезно.
+3
К тому же девушки, которым 19 лет o_O
+3
UFO just landed and posted this here
Вы знаете много 19-ти летних девушек, пишуших на хабр про элементарную геометрию в джаваскрипте? :-)
+4
это не элементарная геометрия – это Аффинное преобразование
-3
неправильно дано определение параметрам m11,m12,m21,m22.
m11 = scaleX * cos(alpha),
m12 = scaleY * sin(alpha),
m21 = -scaleX * sin(alpha),
m12 = scaleY * cos(alpha),
где scaleX,scaleY — сжатие растяжение вдоль соответствующей оси, а alpha — угол поворота.
m11 = scaleX * cos(alpha),
m12 = scaleY * sin(alpha),
m21 = -scaleX * sin(alpha),
m12 = scaleY * cos(alpha),
где scaleX,scaleY — сжатие растяжение вдоль соответствующей оси, а alpha — угол поворота.
0
И на сколько это поможет не понимающим людям понять, что делает каждый из аргументов? Цель этой статьи ведь не в том, чтобы процитировать технические определения, а обьяснить доступным языком, что можно было без заминки использовать трансформации
0
эта матрица является обобщением методов scale, translate и rotate(произведением матриц) и мне кажется если люди поняли как работают эти методы по отдельности, то их не нужно вводить в заблуждение, а дать точное описание параметров
0
Точное описание параметров можно найти в любой «умной» статье про трансформации. Они дают мало понимания менее опытным программистам. Важно понять, как оно работает, а не заучить технические определения
0
Хочу обратить внимание — я не спорю, что желательно глубокое понимание принципов трансформации, более того, сам достаточно хорошо разбираюсь в этом, но такие детали в ЭТОЙ статье только запутают разбирающегося. Любой желающий, прочтя нашу ветку комментариев в легкостью найдет более точные, но менее очевидные описания.
0
Я так же не спорю. Просто я не понимаю, то описание которое дал автор, мне кажется оно не корректным. Хотя для новичков — это старт, чтобы понять предмет трансформации.
0
спросите у новичков, насколько точное определение помогает им понять предмет трансформации
+1
Вы зануда.
Автор молодец, доступно все объяснила, я не думаю что эта статья предназначается для опытных программистов, разбирающихся в терминологии.
Автор молодец, доступно все объяснила, я не думаю что эта статья предназначается для опытных программистов, разбирающихся в терминологии.
-1
UFO just landed and posted this here
немножко иксы-игреки перепутаны.
+1
то что я написал это полный вариант, матрица трансформации — это перемножение трех матриц: поворота, растяжения и параллельного переноса.
-2
UFO just landed and posted this here
я подправил только коэффициенты m11-m22. Я вам говорю про матрицу трансформации на плоскости. Она имеет размер 3х3, и да на плоскости существую только поворот, сжатие и параллельный перенос.
0
и я повторюсь для меня проще сухие формулы, я ни кого не заставляю ими пользоваться.
0
только поворота и растяжения. для переноса нужно вводить третюю координату.
0
перенос это самая простая трансформация. Она имеется даже в R1.
0
shatalov.su/math/transformation_1.php глава про однородные координаты в самом конце
0
"… он шире в два раза чем выше"
После прочтения вспомнилось:
Любая девушка может доказать, что крокодил более зеленый чем широкий...)))
После прочтения вспомнилось:
Любая девушка может доказать, что крокодил более зеленый чем широкий...)))
+2
Эх, жаль в канвасе нет матричных преобразований цвета пикселей… Руками это делать как-то чертовски долго выходит.
0
В тестировании матрицы ввел ошибочные параметры — канва упала, и перестала реагировать даже на корректные данные. Помог F5.
0
в изометрии между тайлами белые точки. как это побороть?
0
Где же Ваши собственные фотографии на этот раз?
0
Я сейчас для развлечения и изучения canvas пишу игру Scorch, мне там понадобилась совмещать трансформации, крутить вокруг выбранной точки, для этого просто написал Matrix2d
Очень удобно пользоваться:
Очень удобно пользоваться:
new Matrix2d(). Rotate(angle, rotationPoint). FlipY(rotationPoint). CreateTransform(context);
function Matrix2d () { var _matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]; var CalcOffset = function (matrix) { var x = matrix[0][2] * matrix[0][0] + matrix[1][2] * matrix[0][1]; var y = matrix[0][2] * matrix[1][0] + matrix[1][2] * matrix[1][1]; matrix[0][2] -= x; matrix[1][2] -= y; return matrix; } var Multiply = function (matrix) { var mulMatrix = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]; for (var x = 0; x < 3; x++) { for (var y = 0; y < 3; y++) { var sum = 0; for (var dim = 0; dim < 3; dim++) { sum += _matrix[y][dim] * matrix[dim][x]; } mulMatrix[y][x] = sum; } } _matrix = mulMatrix; } this.Rotate = function (angle, point) { var sin = Math.sin(angle); var cos = Math.cos(angle); Multiply(CalcOffset([ [cos, -sin, point.x], [sin, cos, point.y], [0, 0, 1] ])); return this; } this.FlipY = function (point) { Multiply(CalcOffset([ [-1, 0, point.x], [0, 1, point.y], [0, 0, 1] ])); return this; } this.FlipX = function (point) { Multiply(CalcOffset([ [1, 0, point.x], [0, -1, point.y], [0, 0, 1] ])); return this; } this.FlipXY = function (point) { Multiply(CalcOffset([ [-1, 0, point.x], [0, -1, point.y], [0, 0, 1] ])); return this; } this.CreateTransform = function (context) { context.transform( _matrix[0][0], _matrix[1][0], _matrix[0][1], _matrix[1][1], _matrix[0][2], _matrix[1][2]); return this; } }
+2
sylvester.jcoglan.com/ видели?)
0
Видел, но только для перемножений матриц брать её не имеет смысла. У них для 2d используется матрица 2x2 — у меня 3x3, что позволяет заодно и смещения считать, крутить вокруг нужной точки, отражать вокруг нужной точки. Плюс возможность цепочки трансформаций. Добавление новой функциональности сводится к добавлению 9 строк кода и новой матрицы в них.
В моём случае поддержка и расширение легче и, самое главное, кода намного меньше.
Да и условия лицензии не надо исполнять ;-)
В моём случае поддержка и расширение легче и, самое главное, кода намного меньше.
Да и условия лицензии не надо исполнять ;-)
0
«сплюскиваем» =)
0
Sign up to leave a comment.
Canvas-трансформации доступным языком