Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Синусоидальная кривая! Кто смогёт? (http://www.flasher.ru/forum/showthread.php?t=74981)

veterok4 01.02.2006 23:14

Синусоидальная кривая! Кто смогёт?
 
Вложений: 2
Как говорится и на старуху бывает проруха. Не варят мои тригонометрические мозги:))

Дано:задаётся программно кривая (синяя), см аттач.
необходимо: преобразовать её в синусоидальную кривую, сохраняя направление изгиба (красная).
Я конечно подозреваю, что синусоиду можно разбить на более мелкие кривые, но как при этом сохранить функцию изгиба?

CrazyFlasher 02.02.2006 02:46

2.jpg - никак не синусойда, а график кривой. Читай математику :D

aksios 02.02.2006 10:01

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

veterok4 02.02.2006 10:54

Интересно!
 
Цитата:

Сообщение от CrazyFlasher
2.jpg - никак не синусойда, а график кривой. Читай математику :D

Это синусоида -правда немного "скорректированная" направляющим изгибом... просьба не флудить.
п.с. Сам читай тригонометрию!

Skubent 02.02.2006 11:41

Во втором случае - это что-то вида
y(x) = A*sin(x) + B*sin(k*x);
где A много больше B, k значительно больше 1.

Kotana 02.02.2006 17:01

Цитата:

Сообщение от Skubent
Во втором случае - это что-то вида
y(x) = A*sin(x) + B*sin(k*x);
где A много больше B, k значительно больше 1.

line_mc.lineTo(x, 23*Math.sin(x*100) + 32*Math.sin(x/34) + 100);
line2_mc.lineTo(x, 23*Math.sin(x*100) + 32*Math.sin(x/4) + 300);
x++;

не то, что нужно, но красиво...

Nox Noctis 02.02.2006 17:15

граждане!

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

что я предлагаю:
Код:

var radius = 200;
var amp = 20;
var speed = 1;
// количество завитков за один оборот на 360 градусов
var sin_number = 20;
//
this.createEmptyMovieClip("curve", 0);
curve._x = 200;
curve._y = 200;
curve.speed = speed;
//
curve.createEmptyMovieClip("plotter", 0);
curve.plotter.lineStyle(10, 0, 100);
curve.plotter.lineTo(1, 0);
curve.plotter.radius = radius;
curve.plotter.angle = 0;
curve.plotter.amp = amp;
curve.plotter.sin_number = sin_number;
//
curve.plotter.onEnterFrame = function()
{
        // вот тут синусоида. только по иксу.
        this._x = this.radius+Math.sin(this.angle)*this.amp;
        this.angle += (2*Math.PI/360)*this.sin_number;
};
//
curve.onEnterFrame = function()
{
        // а вот тут движение по дуге.
        // в данном случае в качестве дуги взята окружность.
        var point = {x:this.plotter._x, y:this.plotter._y};
        this.localToGlobal(point);
        _root.lineTo(point.x, point.y);
        //
        this._rotation += this.speed;
};
//
lineStyle(2, 0xFF0000, 50);
moveTo(curve._x+radius, curve._y);

у меня ушло на этот скрипт 15 минут. из них половина - на придумывание.

если нужна не окружность а какая-то хитрая дуга, то путей несколько:

1. двигать внешний клип программно по параболе/еще какой-то формуле.

2. двигать внешний клип по гайду, нарисованному ручками (сами понимаете, чем это удобно и чем не удобно)

3. взять класс Ивана Дембицкого - Path -- и с помощью него двигать внешний клип программно по любой кривой безье, как угодно.

veterok4 02.02.2006 22:09

Nox Noctis - респектище! красиво выглядит, конечно, но мне не нужна замедленная прорисовка... сейчас попытаюсь разобраться с кодом что тут к чему, а потом спроэцировать на свои рандомные дуги:)....тема ещё не закрыта:)

Nox Noctis 02.02.2006 22:56

Цитата:

Сообщение от veterok4
мне не нужна замедленная прорисовка

тогда вот так я бы сделал:
Код:

var center = {x:200, y:200};
var radius = 200;
var amp = 20;
var speed = 1;
var sin_number = 20;
//
var step = (2*Math.PI/360)*sin_number;
//
this.createEmptyMovieClip("curve", 0);
curve.createEmptyMovieClip("plotter", 0);
curve._x = center.x;
curve._y = center.y;
//
lineStyle(2, 0xFF0000, 50);
moveTo(curve._x+radius, curve._y);
//
var angle = 0;
for (var i = 0; i<=360; i += speed) {
        curve.plotter._x = radius+Math.sin(angle)*amp;
        var point = {x:curve.plotter._x, y:curve.plotter._y};
        curve.localToGlobal(point);
        //
        _root.lineTo(point.x, point.y);
        //
        curve._rotation += speed;
        angle += step;
}

те же яйца, только в профиль. :)
заметь, по-прежнему всего один синус.

а если у тебя такие прям произвольные кривые - бери Path Дембицкого и будет тебе щастье. им очень легко пользоваться.

Usnul 03.02.2006 00:22

а я круче Нокса ^_^
Код:

a = 20 //Apmlitude
r = 100 //Radius
n = 30 //Number of oscillations
_root.moveTo(r,0);
_root.lineStyle(2,0x000000,100);
for(i=1;i<=n/4;i+=2){
        _root.curveTo(Math.cos((i-0.5)*(360/n)*Math.PI/180)*(r+a),Math.sin((i-0.5)*(360/n)*Math.PI/180)*(r+a),Math.cos(i*(360/n)*Math.PI/180)*r,Math.sin(i*(360/n)*Math.PI/180)*r);
        _root.curveTo(Math.cos((i+0.5)*(360/n)*Math.PI/180)*(r-a),Math.sin((i+0.5)*(360/n)*Math.PI/180)*(r-a),Math.cos((i+1)*(360/n)*Math.PI/180)*r,Math.sin((i+1)*(360/n)*Math.PI/180)*r);
}

_root._x = _root._y = 200;


CrazyFlasher 03.02.2006 00:49

ещё повторяю, открой тригонометрию и посмотри там, что такое график синусойды...он идёт по оси OX изменяя период коллебания и амплитуду, но никак не угол ;)

Nox Noctis 03.02.2006 01:14

2Usnul
несомненно. :))
главное пол литра не забыть запасти, прежде чем разобраться, что происходит. кстати, просили синусоиду, а у тебя параболки. :))

2CrazyFlasher
зачем придираться к терминам? ведь автор даже показал, что должно получиться :)

Usnul 03.02.2006 01:18

2Nox Noctis
Я ж трезвенник... А про синусойду ты прав - схалявил я, в лом 4 кривых делать =Р
и кстати, в случае 90 градусов будет синусойда.
кхм... да... тссс... никто ничего не заметил :D

Nox Noctis 03.02.2006 02:18

Цитата:

Сообщение от Usnul
и кстати, в случае 90 градусов будет синусойда

каким образом из двух парабол получается синусоида? :) что курили? :)

Usnul 03.02.2006 02:30

Цитата:

Сообщение от Nox Noctis
каким образом из двух парабол получается синусоида? :) что курили? :)

Дурак ты, Нокс, и коза твоя дура. =Р

veterok4 03.02.2006 09:08

Уже не плохо!
 
Вложений: 1
Тэксь...филателисты - не разбредаемся...
Господа, вы немного упростили задачу!
Небходимо, чтоб "синусоида" повторяла кривую безье (а не окружность)...
это будет потруднее! Т.е., где бы была задействована анкерная точка, а не центр окружности. См. аттач.

silin 03.02.2006 11:45

это было бы серьезно потруднее, если б Ив не сделал свой Path (тебе же Нокс указал..)
Код:

this.createEmptyMovieClip("curve", 0);
var plotter=curve.createEmptyMovieClip("plotter", 0);

var path = new Path(50, 50, 150, 50, 200, 200);//© Ivan Dembicki, http://www.dembicki.org
/////////кривая/////////////////////
var p=path.getPoint(0);
moveTo(p._x,p._y);
lineStyle(0);
for(var i=0;i<path.path_length;i++){
        p=path.getPoint(i);
        lineTo(p._x,p._y);
};
/////////синусода по кривой/////////////////////////
p=path.getPoint(0);
moveTo(p._x,p._y);
lineStyle(1,0xFF0000);
curve._rotation=p._rotation;
plotter._y=10;//амплитуда
var s=0,k=0.1;
for(var i=0;i<path.path_length;i++){
        p=path.getPoint(i);
        plotter._y+=s-=plotter._y*k;
        curve._rotation=p._rotation;
        curve._x=p._x;
        curve._y=p._y;
        var gp = {x:plotter._x, y:plotter._y};
        curve.localToGlobal(gp);
        lineTo(gp.x,gp.y);
};


Nox Noctis 03.02.2006 12:08

2silin
о, спасибо, а то я уже начала сам писать :)

2veterok4
скачай класс, и добавь в код Силина первой строчкой
import org.dembicki.Path;

здесь нет смысла самостоятельно всё расчитывать. это сложно. при помощи класса Path ты можешь получить координаты точек на кривой безье на равных расстояниях, что при самостоятельных расчетах является БОЛЬШИМ математическим гемором, ибо имеет место приближенное вычисление интегралов.

veterok4 03.02.2006 12:19

**Ошибка** Сцена=Сцена 1, слой=Слой 1, кадр=1:Строка 5: The class 'org.dembicki.Path' could not be loaded.
var path = new Path(50, 50, 150, 50, 200, 200);//© Ivan Dembicki, http://www.dembicki.org


Чё то ругается отладчик....:) Хотел как есть запустить - глянуть - что за чудо патч?

Nox Noctis 03.02.2006 12:29

Цитата:

Сообщение от Nox Noctis
2veterok4
скачай класс, и добавь в код Силина первой строчкой
import org.dembicki.Path;

...и кроме того, что класс нужно скачать, его еще нужно положить в папку org/dembicki/ рядом с твоим тестовым файлом.

silin 03.02.2006 13:46

Вложений: 1
держи, но к Дембицкому все равно сходи..

veterok4 03.02.2006 22:16

Вложений: 1
ТЕМА не ЗАКРЫТА!
Внедрил патч Дембицкого... до конца правда, ещё не разобрался... однако уже наблюдаю не желательный эффет: к сожалению синусоида идёт по затухающей...см скрин ==>

Может какие поправки с приращением внести?

veterok4 04.02.2006 17:08

Ещё поправка!
 
Вложений: 1
Цитата:

Сообщение от veterok4
ТЕМА не ЗАКРЫТА!
к сожалению синусоида идёт по затухающей...см скрин ==>

И ещё один минус (см скрин) при задании толщины линии более 10 ps, наблюдается ещё один не желательный эффект: рваные края и проплеш в центре линии.

silin 04.02.2006 17:44

дада, ошибка накапливается, но ты не грусти.., поставь туда синус :)
Код:

ampl=10;
phase=10;
for(var i=0;i<path.path_length;i++){
        p=path.getPoint(i);
        plotter._y=ampl*Math.sin(Math.PI*i/phase);
        curve._rotation=p._rotation;
        curve._x=p._x;
        curve._y=p._y;
        var gp = {x:plotter._x, y:plotter._y};
        curve.localToGlobal(gp);
        lineTo(gp.x,gp.y);
};

ps про второй скрин не понял: зачем такую линию синусоидой рисовать, рисуй по линии и не будет рваных краев..

veterok4 04.02.2006 22:24

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

Сообщение от silin
ps про второй скрин не понял: зачем такую линию синусоидой рисовать, рисуй по линии и не будет рваных краев...

Это я показал конечно утрированную линию... но и при 5 ps уже появляются рваные края - хотелось чистоты эксперимента...

А теперь новая трабла (сокращённый мой код со встроенным патчем Дембицкого):
Код:

        with (Math) {       
                _root.createEmptyMovieClip("myClip"+dd,dd); //создаю клипак
                _root["myClip"+dd]._x = 285;//перемещаю начало координат клипа...
                _root["myClip"+dd]._y = 275;//в центр рабочего стола
                _root.createEmptyMovieClip("curve", -1000+dd);
                var plotter=curve.createEmptyMovieClip("plotter", -1000+dd);

                //hexV = parseInt(colorIn,16);//указываю на 16-ную систему переменной...
                //eyeColor=new Color("myClip"+dd);//цвета, в ново-созданном объекте
                //eyeColor.setRGB(hexV);
                var radians = (ug.text*PI)/180;//перевожу  градусы в радианы
                var rad1 = sqrt(pow(x, 2)+pow(y, 2));//нахождение радиуса для...
                var rad2 = sqrt(pow(q, 2)+pow(w, 2));//каждой точки
                var rad3 = sqrt(pow(e, 2)+pow(r, 2));
               
                if (x<0&&y>0) {//определяю в какой четверти лежит точка и исходя из этого...
                        var ugol1 = PI/2+(PI/2-asin(abs(y)/rad1));//определяю угол
                } else if (x<0&&y<0) {
                        ugol1 = asin(abs(y)/rad1)+PI;
                } else if (x>0&&y<0) {
                        ugol1 = 3*PI/2+(PI/2-asin(abs(y)/rad1));
                }else{
                        ugol1 = asin(y/rad1);
                }
               
                if (q<0&&w>0) {
                        var ugol2 = PI/2+(PI/2-asin(abs(w)/rad2));
                } else if (q<0&&w<0) {
                        ugol2 = asin(abs(w)/rad2)+PI;
                } else if (q>0&&w<0) {
                        ugol2 = 3*PI/2+(PI/2-asin(abs(w)/rad2));
                } else{
                        ugol2 = asin(w/rad2);
                }               
               
                if (e<0&&r>0) {
                        var ugol3 = PI/2+(PI/2-asin(abs(r)/rad3));
                } else if (e<0&&r<0) {
                        ugol3 = asin(abs(r)/rad3)+PI;
                } else if (e>0&&r<0) {
                        ugol3 = 3*PI/2+(PI/2-asin(abs(r)/rad3));
                } else{
                        ugol3 = asin(r/rad3);
                }
                               
                var tt = 360/ug.text;//угол поворота
                for (i=0; i<tt; i++) {//цикл прорисовки
                        var u1 = ugol1+radians;//нахожу угол приращения для кождой точки
                        var u2 = ugol2+radians;
                        var u3 = ugol3+radians;
                        x2 = rad1*cos(u1);//переназначаю координаты точек
                        y2 = rad1*sin(u1);
                        q2 = rad2*cos(u2);
                        w2 = rad2*sin(u2);
                        e2 = rad3*cos(u3);
                        r2 = rad3*sin(u3);
                        var sSomeString : String = _root.czve.inValue;
                        var nSomeNumber : Number = Number( "0x" + sSomeString ); // Number ( ... ) - есть каст.
                        _root['myClip'+dd].lineStyle(tip.text, nSomeNumber, alfa.text);//задаю параметры линии
                        _root['myClip'+dd].moveTo(x2, y2);//ставим на первый анкер
                        _root['myClip'+dd].curveTo(q2, w2, e2, r2);//рисуем через контрольную до второго анкера

                        var path = new Path(x2+285, y2+275, q2+285, w2+275, e2+285, r2+275);//© Ivan Dembicki, http://www.dembicki.org
                        /////////синусода по кривой/////////////////////////
                        p=path.getPoint(0);
                        moveTo(p._x,p._y);
                        lineStyle(tip.text, nSomeNumber, alfa.text);
                        curve._rotation=p._rotation;
                        ampl=10;//амплитуда
                        phase=10;
                        for(var i=0;i<path.path_length;i++){
                                p=path.getPoint(i);
                                plotter._y=ampl*sin(PI*i/phase);
                                curve._rotation=p._rotation;
                                curve._x=p._x;
                                curve._y=p._y;
                                var gp = {x:plotter._x, y:plotter._y};
                                curve.localToGlobal(gp);
                                lineTo(gp.x,gp.y);
                                trace("myClip"+dd);//слежу за количеством итераций
                                dd=dd+1;//приращиваю переменную глубины мувика
};
                        ugol1 = u1;//меняем переменные углов (приращение)
                        ugol2 = u2;
                        ugol3 = u3;
                }
        schet = schet+1;//приращение счётчика истории создания клипов
        }

Дело в том, что флеш производит чуть более 21000 итераций и ...виснет! А всё потому что в цикле патча Дембицкого происходит НУ ОЧЕНЬ много поворотов мувика... Нельзя ли хоть как то сократить их? Или поискать альтернативный путь?

silin 04.02.2006 22:43

Цитата:

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

Вообще флэш не для таких вещей которые делаешь ты, для этого бы больше подошла Java
я, пожалуй, присоединюсь : искать 'альтернативный путь' в теперешнем флеше нет резона, не заточен он под такие вещи..
теоретичски это интерсно, но для практики(флешевой) -null
зы: в 9-ом плеере обещают производительность (арифметики по крайней мере) поднять в разы (а то и порядки), может тогда.., поглядим..

veterok4 04.02.2006 22:56

Ухожу "пробивать лбом стену"...:((

Usnul 06.02.2006 07:41

можно с диференциалом это все решить достаточно легко... находишь этот... как его по русски то? gradient короче, потом находишь синус, поворачиваешь точку на вычесленный угол и так далее пока не дойдешь до начала. Могу почиркать если кого интересует...

veterok4 06.02.2006 21:21

ОЙ!
 
Цитата:

Сообщение от Usnul
Могу почиркать если кого интересует...

ОЧЕНЬ, очень интересует! Ты просто не представляешь как будет тебе благодарно будущее поколение флешеров-дезигнеров-полиграфистов!

Nox Noctis 06.02.2006 21:25

Цитата:

Сообщение от Usnul
находишь этот... как его по русски то? gradient короче, потом находишь синус, поворачиваешь точку на вычесленный угол и так далее пока не дойдешь до начала

градиент по-русски так и называется. :)

очень любопытно, что ты имеешь в виду.

зы: если будешь делать, учти, тебе придется объяснить как это работает :)

Antares 07.02.2006 04:57

Цитата:

Сообщение от veterok4
будущее поколение флешеров-дезигнеров-полиграфистов!

Похоже на команду баскетболистов, играющих в хоккей.

Извините за оффтопик:)

Nox Noctis 07.02.2006 11:33

Цитата:

Сообщение от Antares
Похоже на команду баскетболистов, играющих в хоккей.

Path Дембицкого - это тоже что-то вроде баскетбола на льду. :) однако, какие прикольные штуки можно делать, даже не зная как он работает...

veterok4 09.02.2006 22:35

и всё же...
 
Вложений: 1
Цитата:

Сообщение от Nox Noctis
... однако, какие прикольные штуки можно делать, даже не зная как он работает...

Да прикольные, но не "долгие"... уж больно тяжеловат для поворота мувика 21000 раз...и это только за 1 цикл. На скрине вижно. что даже не закончив итерации клип повис..не завершив полный оборот прорисовки через 5%.
Всё таки я думаю, нужно подходить к этому "не флешево" а чисто математически?

Nox Noctis 09.02.2006 22:49

Цитата:

Сообщение от veterok4
больно тяжеловат для поворота мувика 21000 раз...и это только за 1 цикл

нарисуй 21к раз прямые черточки и понаблюдай, как все будет тормозить.

тебе нужно во-первых разбить итерации а несколько кадров, во-вторых слепливать нарисованное в единый битмап по мере отрисовки (при помощи BitmapData.draw)


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

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