Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Нарисовать 4-угольник с градиентами от углов (http://www.flasher.ru/forum/showthread.php?t=104658)

LinuxVideo 29.11.2007 17:45

Нарисовать 4-угольник с градиентами от углов
 
Вложений: 1
Есть BitmapData, на нем надо нарисовать 4-угольник. У каждой вершины есть свой цвет, градиентами которых надо залить всю площадь фигуры. Пример во вложении. Только при его создании использовался обычный линейный градиент, поэтому цвета снизу несовсем такие как надо, а поскольку стороны у нас не параллельны, то линейный градиент тут непригоден.

Причем рисовать желательно быстро, таких полигонов несколько тысяч, выставленных рядом. Но это не главное - гланое точная заливка, надо как можно точнее передать цвет.

__i 29.11.2007 17:53

Линейный, в направлении биссектрисы угла с цветом угла, от с альфой [1,0], какого размера незнаю. х 4 угла (4 раза заливаем )

F_Flash 29.11.2007 18:13

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

LinuxVideo 30.11.2007 00:04

Вложений: 1
Цитата:

Линейный, в направлении биссектрисы угла с цветом угла, от с альфой [1,0], какого размера незнаю
В том то и проблема, что размер зависит от длинны стороны. Вот биссектриса угла и примерное направление градиента. Между ними должен быть прямой угол, а его как-то не видно...

Цитата:

Исолзовать радиальную заливку со мещенным фокал центром в каждой вершине
Нет, нужно как можно точнее передать значения пикселей, в дальнейшем это будет использована как битовая карта (вообще, битмап тут используется для визуального контроля и ускорения прорисовки), поэтому допуски "чуть краснее" делать бы не хотелось.

BlooDHounD 30.11.2007 00:52

всё там видно. просто площадь занимаемоя конкретным цветом разная. жотого само сабой сабой меньше всего, так как у него угол имеет самое большое отклоение от прямого. у угла в 90 градусов будет самая большая активность.

undefined 30.11.2007 13:39

можно рисовать как это делают вот эти товарищи. Создается битмапдата 2x2 с параметром smooth, точки красятся цветами вершин, далее считаются нужные трансформации для битмапа и рисуется на экране через beginBitmapFill. В твоем случае, т.к. полигон четырехугольный, надо разбить его на 2 треугольника и для каждого посчитать свой matrix.
Делаешь 3д движок, да?

aQuestion 30.11.2007 16:14

можно попробовать залить дважды линейными градиентами цветов от 1 к 3 и от 2 к 4 с 50% прозрачности во второй раз.

undefined 30.11.2007 16:21

тама полигонов несколько тысяч, флэш мувики с альфой очень медленно отрисовывает, у fp сердечный приступ случится =)
на самом деле тот вариант что я описал такое тоже не потянет, на моей тачке рисуется 100-120 полигонов при fps ~ 25, это так для прикидки.

aQuestion 30.11.2007 16:23

Цитата:

Сообщение от LinuxVideo
В том то и проблема, что размер зависит от длинны стороны. Вот биссектриса угла и примерное направление градиента. Между ними должен быть прямой угол, а его как-то не видно...

почему, собственно, бисектрисса? берите высоту на диагональ, соединяющую две соседние вершины... но целых это 4 заливки (+ ещё 1 на средний средний цвет, чтобы не было дырки в центре)

Цитата:

Сообщение от undefined
тама полигонов несколько тысяч, флэш мувики с альфой очень медленно отрисовывает, у fp сердечный приступ случится =)

загоняйте альфу непосредственно в градиент.

undefined 30.11.2007 16:25

а какая разница?

aQuestion 30.11.2007 16:28

ну, наверно так можно рисовать все заливки в один непрозрачный мувик

undefined 30.11.2007 16:35

при растеризации таких градиентов с прозрачностью флэш будет вычислять суммарный цвет, а это тормоза.

aQuestion 30.11.2007 16:39

тогда может вам поможет blending mode add?

undefined 30.11.2007 16:44

ага, пробывали и так, процентов на 20 медленее =)

artcraft 30.11.2007 18:51

возможно эта картинка поможет
http://www.inkscape.org/screenshots/...perimental.png

andrey_x 30.11.2007 19:33

А кто может подсказать, по какому вобще принципу можно получить множественный градиент(3 и больше цвета) ????
вот например, хочу окрасить треугольник, у которого градиент будет такого же цвета как и вершина....
хотя бы в какую сторону копать, подскажите плиз

aQuestion 30.11.2007 19:38

на эту тему можно почитать тут

andrey_x 30.11.2007 19:43

вы дали ссылку на эту же тему )))

мне нужно чуть другое.... просто, как построить треугольник трехградиентный.... вроде бы через BitmapData можно.. но не уверен

aQuestion 30.11.2007 19:56

это потому, что эту тему не мешало бы сначала прочитать.

BlooDHounD 30.11.2007 22:38

да вообще-то битмапдата тут не причём. бесектриса в руки.

LinuxVideo 02.12.2007 00:16

Цитата:

Создается битмапдата 2x2 с параметром smooth, точки красятся цветами вершин, далее считаются нужные трансформации для битмапа и рисуется на экране через beginBitmapFill. В твоем случае, т.к. полигон четырехугольный, надо разбить его на 2 треугольника и для каждого посчитать свой matrix.
Я наверное тупой, поподробнее если можно. Особенно с момента трансформаций.

Цитата:

Делаешь 3д движок, да?
Нет, это будет как карта, потом с нее будут попиксельно читаться данные. Результат будет в 2д, хотя кто знает, с выходом 10 может и 3д прикручу, благо нативное будет

undefined 03.12.2007 13:26

Цитата:

Я наверное тупой, поподробнее если можно. Особенно с момента трансформаций
Вообщем идея такая:
1) создаешь битмапдата 3x3 (почему не 2x2 обьясню ниже)
2) расчет деформации
Код:

// предусловие:
// {x1,y1},{x2,y2},{x3,y3} - координаты вершин рисуемого треугольниика
// {n1x,n1y},{n2x,n2y},{n3x,n3y} - координаты вершин в битмапдате 3x3
// m - матрица искомого преобразования
m = new Matrix();
var tmp=1/((n2x-n1x)*(n3x*n2y-n2x*n3y)-(n3x-n2x)*(n2x*n1y-n1x*n2y));
                m.tx=((x1*n2x-x2*n1x)*(n3x*n2y-n2x*n3y)-(x2*n3x-x3*n2x)*(n2x*n1y-n1x*n2y))*tmp;
                m.ty=((y1*n2x-y2*n1x)*(n3x*n2y-n2x*n3y)-(y2*n3x-y3*n2x)*(n2x*n1y-n1x*n2y))*tmp;
                tmp=1/(n2x*n1y-n1x*n2y);
                m.c=(n2x*x1-x2*n1x-m.tx*(n2x-n1x))*tmp;
                m.d=(n2x*y1-y2*n1x-m.ty*(n2x-n1x))*tmp;
                tmp=1/n1x;
                m.a=(x1-m.c*n1y-m.tx)*tmp;
                m.b=(y1-m.d*n1y-m.ty)*tmp;

Ну и собственно отрисовка треугольника с градиентной заливкой
Код:

// предусловие:
// m - матрица посчитаная выше
// map - битмапдата 3x3
// surface - MovieClip для рисования
                surface.beginBitmapFill(map, m, true);
                surface.moveTo(x1, y1);
                surface.lineTo(x2, y2);
                surface.lineTo(x3, y3);
                surface.endFill();

Дальше т.к. рисовать надо четырехугольник, код приведенный выше надо вызывать 2 раза.
Теперь по поводу размера битмапки 3x3. В формулах битмаповые координаты s1x,s1y,... стоят в знаменателе и чтобы избежать деления на ноль, лучше сместить все координаты на 1. Т.е. битмапка для заливки должна быть примерно такая:
http://smb.intech-ltd.com/Serega/Phong/1.png
Знаю написано довольно скомкано, если будут вопросы - спрашивай

да, чуть не забыл. Формулы которые я привел выглядят довольно пугающе, но есть еще вариант по проще (содрал его не помню у кого). Работает он чуть медленее но зато выглядит красивше
Код:

                      m = new Matrix();
                      tm = new Matrix();
                var _w=1/3;
                var _h=1/3;
                m.tx = n1x;
                m.ty = n1y;
                m.a = (n2x-n1x)*_w;
                m.b = (n2y-n1y)*_w;
                m.c = (n3x-n1x)*_h;
                m.d = (n3y-n1y)*_h;
                tm.a = (x2-x1)*_w;
                tm.b = (y2-y1)*_w;
                tm.c = (x3-x1)*_h;
                tm.d = (y3-y1)*_h;
                tm.tx = x1;
                tm.ty = y1;
                m.invert();
                m.concat(tm);


aQuestion 03.12.2007 13:43

Цитата:

Сообщение от undefined
Теперь по поводу размера битмапки 3x3. В формулах битмаповые координаты s1x,s1y,... стоят в знаменателе и чтобы избежать деления на ноль, лучше сместить все координаты на 1.

может попробовать координаты "центров" пикселей, нечто вроде типа 0.5, 1.5...

undefined 03.12.2007 13:49

согласен, в принципе должно работать. Кстати т.к. координаты вершин в битмапдате не меняются, формулы можно еще подсократить.

aQuestion 07.12.2007 13:38

ещё по теме


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

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