Baixe o app para aproveitar ainda mais
Prévia do material em texto
Curvas de Bézier e Catmull-Rom: Aplicação Interativa de uma Curva Cúbica. Jônatas Venancio Teixeira PPGEE, Programa de Pós Graduação em Engenharia Elétrica Universidade do Estado de Santa Catarina Joinville, Brasil teixeirajv@ymail.com Resumo — As bases matemáticas da modelagem geométrica computacional foram lançadas por diferentes matemáticos do século passado dentre eles pode-se citar Hermite e Bézier. Na época buscavam-se formas de tracejar curvas suaves para representar formas complexas. Este trabalho relata o processo de desenvolvimento de um programa de geração de curvas cúbicas de Bézier e Catmull-Rom permitindo alterar livremente os pontos de controle das curvas em um espaço 2D e impor condições de continuidade. Palavras-chave — Curvas de Bézier, Curvas de Catmull- Rom, curva cúbica interativa, restrições de continuidade C0 e C1, aplicação em Flash. I. INTRODUÇÃO Este trabalho relata brevemente o desenvolvimento de um ambiente interativo em Flash no qual o usuário é capaz de reposicionar qualquer um dos pontos de controle de uma curva cúbica de Bézier e de Catmull-Rom. Na seção II será feita uma breve revisão da literatura sobre as curvas de Bézier e Hermite e Catmull-Rom. Como o objetivo era criar um ambiente interativo de edição de uma Spline de Bézier e de Catmiull-Rom, serão abordadas as formulações algébricas referentes às curvas lineares, quadráticas e cúbicas de Bézier, em seguida a cúbica de Hermite será abordada para efeitos de comparação com a cúbica de Bézier e Catmull-Rom, posteriormente serão feitas abordagens sobre a formulação utilizada para modelar uma curva de Catmull-Rom. Será visto que as curvas de Bézier são muito parecidas com as curvas de Hermite, porém as funções base são diferentes. Na seção III são abordados o problema proposto e a sua resolução indicando como foram calculados os pontos da curva de Bézier e os resultados obtidos pelo programa. Conclui-se este trabalho na seção IV, na seção V são apresentadas as referências bibliográficas e na seção VI é apresentado o código completo desenvolvido para os fins deste trabalho e Revisão da Literatura A modelagem geométrica utiliza uma composição de elementos geométricos simples para obter representações de objetos do mundo real. O ponto é o elemento geométrico mais simples, da união destes obtêm-se as curvas e da junção das curvas provêm os planos. Diferentes formulações matemáticas foram propostas para curvas ao longo do tempo, a curva de Hermite é definida em função de polinômios cúbicos e um conjunto correspondente de equações vetoriais. As técnicas de interpolação de Hermite possui algumas fragilidades ao serem implementadas em processos interativos de modelagem geométrica, quando se tenta controlar o formato de uma curva movimentando os pontos de interpolação pode-se obter um resultado diferente do esperado. Este problema é solucionado em parte pela curva de Bézier desenvolvida em 1960 por P. Bézier [1, pg. 81]. As curvas de Bézier são obtidas a partir de equações paramétricas que relacionam os pontos da curva aos vértices de um polígono característico. Quanto maior a quantidade de pontos do polígono maior a graduação do polinômio da curva. O caso mais simples possui apenas dois pontos resultando em um polinômio de primeiro grau, conforme a equação (1). 𝐵(𝑡) = (1 − 𝑡)𝑃0 + 𝑡𝑃1 (1) Na equação (1) P0 e P1 são os dois pontos de controle, t é um parâmetro da curva que variando de 0 a 1 descreve uma reta que liga os dois pontos de controle. Quando o polígono característico possui três pontos obtém-se um polinômio de segundo grau conforme pode-se observar na equação (2). 𝐵(𝑡) = (1 − 𝑡)2𝑃0 + 2𝑡(1 − 𝑡)𝑃1 + 𝑡 2𝑃2 (2) Os pontos presentes nas equações das curvas de Bézier representam as coordenadas cartesianas dos pontos de controle que influenciam os pontos da curva em função do parâmetro t. A figura 1 ilustra a construção de uma curva quadrática de Bézier. Os pontos auxiliares Q0 e Q1 variam linearmente segundo uma equação de primeiro grau de Bézier entre os pontos de controle e o ponto B pertencente a curva de Bézier varia linearmente entre os pontos Q0 e Q1, esta característica de variação linear entre o pontos pode ser utilizado para criar algoritmo recursivo, este tipo de recurso será utilizado posteriormente em nossa aplicação. Fig. 1 – Construção de uma curva quadrática de Bézier [2]. A partir de um polígono característico com quatro pontos obtém-se um polinômio de terceiro grau resultando em uma curva cúbica de Bézier, a equação do polinômio resultante pode ser observada na equação (3). B(t) = (1 − t)3P0 + 3t(1 − t) 2P1 + 3t 2(1 − t)P2 + t 3P3 (3) A construção da curva cúbica resultante do polinômio de terceiro grau é ilustrada na figura 2, assim como na figura 1 existem pontos auxiliares que variam entre os pontos de controle, porém agora existem pontos R0 e R1 que se movem entre os pontos Q0, Q1, e Q2 e finalmente o ponto B da curva resultante varia entre R0 e R1. Desta forma é possível construir uma curva cúbica a partir dos pontos Pi, Qi, e Ri todos variando linearmente em função das posições dos pontos de referência e do parâmetro t. Fig. 2 – Construção de uma curva cúbica de Bézier [3]. Tanto na figura 1 quanto na figura 2 os pontos auxiliares e o ponto B estão posicionados para t = 0,25. As curvas cúbicas de Hermite por outro lado são definidas em função de dois pontos e dois vetores direcionais, a direção e o modulo destes vetores servem como parâmetro para alterar a forma da curva. A figura 3 ilustra a obtenção de uma cúbica de Hermite em função dos pontos e dos vetores de referência. Fig. 3 – Construção de uma curva cúbica de Hermite [1]. As coordenadas dos pontos P0, P1, P0u e P1u são multiplicadas pelas funções base de Hermite e posteriormente somadas para obter as coordenadas dos pontos pertencentes às curvas. O polinômio resultante para uma cúbica de Hermite corresponde à equação (4). 𝐵(𝑢) = (2𝑢3 − 3𝑢2 + 1)𝑃0 + (−2𝑢 3 + 3𝑢2)𝑃1 + (𝑢3 − 2𝑢2 + 𝑢)𝑃0 𝑢 + (𝑢3 − 𝑢2)𝑃1 𝑢 (4) O controle das retas tangentes pode tornar a confusa manipulação das formas da curva, pois se torna difícil imaginar os efeitos que a manipulação das retas tangentes podem causar sobre a curva, para tornar o controle mais intuitivo são utilizados outros tipos de Splines como as Cardinais, as Catmull-Rom e as TCB-Splines,está última é a própria Spline Hermite com um aparato adicional de cálculo das tangentes [4]. Pode-se observar que a cúbica de Hermite difere da cúbica de Bézier somente nas funções base que multiplicam os pontos de controle da curva, essa sutil diferença faz com que o controle da forma da curva seja mais fácil de prever. O ponto P1u da figura 3 corresponde ao ponto P1 da figura 2, pode-se notar que para se obter a curva da figura 3 foi necessário posicionar o ponto P1u depois do ponto P1 fazendo com que a curvatura da Spline fosse tangente ao vetor diretor do ponto P1u. Este comportamento pode se tornar confuso para o usuário, a mesma forma de curva pode ser obtida alterando o ponto P1 na cúbica de Bézier, conforme pode ser observado na figura 8. Diferentes formulações para a curva de Catmull-Rom podem ser encontradas na literatura. Em [5] foi apresentada uma formulação parametrizada de Catmull-Rom por C. Twigg. Neste trabalho a equação da curva é deduzida a partir da comparação da equação genérica de uma cúbica dada pela equação (5) e as condições de continuidade nas extremidades da curva. Na figura 4 podemos observar a curva de Catmull- Rom utilizada por Twigg em sua dedução, como podemos observar, a tangente da curva no ponto pi-1 e é determinada por um vetor que vai do ponto antecedente, pi-2 no caso do ponto pi-1, ao ponto posterior, pi no caso do ponto pi-1,analogamente é definidaa tangente ao ponto pi, podemos observar as equações de continuidade nas equações (6), (7), (8) e (9). Fig. 5 – Construção de uma curva cúbica de Catmull-Rom [5]. 𝑃(𝑠) = 𝐶0 + 𝑢𝐶1 + 𝑢 2𝐶2 + 𝑢 3𝐶3 (5) 𝑃(0) = 𝑝𝑖−1 (6) 𝑃(1) = 𝑝𝑖 (7) 𝑃(0)′ = 𝜏(𝑝𝑖 − 𝑝𝑖−2) (8) 𝑃(1)′ = 𝜏(𝑝𝑖+1 − 𝑝𝑖−1) (9) A partir de várias manipulações algébricas que não nos convém abordar em detalhes nesse trabalho obtém-se a equação da curva que pode ser observada na equação (10). 𝑃(𝑠) = 𝑝𝑖−1 + 𝜏(𝑝𝑖 − 𝑝𝑖−2)u + (3(𝑝𝑖 − 𝑝𝑖−2) − 𝜏(𝑝𝑖+1 − 𝑝𝑖−1) − 2𝜏(𝑝𝑖 − 𝑝𝑖−2)) 𝑢 2 + (−2(𝑝𝑖 − 𝑝𝑖−2) + 𝜏(𝑝𝑖+1 − 𝑝𝑖−1) + 𝜏(𝑝𝑖 − 𝑝𝑖−2)) 𝑢 3 (10) Difere portanto da curva de Hermite na qual a tangente no ponto pi é definida por um vetor que vai do ponto pi ao ponto pi+1, além disso a formulação proposta por Twigg utiliza um parâmetro τ que tem a função de modular o vetor tangente para controlar a curvatura da curva resultante como pode ser observado na figura 6. Fig. 6 – Influência do parâmetro τ na curva [5]. Apesar da possibilidade de implementar essa equação diretamente para se obter a curva de Catmull-Rom essa abordagem não foi escolhida. Como veremos na próxima seção foi possível desenvolver um programa em Flash bastante didático que permitia observar as retas tangentes se movimentando durante a construção da curva de Bézier, para que fosse possível obter o mesmo efeito para a curva de Catmull-Rom optou-se por utilizar uma parametrização que permitisse relacionar uma curva de Catmull-Rom e os respectivos pontos de controle de uma curva de Bézier equivalente, construindo assim uma curva de Catmull-Rom a partir dos pontos auxiliares de uma curva de Bézier. A formulação necessária para esta abordagem é apresentada por C. Yuksel et. al. [6] que desenvolve uma parametrização que permite através dos pontos de controle pi de uma curva de Catmull-Rom obter os pontos de Bézier equivalentes. Na figura 7 podemos graficamente a relação entre os pontos de controle de uma curva Catmull-Rom e os pontos de controle equivalentes de uma curva de Bézier. Fig. 7 – Representação dos pontos de controle de uma curva de Catmull-Rom e os pontos de controle equivalentes de uma curva de Bézier[6]. Trata-se portanto de utilizar os pontos de controle de Bézier como artifício algébrico para se traçar uma curva de Catmull-Rom. A formulação obtida por Yuksel para relacionar os pontos de controle pode ser observada nas equações (11), (12), (13), (14) e (15). 𝐵0 = 𝑃1 (11) 𝐵1 = 𝑑1 2𝛼 ∗ 𝑃2 − 𝑑2 2𝛼𝑃0 + (2𝑑1 2𝛼 + 3𝑑1 𝛼𝑑2 𝛼 + 𝑑2 2𝛼)𝑃1 3𝑑1 𝛼(𝑑1 𝛼+𝑑2 𝛼) ⁄ (12) 𝐵2 = 𝑑3 2𝛼 ∗ 𝑃1 − 𝑑2 2𝛼𝑃3 + (2𝑑3 2𝛼 + 3𝑑3 𝛼𝑑2 𝛼 + 𝑑2 2𝛼)𝑃1 3𝑑3 𝛼(𝑑3 𝛼+𝑑2 𝛼) ⁄ (13) 𝐵3 = 𝑃2 (14) 𝑑𝑖 = |𝑃𝑖 − 𝑃𝑖−1| (15) O parâmetro α das equações anteriores varia entre 0 e 1. O efeito do parâmetro α é de aumentar ou diminuir a curvatura da curva de Catmull-Rom resultante assim como o parâmetro τ da parametrização proposta por Twigg. II. DESENVOLVIMENTO DE UM AMBIENTE INTERATIVO O desenvolvimento deste trabalho deu-se em duas partes, primeiramente foi proposto ao autor desse trabalho desenvolver um ambiente interativo de controle de uma cúbica de Bézier no qual fosse possível alterar a posição de qualquer um dos vértices do polígono característico para editar livremente a curva resultante. Em seguida o programa previamente desenvolvido foi complementado para a edição de uma Catmull-Rom e para que restrições de continuidade pudessem ser aplicadas às duas curvas criando-se uma junção entre elas onde houvesse continuidade de ordem zero e de primeira ordem. Inicialmente o autor se propôs a desenvolver um ambiente utilizando OpenGL e linguagem C. Todavia por tratar-se de uma ferramenta sobre a qual não se possuía domínio e devido ao pouco tempo disponível para estudar as bibliotecas gráficas foi concedida a opção de se desenvolver em MathLab ou outra ferramenta com a qual se tivesse mais familiaridade. O Macromedia Flash é um ambiente de criação de aplicativos para web que utiliza uma linguagem de programação chamada de Action-Script (AS) bastante similar ao Java-Script que permite criar ambientes interativos baseados em objetos criados dentro do Flash. A possibilidade de clicar diretamente sobre os pontos e arrastá-los para uma nova posição é facilmente implementada no Flash através das funções onPress( ), startDrag( ) e stopDrag( ). Foram então criados vários objetos do tipo botão e a partir da programação dos seus parâmetros de posicionamento _x e _y foi possível construir uma Spline cúbica de Bézier. Para tanto existiria a possibilidade de calcular os pontos da curva diretamente a partir da equação (3), todavia o ambiente de desenvolvimento em Flash propiciava ao autor a criação de um ambiente interativo com animações que demonstrassem como a curva é obtida ponto a ponto. Portanto em lugar de se calcular o ponto resultante diretamente da equação (3) foram utilizadas equações lineares para calcular a posição dos pontos Qi, Ri e o ponto B pertencente à cúbica de Bézier em função da posição dos pontos Pi do polígono característico, no quadro 1 pode-se observar o trecho de código responsável pelo cálculo da posição dos pontos em função do parâmetro t. Quadro 1 – Código em AS2 para cálculo da posição dos pontos da curva. No trecho de código descrito no quadro 1, Q01 e Q02 representam os pontos R0 e R1 e a variável Q03 o ponto B resultante, como pode-se observar a posição do ponto B é obtida a partir de um polinômio linear e da posição dos pontos R0 e R1, analogamente a posição de R0 e R1 é obtida a partir de Q0, Q1, e Q2. Dessa forma foi possível computar a posição dos pontos criando uma animação da construção de uma cúbica de Bézier, apesar da possibilidade de criar retas durante a execução do código com AS, a variação muito brusca da curva em certos pontos diminuía a resolução da curva resultante. Portanto optou-se por duplicar o ponto Q3 a cada interação conforme pode-se observar no trecho de código do quadro 2. Quadro 2 – Código em AS2 para gerar a curva resultante A figura 8 ilustra a execução do programa criado para uma dada configuração dos pontos de controle que formam o polígono característico, nesta configuração obteve-se uma curva em N, alterando-se a posição dos pontos de controle pode-se obter diferentes configurações curva cúbica de Bézier, ainda na figura 9 pode-se observar uma configuração em laço obtida pela edição dos pontos de controle. O código completo está disponibilizado na seção V. Fig. 8 – Construção de uma Spline Cúbica de Bézier na Aplicação desenvolvida pelo autor em forma de N. Fig. 9 – Construção de uma Spline Cúbica de Bézier na Aplicação desenvolvida pelo autor em forma de laço. Até então o ambiente desenvolvido mostrou-se eficiente em realizar aquilo a que se propunha o autor na primeira fase de desenvolvimento. Na segunda fase foram incluídos mais quatro pontos de controle para a edição de uma cúbica de Catmull-Rom, foi também alterada a aparência destes para que fosse possível melhorar a visualização do ponto de junção das curvas. Fig. 10 – Interface gráfica inicial da Aplicação após a inclusão da curva de Catmull-Rom e dos critérios C0e C1. Na figura 10 podemos observar o ambiente desenvolvido pelo autor após a inclusão da curva de Catmull-Rom, os botões C0 e C1 no cantor inferior direito são utilizados para aplicar as restrições de continuidade gerando a junção entre as duas curvas conforme podemos observar na figura 11. Fig. 11 – Junção das curvas de Bézier e de Catmull-Rom da figura 10 após a aplicação dos critérios C0e C1. Q0._x = P0._x+t*(P1._x-P0._x); Q0._y = P0._y+t*(P1._y-P0._y); Q1._x = P1._x+t*(P2._x-P1._x); Q1._y = P1._y+t*(P2._y-P1._y);Q01._x = Q0._x+t*(Q1._x-Q0._x); Q01._y = Q0._y+t*(Q1._y-Q0._y); Q2._x = P2._x+t*(P3._x-P2._x); Q2._y = P2._y+t*(P3._y-P2._y); Q12._x = Q1._x+t*(Q2._x-Q1._x); Q12._y = Q1._y+t*(Q2._y-Q1._y); Q3._x = Q01._x+t*(Q12._x-Q01._x); Q3._y = Q01._y+t*(Q12._y-Q01._y); duplicateMovieClip(Q3, "Q"+c, c); this["Q"+c]._x = Q3._x; this["Q"+c]._y = Q3._y; No quadro 3 podemos observar o trecho de código que calcula os pontos de controle de Bézier Si equivalentes aos pontos de controle de Catmull-Roll Ri através do qual o usuário altera a forma da curva. Quadro 3 – Código em AS2 para gerar calcular os pontos de controle de uma Bézier equivalente aos pontos de controle de uma Catmull-Rom. Após realizar os cálculos para obtenção dos pontos Si o programa utiliza os mesmos algoritmos desenvolvidos anteriormente para desenhar a curva de Catmull-Rom a partir de parâmetros de uma curva de Bézier equivalente. Para as restrições de continuidade foram desenvolvidas duas funções, a primeira delas, como podemos observar no quadro 4 calcula o vetor deslocamento necessário para fazer com que o primeiro ponto da curva de Catmull-Rom coincida com o último ponto da curva de Bézier esse vetor de deslocamento é então aplicado a todos os pontos de controle Ri da curva de Catmull-Rom. Quadro 4 – Função para aplicação da restrição C0 de continuidade. Podemos observar no quadro 5 função que aplica a restrição de continuidade da derivada no ponto de junção calcula primeiramente o modulo do vetor que liga o ponto S1 ao ponto S0, a ideia é não alterar a curvatura da Spline de Catmull-Rom ao aplicar a restrição C1, esse módulo é armazenado na variável di no programa, posteriormente é feito o cálculo do ângulo que deverá ser aplicado ao novo vetor para que o ponto S1 seja colinear ao ponto P2 e ao ponto P3 assim fazendo calcula-se a nova posição do ponto S1 para que a derivada seja contínua nas vizinhanças do ponto de junção. Ao utilizar as funções desenvolvidas observamos que o programa consegue aplicar as restrições de continuidade C0 e C1 independentemente das diferentes configurações de pontos de controle utilizadas pelo usuário de forma que mais uma vez o programa realizou as tarefas necessárias a contento. Na seção VI apresentamos o código fonte completo para a versão do programa que inclui a curva de Catmull-Rom à interface gráfica. Quadro 4 – Função para aplicação da restrição C1 de continuidade III. CONCLUSÃO Neste trabalho foram abordadas algumas das curvas de Bézier e algumas diferenças entre as cúbicas de Bézier e Hermite. Foram relacionadas as equações lineares, quadráticas e cúbicas de Bézier e de Catmull-Rom. Foram feitas breves considerações a respeito do desenvolvimento de um ambiente interativo de edição de cúbicas de Bézier. O ambiente mostrou-se eficaz em produzir curvas de acordo com o reposicionamento contínuo dos pontos de controle. Ao alterar um dos pontos o programa atualiza a forma da curva através de uma animação que permite visualizar a construção de uma curva de Bézier. Futuros trabalhos poderiam ser realizados afim de estudar a junção de outros tipos de Splines aplicando a estas condições de continuidade no ponto de junção das curvas ou ainda a utilização dos algoritmos desenvolvidos neste trabalho para implementar um ambiente de edição de superfícies. IV. REFERÊNCIAS [1] Mortenson, M., E., (2006), Modeling Geometric, 3º Edição. [2] Tregoning P., Bézier Quadrática, Disponível em: http://commons.wikimedia.org/wiki/File:Bézier_2_big.svg, acessado em: outubro de 2014. [3] Tregoning, P., Bézier Cúbica, Disponível em: http://commons.wikimedia.org/wiki/File:Bézier_3_big.png, acessado em: outubro de 2014. [4] Pipenbrinck, N., Hermite Curve Interpolation, Disponível em: http://cubic.org/docs/hermite.htm, acessado em: outubro de 2014. [5] Twigg, C., Catmull-Rom Splines, Disponível em: http://www.cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf, acessado em: outubro de 2014. [6] Yuksel, C., On the Parameterization of Catmull-Rom Curves, Disponível em: http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf , acessado em: outubro de 2014. V. CÓDIGO FONTE stop(); S0._x = R1._x; S0._y = R1._y; S1._x = (Math.pow(d1, 2*alpha)*R2._x - Math.pow(d2, 2*alpha)*R0._x + (2*Math.pow(d1, 2*alpha) + 3*Math.pow(d1, alpha)*Math.pow(d2, alpha) + Math.pow(d2, 2*alpha))*R1._x) / (3*Math.pow(d1, alpha) * (Math.pow(d1, alpha)+Math.pow(d2, alpha))); S1._y = (Math.pow(d1, 2*alpha)*R2._y - Math.pow(d2, 2*alpha)*R0._y + (2*Math.pow(d1, 2*alpha) + 3*Math.pow(d1, alpha)*Math.pow(d2, alpha) + Math.pow(d2, 2*alpha))*R1._y) / (3*Math.pow(d1, alpha)*(Math.pow(d1, alpha)+Math.pow(d2, alpha))); function c1():Void { vx = P3._x-P2._x; vy = P3._y-P2._y; va = vy/vx; di = dist(S1, S0); teta = Math.atan(va); nx = di*Math.cos(teta); ny = di*Math.sin(teta); if (vx<0) { S1._x = P3._x-nx; S1._y = P3._y-ny; } else { S1._x = P3._x+nx; S1._y = P3._y+ny; } R0._x = (S1._x*-3*Math.pow(d1, alpha)*(Math.pow(d1, alpha)+Math.pow(d2, alpha))+Math.pow(d1, 2*alpha)*R2._x+(2*Math.pow(d1, 2*alpha)+3*Math.pow(d1, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R1._x)/Math.pow(d2, 2*alpha); function c0():Void { ex = R1._x-P3._x; ey = R1._y-P3._y; R0._x = R0._x-ex; R0._y = R0._y-ey; R1._x = R1._x-ex; R1._y = R1._y-ey; R2._x = R2._x-ex; R2._y = R2._y-ey; R3._x = R3._x-ex; R3._y = R3._y-ey; } http://commons.wikimedia.org/wiki/File:Bézier_2_big.svg http://commons.wikimedia.org/wiki/File:Bézier_2_big.svg http://commons.wikimedia.org/wiki/File:Bézier_3_big.png http://commons.wikimedia.org/wiki/File:Bézier_3_big.png http://cubic.org/docs/hermite.htm http://www.cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf function dist(A, B) { dX = A._x-B._x; dY = A._y-B._y; D = Math.sqrt(dX*dX+dY*dY); return D; } function c0():Void { ex = R1._x-P3._x; ey = R1._y-P3._y; R0._x = R0._x-ex; R0._y = R0._y-ey; R1._x = R1._x-ex; R1._y = R1._y-ey; R2._x = R2._x-ex; R2._y = R2._y-ey; R3._x = R3._x-ex; R3._y = R3._y-ey; u = 0; u1 = 0; u2 = 0; z = 150; fc = 1; } function c1():Void { vx = P3._x-P2._x; vy = P3._y-P2._y; va = vy/vx; di = dist(S1, S0); teta = Math.atan(va); nx = di*Math.cos(teta); ny = di*Math.sin(teta); if (vx<0) { S1._x = P3._x-nx; S1._y = P3._y-ny; } else { S1._x = P3._x+nx; S1._y = P3._y+ny; } R0._x = (S1._x*-3*Math.pow(d1, alpha)*(Math.pow(d1, alpha)+Math.pow(d2, alpha))+Math.pow(d1, 2*alpha)*R2._x+(2*Math.pow(d1, 2*alpha)+3*Math.pow(d1, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R1._x)/Math.pow(d2, 2*alpha); u = 0; u1 = 0; u2 = 0; z = 150; fc=2; trace(S1._x+" "+S1._y+" "+va); } t = 0; t1 = 0; t2 = 0; c = 5; u = 0; u1 = 0; u2 = 0; z = 150; fc = 0; P0.onPress = function() { startDrag(this); }; P0.onRelease = function() { stopDrag(); t = 0; t1 = 0; t2 = 0; c = 5; }; P1.onPress = function() { startDrag(this); }; P1.onRelease = function() { stopDrag(); t = 0; t1 = 0; t2 = 0; c = 5; }; P2.onPress = function() { startDrag(this); }; P2.onRelease = function() { stopDrag(); t = 0; t1 = 0; t2 = 0; c = 5; }; P3.onPress = function() { startDrag(this); }; P3.onRelease = function() { stopDrag(); t = 0; t1 = 0; t2 = 0; c = 5; }; R0.onPress = function() { startDrag(this); fc=1; }; R0.onRelease = function() { stopDrag(); u = 0; u1 = 0; u2 = 0; z = 150; }; R1.onPress = function() { startDrag(this); }; R1.onRelease = function() { stopDrag(); u = 0; u1 = 0; u2 = 0; z =150; }; R2.onPress = function() { startDrag(this); }; R2.onRelease = function() { stopDrag(); u = 0; u1 = 0; u2 = 0; z = 150; }; R3.onPress = function() { startDrag(this); }; R3.onRelease = function() { stopDrag(); u = 0; u1 = 0; u2 = 0; z = 150; }; C0.onRelease = function() { c0(); }; C1.onRelease = function() { c1(); }; function bez():Void { if(R1._x==P3._x and R1._y==P3._y){ C1._visible=true; }else{ C1._visible=false; } t2 = Math.round(getTimer()/10); //trace(c); if (t1 != t2 and t<1) { c++; t = t+0.01; t1 = t2; } Q0._x = P0._x+t*(P1._x-P0._x); Q0._y = P0._y+t*(P1._y-P0._y); Q1._x = P1._x+t*(P2._x-P1._x); Q1._y = P1._y+t*(P2._y-P1._y); Q01._x = Q0._x+t*(Q1._x-Q0._x); Q01._y = Q0._y+t*(Q1._y-Q0._y); Q2._x = P2._x+t*(P3._x-P2._x); Q2._y = P2._y+t*(P3._y-P2._y); Q12._x = Q1._x+t*(Q2._x-Q1._x); Q12._y = Q1._y+t*(Q2._y-Q1._y); Q3._x = Q01._x+t*(Q12._x-Q01._x); Q3._y = Q01._y+t*(Q12._y-Q01._y); this.createEmptyMovieClip("line0", 1); line0.lineStyle(0, 0x000000, 50, true, "none", "square", "miter", 0); line0.moveTo(P0._x, P0._y); line0.lineTo(P1._x, P1._y); line0.lineTo(P2._x, P2._y); line0.lineTo(P3._x, P3._y); this.createEmptyMovieClip("line1", 2); line1.lineStyle(0, 0x0000FF, 50, true, "none", "square", "miter", 0); line1.moveTo(Q0._x, Q0._y); line1.lineTo(Q1._x, Q1._y); this.createEmptyMovieClip("line2", 3); line2.lineStyle(0, 0x00FF00, 50, true, "none", "square", "miter", 0); line2.moveTo(Q1._x, Q1._y); line2.lineTo(Q2._x, Q2._y); this.createEmptyMovieClip("line3", 4); line3.lineStyle(0, 0xFF0000, 50, true, "none", "square", "miter", 0); line3.moveTo(Q01._x, Q01._y); line3.lineTo(Q12._x, Q12._y); duplicateMovieClip(Q3, "Q"+c, c); this["Q"+c]._x = Q3._x; this["Q"+c]._y = Q3._y; } function cat():Void { cbc(); //trace(u+" "+u1+" "+u2); //trace(z); u2 = Math.round(getTimer()/10); if (u1 != u2 and u<1) { z++; u = u+0.01; u1 = u2; } T0._x = S0._x+u*(S1._x-S0._x); T0._y = S0._y+u*(S1._y-S0._y); T1._x = S1._x+u*(S2._x-S1._x); T1._y = S1._y+u*(S2._y-S1._y); T01._x = T0._x+u*(T1._x-T0._x); T01._y = T0._y+u*(T1._y-T0._y); T2._x = S2._x+u*(S3._x-S2._x); T2._y = S2._y+u*(S3._y-S2._y); T12._x = T1._x+u*(T2._x-T1._x); T12._y = T1._y+u*(T2._y-T1._y); T3._x = T01._x+u*(T12._x-T01._x); T3._y = T01._y+u*(T12._y-T01._y); this.createEmptyMovieClip("line4", 255); line0.lineStyle(0, 0x000000, 50, true, "none", "square", "miter", 0); line0.moveTo(S0._x, S0._y); line0.lineTo(S1._x, S1._y); line0.lineTo(S2._x, S2._y); line0.lineTo(S3._x, S3._y); this.createEmptyMovieClip("line5", 256); line1.lineStyle(0, 0x0000FF, 50, true, "none", "square", "miter", 0); line1.moveTo(T0._x, T0._y); line1.lineTo(T1._x, T1._y); this.createEmptyMovieClip("line6", 257); line2.lineStyle(0, 0x00FF00, 50, true, "none", "square", "miter", 0); line2.moveTo(T1._x, T1._y); line2.lineTo(T2._x, T2._y); this.createEmptyMovieClip("line7", 258); line3.lineStyle(0, 0xFF0000, 50, true, "none", "square", "miter", 0); line3.moveTo(T01._x, T01._y); line3.lineTo(T12._x, T12._y); duplicateMovieClip(T3, "T"+z, z); this["T"+z]._x = T3._x; this["T"+z]._y = T3._y; } function cbc():Void { alpha = 2/3; d1 = dist(R1, R0); d2 = dist(R2, R1); d3 = dist(R3, R2); S0._x = R1._x; S0._y = R1._y; if (fc != 2) { S1._x = (Math.pow(d1, 2*alpha)*R2._x-Math.pow(d2, 2*alpha)*R0._x+(2*Math.pow(d1, 2*alpha)+3*Math.pow(d1, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R1._x)/(3*Math.pow(d1, alpha)*(Math.pow(d1, alpha)+Math.pow(d2, alpha))); S1._y = (Math.pow(d1, 2*alpha)*R2._y-Math.pow(d2, 2*alpha)*R0._y+(2*Math.pow(d1, 2*alpha)+3*Math.pow(d1, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R1._y)/(3*Math.pow(d1, alpha)*(Math.pow(d1, alpha)+Math.pow(d2, alpha))); } S2._x = (Math.pow(d3, 2*alpha)*R1._x-Math.pow(d2, 2*alpha)*R3._x+(2*Math.pow(d3, 2*alpha)+3*Math.pow(d3, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R2._x)/(3*Math.pow(d3, alpha)*(Math.pow(d3, alpha)+Math.pow(d2, alpha))); S2._y = (Math.pow(d3, 2*alpha)*R1._y-Math.pow(d2, 2*alpha)*R3._y+(2*Math.pow(d3, 2*alpha)+3*Math.pow(d3, alpha)*Math.pow(d2, alpha)+Math.pow(d2, 2*alpha))*R2._y)/(3*Math.pow(d3, alpha)*(Math.pow(d3, alpha)+Math.pow(d2, alpha))); S3._x = R2._x; S3._y = R2._y; } _root.onEnterFrame = function():Void { bez(); cat(); };
Compartilhar