bing maps how to get the not share square of 2 rectangle boundaries? - windows-store-apps

I am using bing maps and I want to query my database to return all values inside the map bounds, so every time, the map moves, I want to query it again.
In order to make it more efficient, I want to query only the boundary I haven't query before.
So I get the previous bound and the current bound and want to get the square bound of the non shared rectangle between the previous and the current rectangles (The not shared rectangle of the current bounds).
For example, If I move the map right for 5cm and up for 2cm, I will recieve a new LocationRect of the rectangle 5cm 2cm (the not shared).
I have the map bounds:
LocationRect currentBounds = map.Bounds;
When I move the map I get a new bounds, but before I save the previous bounds:
previousBounds = currentBounds;
I want to get the new location I moved to (only the new, not the whole currentBounds).
So I want to do something like this:
LocationRect newMapBounds = currentBounds.NotSharedBounds(previousBounds);
But how can I check this? I saw there is a method of Intersects but it returns bool, and I need to get the new LocationRect...
I will be very thankfull for the helper :)

If i understand you right you have the blue rectangle(ABCD) and when you move the map
you have red rectangle(EHGF) and you know their vertexes coordinates
e
So the not common space creating 3 new rectangles for you: Green Yellow And Black.
And you need coordinates of those 3 rectangles in order to query your data, in other words you need to perform three queries to you DB in order to get the NOT common space of BLUE and RED rectangles.
You will have scenarios of RED and BLUE rectangles that you need to deal before you start the calculations:
The rectangles are coincide.
The scenario in the picture
They have no common space at all.
For example the vertexes coordinates of GREEN rectangle are(The second scenario):
T(x) = E(x), T(y) = D(y)
F is a common of RED and GREEN Rectangles
N(x) = B(x) , N(y) = G(y)
F is a common of BLUE and GREEN Rectangles
Hope it helps.

Related

Is there a way to determine whether there's a sufficient amount of space in a Pie chart segment for a label?

In the attached Google charts Pie chart the labels fit well inside the segments. Determining the length of a bit of text in HTML5 canvas is easy enough - but how do you determine whether the label will fit into a particular segment (using trigonometry) ? As you can see on the image, two of the segments don't have labels inside the segment.
EDIT: Here's an example of what I have at the moment: https://www.rgraph.net/tests/canvas.pie/in-pie-labels.html
As you see the labels for the small segments overlap. What I'm after is a way to calculate whether there's enough space for the labels at the point where they're going to be rendered. If not, I can just not draw the label like in the example image above.
Could chord size be useful to do this?
Here's the forumulae for the chord size that I found via Google:
"Chord length using trigonometry = 2 × r × sin(θ/2); where 'r' is the radius of the circle and 'θ' is the angle subtended at the center by the chord."
I sorted it (in about one hour) after 3 days of trying to calculate it with trig by using the built-in context.isPointInPath() function...
Draw the text (transparent color) to get the coordinates (x/y/w/h) of it. You might be able to get away with measuring it to get the width and height.
Draw the segment in a transparent color and do not stroke or fill it. Also, do not close the path.
Test each corner of the text rectangle (formed the x/y/w/h that you got above) using the context.isPointInPath() function. If the function returns true for each corner of the rectangle formed by the coordinates of the text, then the text will fit into the segment.

Flash Games: Make a world continuous, circular

I am writing now a flash game and I run into a an issue. I have a map for the game which is defined as a 2-D array, where each element represents a component of the map. The player is always in the center of the map.
The problem is when the player reaches one end of the map. Now it is empty space. I want that the player instead of seeing the empty space, to see another end of the map and in this way, the map will loo like it goes around.
So for example if the player goes to right he will eventually start seeing the the left side of the map and the world will look continuous.
Does anyone knows how to implement this functionality?
You could make the array 2 times and put the first one behind the second one again and than the second one behind the first etc etc..
It's done here with 2 pictures, just use the arrays instead:
//The speed of the scroll movement.
var scrollSpeed:uint = 2;
//This adds two instances of the movie clip onto the stage.
var s1:ScrollBg = new ScrollBg();
var s2:ScrollBg = new ScrollBg();
addChild(s1);
addChild(s2);
//This positions the second movieclip next to the first one.
s1.x = 0;
s2.x = s1.width;
//Adds an event listener to the stage.
stage.addEventListener(Event.ENTER_FRAME, moveScroll);
//This function moves both the images to left. If the first and second
//images goes pass the left stage boundary then it gets moved to
//the other side of the stage.
function moveScroll(e:Event):void{
s1.x -= scrollSpeed;
s2.x -= scrollSpeed;
if(s1.x < -s1.width){
s1.x = s1.width;
}else if(s2.x < -s2.width){
s2.x = s2.width;
}
}
You simply check if your player is about to get off the "right" or "left" edge of the map, and position him at the other edge. To draw a circular map, you can use the following technique: if you are about to draw a column of a number that exceeds the map's width, decrease that number by width and draw the column at resultant index; and if you are about to draw a column at index below zero, add width and draw the column at resultant index. If you are in troubles of making a hitcheck at continuous map's borders, you can employ the same trick to find neighbors. (The "circular array" is a pretty basic algorithmic problem, and is resolved in many ways already)
You have a few options here. You can do the pac-man style of just making your character pop up on the other side of the screen, but that would require you to abandon the cool bit of the character being in the middle at all times.
On to the real suggestions:
If you're not implementing your array as one solid object (i.e. making it draw individual collumns/rows at a time) then this is a no-brainer. Just have a function that returns the index of the next collumn/row, within certain bounds. Like, if your array is 40 elements wide, when it tries to draw element 41, subtract the size of the array, and make it draw element 1 instead.
If your array is one solid object (like if you drew it onto a stage object and are just manipulating that) and it's not very big, you could probably get away with drawing a total of four of them, and just having a new one cover up any whitespace that's about to appear. Like, as you approach the right edge of the first array, the second array moves to the right of it for a lawless transition.
If your array is a solid object and is very big, perhaps you could make eight buffer objects (one per edge and one per corner) that hold approximately half a screen's worth of the array. That way as you approach the right edge, you see the left edge, but then when you cross into the buffer zone, you could teleport the player to the corresponding position on the left of the array, which has the buffer for the right size. To the player, nothing has changed, but now they're on the other side of the world.

Moving shape within the polygon

Test link: http://bit.ly/Runmah
pick one item from left side for testing.
it's rotating when he find two intersect points on the line.
i want to move red rectangle within the polygon. It shouldn't go outside of polygon.
My code is: http://pastebin.com/pRMpk81f
Edit 1: http://pastebin.com/C3j4WSC1
If you know how to find the intersection of points on the line then you should be able to find distance between wall and furniture (line and edge of rectangle), you can check this value and for example stop draging and snap,
EDIT1:
when dragged item is selected (mouse is down) than you constantly check distance (e.g. on mouse move), then you can decide that if distance is within some threshold you will stop movement (basicaly you will set calculated position- snap - instead of applying mouse position) otherwise you will follow mouse.
EDIT2:
also you can test if the point is inside the shape by calculating intersection points - even number the point is outside, odd number - the point is inside
best regards

AS3 - geometry - perspective projection of a point on a 2D plane

I'm currently struggling on a problem that seems far beyond my maths capacities (been a long time since I've made some proper maths...) and I would appreciate some help on that.
Here's my setting :
I got some simple shapes (rectangles), and I "project" their bottom points on a line, coming from an Origin point.
Up to this point everything is fine.
But now I'd like to draw the original shape distorted as if it was projected with some perspective on a plane.
Please consider that I have nothing related to any rotation, isometric or any 3D or fake 2D perspective in my code, I'm only trying to draw some shapes using the graphics library to only have a feeling of something real.
Here's a quick drawing of what I'm trying to do :
What I know :
Origin point coordinates
the rect position & sizes
the red line position
the A & B points coordinates
What I want to determine is the coordinates of the C & D points, thing that could be easy if I wasn't struggling to find the "Origin bis" coordinates.
What I'm trying to do is to fake the projection of my rectangle on something that can be considered as a "floor" (related to the plane where my original rectangle is that can be seen as a wall).
Maybe I'm over-complicating the problem or maybe I fail to see any other easier way to do it, but I'm really not good anymore in any geometry or maths thing... :-(
Thanks a lot for your answers !
hmm i don't know if I undestood it correctly but I think you have too few input parameters:
you said the following information is given:
Origin point coordinates
the rect position & sizes
the red line position
the A & B points coordinates
I don't think it is possible to get your projected rectangle with this information alone.
Additionally, I think your green lines and the 'origin Bis' aren't helpful as well.
Perhaps, try this:
Supose, a blue line going through the points C & D is given as well.
Then you could find your projected rectangle by projecting the top of the rectangle onto that blue line.
So in summary:
You define an origin + two parallel lines, a red and a blue one.
Then you can project the top of the rect onto the blue line and the bottom of the rect onto the red line, yielding the points A,B,C,D
I hope this helps.
If I'm right, this code will show what you wanted to see.
First of all, I've ignored your initial setup of objects and information, and focused on the example situation itself; fake-projecting shadow for a "monolith" (any object is possible with the example below, even textured)
My reason was that it's really quite easy with the Matrix class of ActionScript, a handy tool worth learning.
Solution:
You can use the built-in Matrix class to do skew transform on DisplayObjects.
Try this example:
(The "useful" part lies in the _EF EnterFrame handler ;) )
import flash.display.MovieClip;
import flash.geom.Matrix;
import flash.events.Event;
import flash.display.BitmapData;
const PIP180:Number = Math.PI / 180;
const MAX_SHADOW_HEIGHT_MULTIPLIER:Number = 0.25; // you can also calculate this from an angle, like ... = Math.sin(angle * PIP180);
const ANIM_DEG_PER_FRAME:Number = 1.0 * PIP180; // the shadow creeps at a +1 degree per frame rate
var tx:BitmapData = new MonolithTexture(); // define this BitmapData in the library
var skew:Number = -10 * PIP180; // initial
var mono:MovieClip = new MovieClip();
mono.graphics.beginBitmapFill(tx);
// drawn that way the registration point is 0,0, so it's standing on the ground
mono.graphics.drawRect(0, -tx.height, tx.width, tx.height);
mono.graphics.endFill();
// align monolith to the "ground"
mono.x = stage.stageWidth / 2;
mono.y = stage.stageHeight - 100;
// make it be 100x300 pixel
mono.width = 100;
mono.height = 300;
var shad:MovieClip = new MovieClip();
// colored:
shad.graphics.beginFill(0x000000);
// or textured:
//shad.graphics.beginBitmapFill(tx);
shad.graphics.drawRect(0, -tx.height, tx.width, tx.height);
shad.graphics.endFill();
addChild(shad); // shadow first
addChild(mono); // then the caster object
addEventListener(Event.ENTER_FRAME, _EF);
function _EF(e:Event):void {
// animate skew on the positive half circle
skew = (skew + ANIM_DEG_PER_FRAME) % Math.PI;
// Matrix takes 6 parameters: a, b, c, d, x, y
// for this shadow trick, use them as follows:
// a = width scaling (as mono and shad are drawn in the same way, copy mono.scaleX for a perfect fit
// b = 0, because we don't want to project the vertical axis of transformation to the horizontal
// c = horizontal skew
// d = height scaling * skew * making it a bit flat using the constant
// x = mono.x, ...
// y = mono.y since originally mono and shad look alike, only the Matrix makes shad render differently
var mtx:Matrix = new Matrix(mono.scaleX, 0, Math.cos(skew), mono.scaleY * Math.sin(skew) * MAX_SHADOW_HEIGHT_MULTIPLIER, mono.x, mono.y);
shad.transform.matrix = mtx;
}
Now all you got to know to utilize this in your case, is the following N factors:
Q1: from what angle you want to project the shadow?
A1: horizontal factor is the skew variable itself, while vertical angle is stored as constant here, called MAX_SHADOW_HEIGHT_MULTIPLIER
Q2: do you want to project shadow only "upwards", or freely?
A2: if "upwards" is fine, keep skew in the positive range, otherwise let it take negative values as well for a "downward" shadow
P.S.: if you render the internals of the objects that they don't snap to 0 y as a base point, you can make them seem float/sink, or offset both objects vertically with a predefined value, with the opposite sign.
You face 1 very simple problem, as you said:
'What I want to determine is the coordinates of the C & D points, thing that could be easy if I wasn't struggling to find the "Origin bis" coordinates.'
But these co-ordinates relate to each other, so without one (or another value such as an angle) you cannot have the other. If you are to try this in 3D you are simply allowing the 3D engine to define 'Origin bis' and do your calculating for C and D itself.
So regardless you will need an 'Original bis', another value relating to the redline or your Rect for which to calculate the placement of C and D.
I remember making stuff like this and sometimes it's better to just stick with simple, you either make an 'Original bis' defines by yourself (it can be either stationary or move with the player/background) and get C and D the way you got A and B only that you use a lower line than the red line, or as I would of done, once you have A and B, simple skew/rotate your projection from those points down a bit further, and you get something the same as an 'Original bis' that follows the player. This works fine at simulating 'feeling of something real' but sadly as has been said, it looking real depends on what you are portraying. We do not know what the areas above or below the red line are (sky/ground, ground/water) and whether 'Origin' and 'Origin bis' is your light source, vanishing point, etc.

Finding a free area in the stage

I'm drawing rectangles at random positions on the stage, and I don't want them to overlap.
So for each rectangle, I need to find a blank area to place it.
I've thought about trying a random position, verify if it is free with
private function containsRect(r:Rectangle):Boolean {
var free:Boolean = true;
for (var i:int = 0; i < numChildren; i++)
free &&= getChildAt(i).getBounds(this).containsRect(r);
return free;
}
and in case it returns false, to try with another random position.
The problem is that if there is no free space, I'll be stuck trying random positions forever.
There is an elegant solution to this?
Let S be the area of the stage. Let A be the area of the smallest rectangle we want to draw. Let N = S/A
One possible deterministic approach:
When you draw a rectangle on an empty stage, this divides the stage into at most 4 regions that can fit your next rectangle. When you draw your next rectangle, one or two regions are split into at most 4 sub-regions (each) that can fit a rectangle, etc. You will never create more than N regions, where S is the area of your stage, and A is the area of your smallest rectangle. Keep a list of regions (unsorted is fine), each represented by its four corner points, and each labeled with its area, and use weighted-by-area reservoir sampling with a reservoir size of 1 to select a region with probability proportional to its area in at most one pass through the list. Then place a rectangle at a random location in that region. (Select a random point from bottom left portion of the region that allows you to draw a rectangle with that point as its bottom left corner without hitting the top or right wall.)
If you are not starting from a blank stage then just build your list of available regions in O(N) (by re-drawing all the existing rectangles on a blank stage in any order, for example) before searching for your first point to draw a new rectangle.
Note: You can change your reservoir size to k to select the next k rectangles all in one step.
Note 2: You could alternatively store available regions in a tree with each edge weight equaling the sum of areas of the regions in the sub-tree over the area of the stage. Then to select a region in O(logN) we recursively select the root with probability area of root region / S, or each subtree with probability edge weight / S. Updating weights when re-balancing the tree will be annoying, though.
Runtime: O(N)
Space: O(N)
One possible randomized approach:
Select a point at random on the stage. If you can draw one or more rectangles that contain the point (not just one that has the point as its bottom left corner), then return a randomly positioned rectangle that contains the point. It is possible to position the rectangle without bias with some subtleties, but I will leave this to you.
At worst there is one space exactly big enough for our rectangle and the rest of the stage is filled. So this approach succeeds with probability > 1/N, or fails with probability < 1-1/N. Repeat N times. We now fail with probability < (1-1/N)^N < 1/e. By fail we mean that there is a space for our rectangle, but we did not find it. By succeed we mean we found a space if one existed. To achieve a reasonable probability of success we repeat either Nlog(N) times for 1/N probability of failure, or N² times for 1/e^N probability of failure.
Summary: Try random points until we find a space, stopping after NlogN (or N²) tries, in which case we can be confident that no space exists.
Runtime: O(NlogN) for high probability of success, O(N²) for very high probability of success
Space: O(1)
You can simplify things with a transformation. If you're looking for a valid place to put your LxH rectangle, you can instead grow all of the previous rectangles L units to the right, and H units down, and then search for a single point that doesn't intersect any of those. This point will be the lower-right corner of a valid place to put your new rectangle.
Next apply a scan-line sweep algorithm to find areas not covered by any rectangle. If you want a uniform distribution, you should choose a random y-coordinate (assuming you sweep down) weighted by free area distribution. Then choose a random x-coordinate uniformly from the open segments in the scan line you've selected.
I'm not sure how elegant this would be, but you could set up a maximum number of attempts. Maybe 100?
Sure you might still have some space available, but you could trigger the "finish" event anyway. It would be like when tween libraries snap an object to the destination point just because it's "close enough".
HTH
One possible check you could make to determine if there was enough space, would be to check how much area the current set of rectangels are taking up. If the amount of area left over is less than the area of the new rectangle then you can immediately give up and bail out. I don't know what information you have available to you, or whether the rectangles are being laid down in a regular pattern but if so you may be able to vary the check to see if there is obviously not enough space available.
This may not be the most appropriate method for you, but it was the first thing that popped into my head!
Assuming you define the dimensions of the rectangle before trying to draw it, I think something like this might work:
Establish a grid of possible centre points across the stage for the candidate rectangle. So for a 6x4 rectangle your first point would be at (3, 2), then (3 + 6 * x, 2 + 4 * y). If you can draw a rectangle between the four adjacent points then a possible space exists.
for (x = 0, x < stage.size / rect.width - 1, x++)
for (y = 0, y < stage.size / rect.height - 1, y++)
if can_draw_rectangle_at([x,y], [x+rect.width, y+rect.height])
return true;
This doesn't tell you where you can draw it (although it should be possible to build a list of the possible drawing areas), just that you can.
I think that the only efficient way to do this with what you have is to maintain a 2D boolean array of open locations. Have the array of sufficient size such that the drawing positions still appear random.
When you draw a new rectangle, zero out the corresponding rectangular piece of the array. Then checking for a free area is constant^H^H^H^H^H^H^H time. Oops, that means a lookup is O(nm) time, where n is the length, m is the width. There must be a range based solution, argh.
Edit2: Apparently the answer is here but in my opinion this might be a bit much to implement on Actionscript, especially if you are not keen on the geometry.
Here's the algorithm I'd use
Put down N number of random points, where N is the number of rectangles you want
iteratively increase the dimensions of rectangles created at each point N until they touch another rectangle.
You can constrain the way that the initial points are put down if you want to have a minimum allowable rectangle size.
If you want all the space covered with rectangles, you can then incrementally add random points to the remaining "free" space until there is no area left uncovered.