Векторное рисование в полярных координатах и арктангенс.
To view this page ensure that Adobe Flash Player version 10.0.0 or greater is installed.
Ниже я покажу код одного своего теста, без которого у меня не получилось сдвинутся в одной моей коммерческой проге. Этот тест был написан для того, чтобы еще раз вникнуть в тригонометрические функции - в без них никуда при векторном рисовании. Когда в коммерческой проге нагромоздились горы кода - у меня не получилось с разбегу сообразить, какая из тригонометрических функций мне тут нужна в моей проге - котангенс, арктангенс, тангенс, арккотенгенс. Пришлось выделить нужный фрагмент кода - так получился тест, который вы видите.
Потом я добавил в тестик пульсацию - чтобы придать тесту более симпатичный вид. Хотя вариантов облагородить тест вокруг функции можно придумать миллион. Если бы у меня было свободное время - я бы сделал вокруг функции Koleso вращающееся, подпрыгивающее и деформируемое на кочках колесо. Ну или например вылазящие из орбит глаза в которых вращаются от удивления зрачки. Но, увы... времени нет совершенно - единственное что я успел - сделать для другого топика пример на этих же графических примитивах - Шаблон Flex/Air приложений со вкладками - ViewStack.
НумерикБокс с количеством спиц (сверху клипа) можно менять на ходу - это и есть проверка корректности тригонометрической функции - иначе это было бы простейшее матричное преобразование.
1: <?xml version="1.0" encoding="utf-8"?>
2: <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
3: xmlns:s="library://ns.adobe.com/flex/spark"
4: xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="900" minHeight="900"
5: applicationComplete="application1_applicationCompleteHandler(event)" backgroundColor="#FDF5E6">
6: <fx:Style source="DrawPolarGradientAtan.css"/>
7: <fx:Script>
8: <![CDATA[
9:
10: //http://live.mephist.ru/show/unit-circle/
11:
12: import mx.core.UIComponent;
13: import mx.events.FlexEvent;
14:
15: private var Circle_Line_thickness:Number=1;
16: private var Circle_Line_color:uint=0;
17: private var Circle_Line_alpha:Number=1.0;
18: private var Circle_Line_pixelHinting:Boolean=false;
19: private var Circle_Line_scaleMode:String="normal";
20: private var Circle_Line_caps:String=null;
21: private var Circle_Line_joints:String=null;
22: private var Circle_Line_miterLimit:Number=3;
23: private var Circle_FillColor:uint=0xFF0000;
24: private var Circle_Radius:uint=10;
25:
26: private var Line_thickness:Number=1;
27: private var Line_color:uint=0;
28: private var Line_alpha:Number=1.0;
29: private var Line_pixelHinting:Boolean=false;
30: private var Line_scaleMode:String="normal";
31: private var Line_caps:String=null;
32: private var Line_joints:String=null;
33: private var Line_miterLimit:Number=3;
34:
35: private var timer:Timer;
36: private var CircleRadiusStep:Number=1;
37: private var TimerCount:int=0;
38: private var MaxTimerRepeat:int=30;
39:
40:
41: protected function application1_applicationCompleteHandler(event:FlexEvent):void
42: {
43: ResetTimer();
44: }
45:
46: private function ResetTimer():void{
47: if (timer!==null){
48: if (timer.running){
49: timer.stop();
50: timer.removeEventListener(TimerEvent.TIMER, timerHandler);
51: timer.removeEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
52: timer=null;
53: }
54: }
55: TimerCount=0;
56: timer=new Timer(50, MaxTimerRepeat);
57: timer.addEventListener(TimerEvent.TIMER, timerHandler);
58: timer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
59: timer.start();
60: }
61:
62: private function timerHandler(e:TimerEvent):void{
63: Circle_Radius+=CircleRadiusStep;
64: Stage2.graphics.clear();
65: DrawKoleso();
66: }
67:
68: private function completeHandler(e:TimerEvent):void {
69: CircleRadiusStep = -CircleRadiusStep;
70: timer.stop;
71: timer.removeEventListener(TimerEvent.TIMER, timerHandler);
72: timer.removeEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
73: timer=null;
74: TimerCount+=1;
75: if (TimerCount<MaxTimerRepeat){
76: ResetTimer();
77: }
78: }
79:
80:
81: private function DrawGradientCircle(Sprite:Graphics,x:Number, y:Number,GradientFocalPointRatio:Number, GradientRotationAngle:Number ){
82: var GradientMatrix:Matrix = new Matrix(); //матрица блика
83: var GradientBoxWidth:Number=2*Circle_Radius*1.5; //размазывание блика по оси X
84: var GradientBoxHeigth:Number=2*Circle_Radius*1.5; //размазывание блика по оси Y - если числа равно - блик круглый
85: var _GradientBoxRotationAngle:Number=0; //если GradientFocalPointNumber<>0 то это угол блика от центра круга
86: var GradientBoxTx:Number=x-GradientBoxWidth/2; //левый угол матрицы блика по X
87: var GradientBoxTy:Number=y-GradientBoxHeigth/2; //левый угол матрицы блика по Y
88: GradientMatrix.createGradientBox(GradientBoxWidth,GradientBoxHeigth,GradientRotationAngle,GradientBoxTx,GradientBoxTy);
89: var GradientColors:Array=[0xFFFFFF, Circle_FillColor]; //первое число 0xFFFFFF - белый блик, второе число - цвет круга
90: var GradientAlphas:Array=[1,1]; //прозрачности (1 - непрозрачный, 0 - невидимый) : первое число от 0 до 1 прозрачность блика, второе - прозрачность круга
91: var GradientRatios:Array=[0,255]; //от 0 до 255 - первое число размер яркой точки 0- центральная яркая, 255 - яркий одноцветный круг, второе должно быть больше, иначе нет градиента, а просто белая дырка
92: var _GradientFocalPointRatio:Number=0; //0 - центр блика точно в центре круга, 1 - смещен на границу
93: var GradientInterpolation:String=InterpolationMethod.RGB;
94: var GradientSpreadMethod:String=SpreadMethod.PAD;
95: Sprite.lineStyle(Circle_Line_thickness, Circle_Line_color, Circle_Line_alpha, Circle_Line_pixelHinting, Circle_Line_scaleMode, Circle_Line_caps, Circle_Line_joints, Circle_Line_miterLimit);
96: Sprite.beginGradientFill(GradientType.RADIAL,GradientColors,GradientAlphas,GradientRatios,GradientMatrix,GradientSpreadMethod,GradientInterpolation, GradientFocalPointRatio);
97: Sprite.drawCircle(x,y,Circle_Radius)
98: Sprite.endFill()
99: }
100:
101:
102: private var Center:Point= new Point(400,400); //стартовая точка
103: private var KolesoRadius:Number ; //радиус колеса
104: private var CurveLen:Number ; //длина дуги = KolesoRadius*2*Math.PI
105: private var KolStep:Number; //количество спиц = CurveLen/(2*Circle_Radius)
106: private var AngleRadian:Number; //угол в радианах = 2*Math.PI/KolStep;
107:
108: private function DrawKoleso():void{
109:
110: KolStep = num1.value;
111: CurveLen = num1.value * (2*Circle_Radius);
112: AngleRadian = 2*Math.PI/KolStep;
113: KolesoRadius = CurveLen / (2*Math.PI) ;
114:
115:
116: if (Blic.selected){
117: DrawGradientCircle(Stage2.graphics,Center.x,Center.y,0,0);
118: }
119: else{
120: DrawCircle1(Stage2.graphics,Center.x,Center.y)
121: }
122:
123:
124: for (var i:Number=0;i<KolStep ;i++){
125: Err1.text += i.toString();
126:
127: var P1:Point = Point.polar(KolesoRadius,i*AngleRadian)
128:
129: if (Blic.selected){
130: DrawGradientCircle(Stage2.graphics,P1.x+Center.x,P1.y+Center.y,0.6,i*AngleRadian);
131: }
132: else{
133: DrawCircle1(Stage2.graphics,P1.x+Center.x,P1.y+Center.y);
134: }
135:
136: /*var txt1:UIComponent= new UIComponent();
137: txt1.addChild(DrawText(P1.x+Center.x-8,P1.y+Center.y-10,i.toString()));
138: Stage2.addChild(txt1 ); */
139:
140: //DrawLine1(Stage2.graphics,Center.x,Center.y,P1.x+Center.x,P1.y+Center.y);
141: DrawLine3(i,Stage2.graphics,Center.x,Center.y,P1.x+Center.x,P1.y+Center.y);
142: }
143: }
144:
145:
146: private function DrawCircle1(Sprite:Graphics , x:Number, y:Number):void {
147: Sprite.lineStyle(Circle_Line_thickness, Circle_Line_color, Circle_Line_alpha, Circle_Line_pixelHinting, Circle_Line_scaleMode, Circle_Line_caps, Circle_Line_joints, Circle_Line_miterLimit);
148: Sprite.beginFill(Circle_FillColor);
149: Sprite.drawCircle(x,y,Circle_Radius);
150: Sprite.endFill();
151: }
152:
159: private var Text_size:Number=10;
160: private function DrawText(X:Number, Y:Number, Text:String):TextField {
161: var Text1:TextField = new TextField();
162: var TxtFormat:flash.text.TextFormat = new flash.text.TextFormat();
163: TxtFormat.size = Text_size;
164: Text1.setTextFormat(TxtFormat);
165: Text1.text=Text;
166: Text1.x=X;
167: Text1.y=Y;
168: Text1.width=500;
169: return Text1;
170: }
171:
172: private function DrawLine1(Sprite:Graphics, FromX:Number, FromY:Number, ToX:Number, ToY:Number):void {
173: Sprite.lineStyle(Line_thickness,Line_color,Line_alpha,Line_pixelHinting,Line_scaleMode,Line_caps,Line_joints,Line_miterLimit);
174: Sprite.moveTo(FromX,FromY);
175: Sprite.lineTo(ToX,ToY);
176: }
177:
178: private function DrawLine3(Num:Number,Sprite:Graphics, FromX:Number, FromY:Number, ToX:Number, ToY:Number):void {
179: Sprite.lineStyle(Line_thickness,Line_color,Line_alpha,Line_pixelHinting,Line_scaleMode,Line_caps,Line_joints,Line_miterLimit);
180:
181: if (FromX==ToX){
182: if (FromY>ToY){
183: Sprite.moveTo(FromX, FromY-Circle_Radius);
184: Sprite.lineTo(ToX ,ToY+Circle_Radius);
185: }
186: else{
187: Sprite.moveTo(FromX , FromY+Circle_Radius);
188: Sprite.lineTo(ToX , ToY-Circle_Radius);
189: }
190: }
191: else if (FromY==ToY){
192: if (FromX<ToX){
193: Sprite.moveTo(FromX+Circle_Radius , FromY);
194: Sprite.lineTo(ToX-Circle_Radius , ToY);
195: }
196: else{
197: Sprite.moveTo(FromX-Circle_Radius , FromY);
198: Sprite.lineTo(ToX+Circle_Radius , ToY);
199: }
200: }
201: else{
202:
203: //Sprite.moveTo(FromX , FromY );
204: //Sprite.lineTo(ToX , ToY );
205:
206: var Angle:Number= Math.atan((ToY-FromY) / (ToX-FromX));
207: var P1:Point=Point.polar(Circle_Radius,Angle);
208: //Err1.text += "\n" + FromX.toString() + " , " + FromY.toString() + " , " + ToX.toString() + " , " + ToY.toString() + " , " + Angle.toString() + " , " + P1.x.toString() + " , " + P1.y.toString() ;
209:
210: if ((FromX<ToX) && (FromY<ToY)) {
211: Sprite.moveTo(FromX + P1.x , FromY + P1.y) ;
212: Sprite.lineTo(ToX - P1.x , ToY - P1.y);
213: }
214: else if ((FromX>ToX) && (FromY>ToY)) {
215: Sprite.moveTo(FromX - P1.x , FromY - P1.y) ;
216: Sprite.lineTo(ToX + P1.x , ToY + P1.y);
217: }
218: else if ((FromX>ToX) && (FromY<ToY)) {
219: Sprite.moveTo(FromX - P1.x , FromY - P1.y) ;
220: Sprite.lineTo(ToX + P1.x , ToY + P1.y);
221: }
222: else if ((FromX<ToX) && (FromY>ToY)) {
223: Sprite.moveTo(FromX + P1.x , FromY + P1.y) ;
224: Sprite.lineTo(ToX - P1.x , ToY - P1.y);
225: }
226: }
227: //http://live.mephist.ru/show/unit-circle/
228: }
229:
230:
231:
232:
233: ]]>
234: </fx:Script>
235: <fx:Declarations>
236: <!-- Place non-visual elements (e.g., services, value objects) here -->
237: </fx:Declarations>
238:
239: <mx:Canvas id="Stage2" contentBackgroundColor="#F99999" height="800" y="50" width="800" x="10"/>
240: <s:Label id="Err1" x="10" y="10" visible="false" />
241: <s:NumericStepper x="10" y="10" id="num1" minimum="10" maximum="50" stepSize="1" value="10" contentBackgroundColor="#FFFFFF"/>
242: <s:CheckBox x="71" y="10" id="Blic" selected="true" visible="false"/>
243: </s:Application>
Если вас интересует FLASH, AIR и FLEX - то вы можете посмотреть и другие мои заметки, которые собрались у меня на сайте в прошлом году:
- 2012 год: Шаблон Flex/Air приложений со вкладками - ViewStack.
- 2011 год: Simple Freeware OpenSource Flex Player for Web (one sound).
- 2011 год: Парсинг AJAX-сайтов в среде AIR (путем выполнения jQuery-запросов из ActionScript).
- 2011 год: Флекс диаграммы.
- 2011 год: Видео-камеры, видео-чаты и Flash-медиасервера (работающие по RTMP и самописным протоколам).
- 2011 год: Сокеты во Flash.
- 2011 год: Freeware OpenSource панорамный фотослайдер.
- 2011 год: AIR приложения для платформ Android, Macintosh и Linux.
- 2011 год: Реклама в видеоплеере (возможности объектного программирования ActionScript).
- 2011 год: Трехмерное вдохновение PaperVision3D.
- 2011 год: TextBannerRotator - простой ротатор текстовых баннеров с эффектом BLUR.
- 2011 год: OpenSource Freeware FotoSlider on Flex 3 and jQuery.
- 2011 год: Как сделать SOAP/WSDL-вебсервис на ASP.NET/MONO для вызова его из FLEX.
- 2011 год: Как с помощью jQuery сделать флеш-ролик резиновым.
- 2011 год: Мой первый фото-слайдер на Flex 4.
|