AC 3.0 - How can i place randomly a circle within another? - actionscript-3

I'm working on a project in which i make a small circle inside a big one. That small circle will be moving inside that circle randomly. I desire to find the border of outer circle and constraint the inner circle to be reflected by the border of outer circle.
The small circle is moving in different direction but when is hits the border of an outer bigger circle it then reflected.
sorry cannot attach image due to low reputations.
assume that the small circle is inside the bigger circle.

You can do like that, with two circles named c1 and c2 on the stage:
var r1:Number = c1.width / 2; // big circle radius
var r2:Number = c2.width / 2; // small circle radius
var diff:Number = r1 - r2; // difference
var dist:Number = Math.random() * diff; // random distance between 0 and diff
var a:Number = Math.random() * 2 * Math.PI; // random angle
c2.x = c1.x + dist * Math.cos(a); // coordinates of the small circle
c2.y = c1.y + dist * Math.sin(a);

Related

how to move polygon points depending on movement of one point?

i have polygon say (Hexagonal with 6 lines) this Hexagonal connected from center with 6 point That make 6 triangles
I need when move any point(cause to move triangles) ,, other points move like this point i mean if the left point move to lift other points move to the left and so on
the code I want like this ptcP1.x and ptcP1.y the point that i moving it other point move depend on ptcP1 movement note that, this equations work fine in square shape ,, put in Penta and hexa ..etc this equations in valid so can any one help me
function button1_triggeredHandler( event:Event ):void
{
mode="mode2";
//trace(list.selectedIndex);
if(list.selectedIndex==1)
{
DrawSqure.ptcP1.x = Math.random() + 50;
DrawSqure.ptcP1.y = Math.random() + 50;
DrawSqure.ptcP2.y = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP2.x = DrawSqure.ptcP1.y;
DrawSqure.ptcP3.x = 50-DrawSqure.ptcP1.y;
DrawSqure.ptcP3.y = DrawSqure.ptcP1.x;
DrawSqure.ptcP4.x = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP4.y = 50-DrawSqure.ptcP1.y;
}
As stated in the comments, storing the vertices/points into a container (Array or Vector) and then adjusting those positions when you move is the best way to do it. Here is an example of how that might work:
//setup array or vector of vertices
var polygonVertices:Array = [DrawPolygon.ptcP1, DrawPolygon.ptcP2, DrawPolygon.ptcP3, DrawPolygon.ptcP4];
This method will take all the vertices and apply the translation:
//function for adjusting all the vertices based on the distance you pass
function moveShape( vertices:Array, dx:Number, dy:Number ) {
var i:int;
for ( ; i < vertices.length; i++ ) {
vertices[i].x += dx;
vertices[i].y += dy;
}
}
Then you would just need to know your distance X & Y your shape has moved and you can call moveShape( polygonVertices, 100, 100 );
I inserted 100,100 as the distance parameters as an example, but this should give you the results you are looking for.

circularly layout smaller squares within a large square

Given a bounding square and the total number of smaller squares. The smaller squares need to be drawn within the bigger square evenly spaced out in a circular fashion, just touching but not overlapping. How do you compute the width of the inner square ?
(updated fiddle link)
http://jsfiddle.net/mdluffy/6bUVz/3/
///////// INPUTS ///////////////////////////////////////////
var BoundingBoxSide = 100;
var NofInnerBoxes = 14;
////////////////////////////////////////////////////////////
drawBoxes();
function drawBoxes()
{
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.rect(0,0,BoundingBoxSide,BoundingBoxSide);
ctx.stroke();
for(var i=0; i < NofInnerBoxes; i++)
{
// ************************************************************************************ //
// This needs to be computed so that the boxes touch each other, but not overlap
var innerBoxSide = 20;
// ************************************************************************************ //
var angle = degToRad(i * 360/NofInnerBoxes);
var innerX = ((BoundingBoxSide - innerBoxSide)/2) * Math.cos(angle);
var innerY = ((BoundingBoxSide - innerBoxSide)/2) * Math.sin(angle);
ctx.rect(BoundingBoxSide/2 + innerX - innerBoxSide/2, BoundingBoxSide/2 - innerY - innerBoxSide/2, innerBoxSide, innerBoxSide);
ctx.stroke();
}
}
function degToRad(d)
{
return d * Math.PI / 180;
}
Update:
I'm working on a 3D visualization using Three.js. This is a tree structure with nodes represented as cubes. The child node cubes are layed out circularly on top of the parent node cubes. Applied recursively.
The inner squares need not touch the outer squares, but it should touch the largest circle that can be fit inside the outer square.
Here's my attempt:
var alpha = Math.PI * (NofInnerBoxes - 2) / (2 * NofInnerBoxes)
var t = Math.tan(alpha)
var innerBoxSide = BoundingBoxSide / Math.sqrt(t*t + 4*t + 5)
(Credit: to WolframAlpha for solving for innerBoxSide; and to an envelope I doodled on the back of.)
Update: The above was under the assumption that two sides of each inner square are parallel to a line that passes through the centers of that inner square and the outer square. I now see that this assumption was not what you had in mind.
Here's another approach. In this one, the circles that circumscribe the inner squares will all touch each other, though the inner squares themselves will not quite touch each other:
var alpha = Math.PI / NofInnerBoxes
var t = Math.sin(alpha)
var innerBoxSide = BoundingBoxSide * t / ((t + 1) * Math.sqrt(2))
Result:
Derivation
In response to the request for how the formula was derived...
Let r_s (r sub s) be the "small radius", i.e. the radius of the circles that circumscribe the inner squares. These inner circles are all tangent to the big circle that inscribes the outer square. Call the radius of the big circle r_b (b for "big").
Note that the side of the outer square, a.k.a. BoundingBoxSide, is = 2 * r_b. Note also that the diameter of each inner circle, 2 * r_s, is also the diagonal of each inner square. Therefore the side of each inner square, a.k.a. innerBoxSide, is = (2 * r_s) / sqrt(2).
Now let angle alpha = half the angle that each inner circle subtends (if that's the right verb) around the center of the big circle. I.e. alpha = (2 * pi / NofInnerBoxes) / 2 = pi / NofInnerBoxes.
The key is to draw a right triangle, where one of the angles is alpha; this will tell us the ratios between all the sides of that triangle, using trig functions like sin(). And we can draw such a triangle whose vertices are:
A. The center of the big circle
B. The center of a small circle
C. The point where that small circle touches its neighbor
The right angle is at vertex C, and the angle alpha is at vertex A. The length of side BC = r_s, and the length of the hypotenuse (AB) = r_b - r_s.
So by the definition of sin(), we can say that sin(alpha) = opposite side / hypotenuse = BC / AB = r_s / (r_b - r_s). Solve this equation for r_s, and we get r_s = r_b * sin(alpha) / (1 + sin(alpha)).
Finally, plug in the fact (above) that BoundingBoxSide = 2 * r_b, and innerBoxSide = (2 * r_s) / sqrt(2); and you get the formula shown above, innerBoxSide = BoundingBoxSide * t / ((t + 1) * Math.sqrt(2)).
Sorry this is a longish wall of text, but I hope it's sufficiently clear if read carefully. I may post a diagram as well, if time allows. Let me know if you have questions. (There's probably an easier way to derive this, but that's how I did it.)

Scaling tile grid

I'm working on my own tile bliting engine, this one is using hexagonal tiles - but I think it doesn't differ much from regular tiles.
I have huge x,y array of tiles and they have their x,y coordinates for rendering on canvas, I iterate only the ones that should be visible on canvas in current camera position.
So I'm stuck with scaling and cant resolve this on my own.
Here is my code for drawing tiles on canvas:
public function draw():Void{
clearCanvas(); //Clear canvas (bitmapData)
var _m:Matrix;
iterateTiles(function(_tile:HexTile):Void{ // loop every tile that is visible on screen
_m = new Matrix();
_m.translate(_tile.x + cameraPoint.x,_tile.y + cameraPoint.y);//Get pre calculated tile x,y and add camera x,y
_m.scale(matrixScale, matrixScale);
drawToCanvas(_tile,_m);//Send to draw tile on canvas using Matrix
},true);
}
This works nice and fast but only problem is it scales tiles from left top corner (like regular scale would work)
Before scale
After scale
My question is how to transform tiles to always scale from center. So if tile 10:10 is in center of screen before scaling, then it should
stay there after scaling.
Sorry, I misunderstood the question, but I think I've got it now:
// Scale the distance from the original point to the center of the canvas
var xDistance:Number = ((_tile.x + cameraPoint.x) - xCenter) * matrixScale;
var yDistance:Number = ((_tile.y + cameraPoint.y) - yCenter) * matrixScale;
// Add the distances to the center of the canvas. This is where you want the tile
// to appear.
var x:Number = xCenter + xDistance;
var y:Number = yCenter + yDistance;
// Because the coordinate is going to be scaled, you need to increase it first.
x = (1 / matrixScale) * x;
y = (1 / matrixScale) * y;
_m.translate(x, y);
I have not tested this, I've just drawn it out on graph paper. Let me know if it works.

drawing part of a perfect circle using curveTo

I need to draw a part of a perfect circle using graphics.curveTo (I have the radius and the angle I want to draw) but i cant manage to understand the exact formula for the cotorol x&y in order for the curve to be perfect
I know how to do it with a loop and many lineTo but this is not good enough for my needs...
thanks in advance!
I use this function to draw circle segments (I think I ported it from an online AS2 example on how to draw full circles long ago):
/**
* Draw a segment of a circle
* #param graphics the graphics object to draw into
* #param center the center of the circle
* #param start start angle (radians)
* #param end end angle (radians)
* #param r radius of the circle
* #param h_ratio horizontal scaling factor
* #param v_ratio vertical scaling factor
* #param new_drawing if true, uses a moveTo call to start drawing at the start point of the circle; else continues drawing using only lineTo and curveTo
*
*/
public static function drawCircleSegment(graphics:Graphics, center:Point, start:Number, end:Number, r:Number, h_ratio:Number=1, v_ratio:Number=1, new_drawing:Boolean=true):void
{
var x:Number = center.x;
var y:Number = center.y;
// first point of the circle segment
if(new_drawing)
{
graphics.moveTo(x+Math.cos(start)*r*h_ratio, y+Math.sin(start)*r*v_ratio);
}
// draw the circle in segments
var segments:uint = 8;
var theta:Number = (end-start)/segments;
var angle:Number = start; // start drawing at angle ...
var ctrlRadius:Number = r/Math.cos(theta/2); // this gets the radius of the control point
for (var i:int = 0; i<segments; i++) {
// increment the angle
angle += theta;
var angleMid:Number = angle-(theta/2);
// calculate our control point
var cx:Number = x+Math.cos(angleMid)*(ctrlRadius*h_ratio);
var cy:Number = y+Math.sin(angleMid)*(ctrlRadius*v_ratio);
// calculate our end point
var px:Number = x+Math.cos(angle)*r*h_ratio;
var py:Number = y+Math.sin(angle)*r*v_ratio;
// draw the circle segment
graphics.curveTo(cx, cy, px, py);
}
}
I think it's close enough to perfect circles. I don't really understand the math inside, but I hope the parameters are clear enough for you.
it would be quite difficult to create a perfect circle (or even part of one) using quadratic bezier curves, so don't feel bad.
a long awaited addition to the graphics API came in Flash Player 11 / AIR 3, which is the cubicCurveTo() function that draws cubic bezier curves, which makes drawing things like half circles especially simple.
You cannot draw a perfect circle with Bézier curves. You only approximate it. See http://cgafaq.info/wiki/Bézier_circle_approximation.

How do I calculate the location of points in a rotated shape AS3

I am creating a game in which I draw a series of polygons by creating points around a radius of a cricle.
Later on I rotate the shapes and I need to calculate the new location (X,Y) of the points based on the rotation. I have the Old XY of each point, the XY of the center of the shape, radius of shape and the rotation.
Have a look at my diagram of the problem.
It should be possible to use matrix transformations for this, but you can also do it manually:
http://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/2drota.htm
So essentially;
newX = initialX * Math.cos(angle) - initialY * Math.sin(angle);
newY = initialY * Math.cos(angle) + initialX * Math.sin(angle);
//Angle is in radians btw
This assumes that the initialX/Y is relative to the center of rotation, so you would have to subtract the center point before starting, and then add it again after the calculation to place it correctly.
Hope this helps!
For each point do:
alpha = arctan2(x, y)
len = sqrt(x^2 + y^2)
newX = len * cos(alpha + rotation)
newy = len * sin(alpha + rotation)
Original [x,y] and new [newX,newY] coordinates are both relative to the center of your rotation. If your original [x,y] is absolut, you have to calculate relative first:
x = xAbs - xCenter
y = yAbs - yCenter
Make sure your arctan2 function provides a result of PI/2 or -PI/2 if x=0. Primitive arctan functions do not allow x=0.