Easiest way to change scale of a Cesium.Rectangle? - cesiumjs

I want to create a Cesium Rectangle that contains a list of points but is maybe 20% larger in all directions than needed. What is the easiest way to do that?
var rectangle = Cesium.Rectangle.fromCartographicArray(arrayOfCartos);
...how to make rectangle bigger?

I couldn't find a builtin way in the documentation, so maybe calculating it manually is the way to go:
var enlargeFactor = 0.2;
var marginX = rectangle.width * enlargeFactor / 2;
var marginY = rectangle.height * enlargeFactor / 2;
rectangle.east -= marginX;
rectangle.west += marginY;
rectangle.north += marginY;
rectangle.south -= marginY;

Related

Draw random way in ActionScript

I'd like to move an AS 3 movieclip randomly. This is what I currently have, bound to the ENTER_FRAME event. This obviously moves the movieclip from the left upper to the right lower edge, so I need some kind of switch to add/substract the target positions.
function movePsycho(e:Event):void {
e.target.y += Math.random()*2;
e.target.x += Math.random()*2;
if (e.target.y >= stage.height || e.target.x >= stage.width)
e.target.removeEventListener(Event.ENTER_FRAME, movePsycho);
}
You don't need add/substract thing. You just have to make sure not only you get positive values out of your random, but negatives too, so it runs to all sides.
Try changing your random generating lines to this:
e.target.y += Math.random()*10 - 5;
e.target.x += Math.random()*10 - 5;
This will work if you want to make it move in a 5px radius.
I just realized you may want to generate a new random point on the screen, then move to that point and when your object reaches the destination generate another random point to go to. So if that's the case, try this:
mc.addEventListener(Event.ENTER_FRAME, onFrame);
var dirX:int = mc.x;
var dirY:int = mc.y;
function generateRandomPoint():void
{
dirX = Math.random() * stage.stageWidth;
dirY = Math.random() * stage.stageHeight;
}
function onFrame(e:Event):void
{
mc.x += (dirX - mc.x) * 0.1;
mc.y += (dirY - mc.y) * 0.1;
if(Math.abs(dirX - mc.x) < 1 || Math.abs(dirY - mc.y) < 1)
generateRandomPoint();
}
i don't know actionscript but you may find help with this
http://www.actionscript.org/forums/showthread.php3?t=270725

for..each loop for Adobe air form controls

I have four TextInput controls in a adobe air form.
They are showing in a panel named : pnlUnlockCode.
Now what I want to do is to implement a for..each loop for these four TextInput like
foreach (Control c in this.Controls)
{
c.Height = this.Height * (sizes[count].Height / SCALE_H);
c.Width = this.Width * (sizes[count].Width / SCALE_W);
c.Left = this.Width * (positions[count].X / SCALE_W);
c.Top = this.Height * (positions[count].Y / SCALE_H);
}
in c#.
Please pull me from this problem.
Awaiting your response.
Thanks
You can do the following:
for( var i:int=0; i < pnlUnlockCode.numElements; i++){
var c:TextInput in pnlUnlockCode.getElementAt(i)
...
}
This is what I would try:
var numControls : uint = pnlUnlockCode.numChildren;
for (var i : uint; i < numControls; i++) {
var control : TextInput = pnlUnlockCode.getChildAt(i) as TextInput;
control.setActualSize(sizes[count].Width / SCALE_W, sizes[count].Height / SCALE_H);
control.move(positions[count].X / SCALE_W, positions[count].Y / SCALE_H);
}
Note, you can apply scalings also by setting the scaleX, scaleY properties of a display object.
And here another note:
setActualSize(w, h) sets the size apparently not reliably. I cound not find any Flex method to set widht and height in one run. So you perhaps will be better to use the width and height properties individually:
control.width = ...;
control.height = ...;
Could someone confirm this?

Actionscript 3: Dynamically adding movieclips constrained to a container

Last Edit: Resolved!
Well, i was unable to find the ENTIRE answer here but i finally got what i was after. thanks very much for all of your help and patience.
as a side note: i think i may have been having problems with using the int and Number types, upon closer inspection of my solution, i realised that Number was being used and not int. turns out number contains floating points and int doesn't. my numbers were probably rounding whenever i tried to fix this my self. for all i know, TDI's answer might have been spot on and the use of int for the padding might have accumulated rounded numbers.. Oh well, you learn something every day..
the correct code to constrain movie clips to a container movie clip (or sprite or whatever) in the fashion i was looking for is this:
var picContainer:PicContainer = new PicContainer();
picContainer.x = stage.stageWidth / 2 - picContainer.width / 2;
picContainer.y = stage.stageHeight / 2 - picContainer.height / 2;
addChild(picContainer);
var totalPics:int = 17;
var pic:Pic = new Pic(); //make an instance just to get its width
var xRange:Number = picContainer.width - pic.width;
var spacing:Number = xRange / (totalPics - 1);
//A little optimization: only need to calculate this number ONCE:
var yLoc:Number = picContainer.height / 2 - pic.height / 2;
for(var i:int = 0; i < totalPics; i++) {
pic = new Pic();
pic.x = i * spacing;
pic.y = yLoc;
picContainer.addChild(pic);
}
the logic is pretty simple, and i don't know why i couldn't get it my self, because i drew diagrams that say exactly this logic. however, i must not have put the numbers in the right places or i wouldn't have had to ask, would i ;P
BONUS CONTENT!
as an added bonus (if anyone finds this thread looking for answers..)
you could also have the 'pic's fan out from the center point (but they'd still be in order of left to right) by using this code:
var picContainer:PicContainer = new PicContainer();
picContainer.x = stage.stageWidth / 2 - picContainer.width / 2;
picContainer.y = stage.stageHeight / 2 - picContainer.height / 2;
addChild(picContainer);
var totalPics:int = 5;
var pic:Pic = new Pic(); //make an instance just to get its width
var padding:Number = (picContainer.width - (pic.width * totalPics)) / (totalPics + 1);
for(var i:int = 0; i < totalPics; i++) {
pic = new Pic();
pic.x = padding + i * (pic.width + padding);
pic.y = picContainer.height / 2 - pic.height / 2;
picContainer.addChild(pic);
}
Try it out, these make for great thumbnail dock engines!
First Edit: Well, there is some progress thanks to TDI but not a complete solution.
you see, the problem remains that the movie clips do not squash completely into the container, the last one or two are left sticking out.
example:
my revised code looks like this:
var newPicContainer:picContainer = new picContainer();
var newPic:pic;
var picwidth:int = 100;
var amountofpics:int = 22;
var i:int;
//add a container
addChild(newPicContainer);
//center our container
newPicContainer.x = (stage.stageWidth/2)- (newPicContainer.width/2);
newPicContainer.y = (stage.stageHeight/2)- (newPicContainer.height/2);
var totalpicwidth:int = picwidth*amountofpics;
var totalpadding:int = newPicContainer.width - totalpicwidth;
var paddingbetween:int = (totalpadding / amountofpics);
for (i = 0; i < amountofpics; ++i)
{
//make a new mc called newPic(and i's value) eg. newPic1
this['newPic' + i] = new pic();
this['newPic' + i].width = picwidth;
//add our pic to the container
newPicContainer.addChild(this['newPic' + i]);
//set the new pics X
if (i != 0)
{
// if i is not 0, set newpic(i)s x to the previous pic plus the previous pics width and add our dynamic padding
this['newPic' + i].x = this['newPic' + (i-1)].x + picwidth + paddingbetween;
}
else
{
this['newPic' + i].x = 0;
}
}
thanks again to anyone in advance!
Original Post:
Hello, First time posting here. I hope I'm not getting anything wrong . my problem is as follows:
I've got a pretty basic for loop that creates a 'thumbnail' and puts it next to the previous one (With a little padding) inside a containing movie clip.
var newPicContainer:picContainer = new picContainer();
var newPic:pic;
var amount:int = 9;
var i:int;
//Add our container
addChild(newPicContainer);
//center our container
newPicContainer.x = (stage.stageWidth/2)- (newPicContainer.width/2);
newPicContainer.y = (stage.stageHeight/2)- (newPicContainer.height/2);
for (i = 0; i < amount; ++i)
{
newPic = new pic();
newPicContainer.addChild(newPic);
//just so i know it's adding them..
trace(newPic.thisOne);
newPic.thisOne = i;
// set this one to its self (+5 for padding..) Times, the amount already placed.
newPic.x = (newPic.width+5) *i;
}
I'm wondering if there is some equation or 'magic math' that I can use to figure out what the length of the container is and have the 'thumbnails' be added relative to that number. basically squashing the thumbnails against each other to make them all fit inside..
something along the lines of:
newPic.x = (newPic.width *i) - stuff here to make it know not to go past the containing width;
I must admit i'm not too great with math and so this part of coding escapes me..
thanks to any takers in advance..
you can get the length of your container by either calling its width property explicitly:
//Container Width
newPicContainer.width;
or the newContainer is also the parent of the added pics:
//Container Width
newPic.parent.width;
then you need to get the total length occupied by you pics:
var arrayOfPics:array = [pic1, pic2, pic3, pic4, pic5];
var picsWidth:Number;
for each (var element:pic in arrayOfPics)
picsWidth =+ element.width;
after than you can subtract the length of the total pics from the container to know your available padding for separation:
var totalPadding:Number = newPicContainer.width - picsWidth;
now you can determine how much padding you can afford between the pics and both sides of the container by dividing the totalPadding by the number of pics, and add an extra padding for the end.
var padding:Number = totalPadding / arrayOfPics.length + 1;
now you can simply add your pics by including the padding
for (var i:int = 0; i < arrayOfPics.length; i++)
{
newPicContainer.addChild(arrayOfPics[i]);
(i == 0) ? arrayOfPics[i].x = padding : arrayOfPics[i].x = arrayOfPics[i - 1].x + arrayOfPics[i - 1].width + padding;
}
Try this...
//maximum available length
var maxLength:int;
// a single thumbnail width
var picWidth:int = 100;
// total number of pics in a container
var maxNumPics:int;
// as long as the maximum available length
// is inferior to the container length
// add a new thumbnail
while( maxLength < newPicContainer.length - 100 )
{
maxLength += 100;
maxNumPics += 1;
}
// calculate the amount of available padding.
var padding:Number = ( newPicContainer.length - maxLength )/ maxNumPics;
//add your thumbs
var picX:int;
for( var i:int ; i < maxNumPics ; ++i )
{
var newPic:Pic = new Pic();
newPic.x = picX;
picX += padding + picWidth;
newPicContainer.addChild( newPic );
}
I'd recommend you look at using the Flex framework (it's a Flash framework), it will make building this sort of view much easier.
You can set a container's layout property, so that items are placed in horizontal, vertical or tiled layouts, and then just add items to the container.
For more info on Flex look here
For info on Flex Layouts

splitting a bezier curve in actionscript3

I would like to "grow" a path with bezier-curves. After the path has been drawn, it should be shaking a bit: Weave-like look and feel.
visual example:
weave example
At the moment I use TweenMax.bezier, which let me move a point along this curve and at the same time (onEnterFrame) I draw lines to the current Position of the Point.
Unfortunately this approach leads to bad quality of the curve if the framerate drops(square-cut) and it is difficult to recalculate all the points in between(for the weave effect);
Recent suggestions lead me to use curves to solve the problem, but I don't know exactly how.
This example would solve my problem: split bezier
But no code-snippets.
Did anyone encounter the same problem ?
Thanks in advance
I often use Tweeners CurveModifiers._bezier_get to create bezier curves and retrieve points easily (I've tried a few and this one is actually fast).
... Quickly :
Set up two arrays (x,y) listing the control points.
Iterate each frame to modify the positions of the control points.
Redraw your curve with some similar code :
for(var i:Number=0; i <1; i += precision)
{
x = CurveModifiers._bezier_get(pathX[0], pathX[pathX.length - 1], t, pathX);
y = CurveModifiers._bezier_get(pathY[0], pathY[pathY.length - 1], t, pathY);
// ...graphics.lineTo(x,y)
}
Edit
Here you go :
import caurina.transitions.*;
import caurina.transitions.properties.CurveModifiers;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(e:Event)
{
modifyCurve();
drawCurve();
}
// Control points
var pathX:Array = new Array(50,200,600,850);
var pathY:Array = new Array(50,200,100,350);
// growth related
var growth:Number=0;
var growthSpeed:Number=0.01;
/**
* Grows and draws the curve
*/
function drawCurve():void {
const precision:Number = 0.001;
var cx:Number,
cy:Number;
// grow (avoid making it more than one)
if (growth<1) growth = Math.min(1, growth+growthSpeed);
graphics.clear();
graphics.lineStyle(1);
for (var t:Number=0; t <growth; t += precision) {
cx=CurveModifiers._bezier_get(pathX[0],pathX[pathX.length-1],t,pathX);
cy=CurveModifiers._bezier_get(pathY[0],pathY[pathY.length-1],t,pathY);
if (t==0) {
graphics.moveTo(cx,cy);
} else {
graphics.lineTo(cx,cy);
}
}
}
var motion_t:Number = 0;
var motionSpeed:Number = Math.PI * 0.1;
var motionRadius:Number = 10*motionSpeed;
/**
* Creates a movement by transforming the control points
*/
function modifyCurve():void
{
var len:int = pathX.length;
motion_t += motionSpeed;
for(var index:int = 1; index < len; index++)
{
// simple circular movement for each control point
pathX[index] += Math.cos(motion_t + Math.PI * 2 / index) * motionRadius;
pathY[index] += Math.sin(motion_t + Math.PI * 2 / index) * motionRadius;
}
}
What you're looking for is more commonly called the deCastlejau algorithm. Blossoming or polar labels are more general methods for the same thing.

Zooming an object based on mouse position

I've got a large large Sprite, and I want to zoom in and out keeping mouse position as the pivot point, exactly how google maps or the photoshop zoom works, when you rotate the mouse wheel.
To archieve the zoom effect I tween the scaleX and scaleY properties, but the fixed point is (0,0), while i need to be the mouse position (that changes everytime, of course).
How can I change this?
thanks.
I just did a Google search for "zoom about an arbitrary point" (minus the quotes) and the first result looks promising.
You have to take the original offset out the scale and then reapply it at the new scale. I've done this myself but don't have the code to hand right now, so I'll see if I can dig it out and post it later.
The pseudo code for this is something like this (from memory):
float dir = UP ? 1 : -1;
float oldXscale = Xscale;
float oldYscale = Yscale;
Xscale += dir * increment;
Yscale += dir * increment;
newX = (oldX - Xoffset) / Xscale;
newY = (oldY - Yoffset) / Yscale;
Xoffset += (newX * oldXscale) - (newX * Xscale);
Yoffset += (newY * oldYscale) - (newY * Yscale);
Anything not declared is a "global"
Found out by searching the right words on google ...
This link explains the Affine Transformations http://gasi.ch/blog/zooming-in-flash-flex/
and so I can Tween the transformation Matrix:
var affineTransform:Matrix = board.transform.matrix;
affineTransform.translate( -mouseX, -mouseY );
affineTransform.scale( 0.8, 0.8 );
affineTransform.translate( mouseX, mouseY );
var originalMatrix:Matrix = board.transform.matrix;
TweenLite.to(originalMatrix, 0.7, {a:affineTransform.a, b:affineTransform.b, c:affineTransform.c, d:affineTransform.d, tx:affineTransform.tx, ty:affineTransform.ty, onUpdate:applyMatrix, onUpdateParams:[originalMatrix]});
:-)
private static function onMouseWheel(event:MouseEvent):void {
var zoomAmount:Number = 0.03;
if (event.delta < 0)
zoomAmount *= -1;
var x:int = largeLargeSprite.mouseX;
var y:int = largeLargeSprite.mouseY;
largeLargeSprite.scaleX += zoomAmount;
largeLargeSprite.scaleY += zoomAmount;
largeLargeSprite.x -= x * zoomAmount;
largeLargeSprite.y -= y * zoomAmount;
}