View Full Version : Calculate the distance between 2 objects! But with heigth and width for calculating!
D I C E
02-20-2008, 05:01 PM
Hey dudes!
Humm, i need some help with one thing, i have many objects in the stage, and i use the mouse to calculate the distance between a random target in this stage, using the x and y position of mouse, i can do this perfectly getting the x and y position of target object.
A use that to give me in % the distance of target object, and starting animations, between the percentage.
Today i use the Pythagorean theorem. to do that.
c = Math.sqrt(Math.pow(a, 2)+Math.pow(b, 2));
But, now i need that be influenced by the width and height of object, as they _x,_y, stay allong the object, a do a little draw to better explanation:
http://img185.imageshack.us/img185/6942/pytagorasii6.gif
Someone can help me? With this? What i have to do, to getting the 0% all over the object.
Thanks, for the help!!
inhan
02-20-2008, 05:18 PM
Which side are we trying to calculate? Side with 70% or side with 50%?
xxneon
02-20-2008, 05:45 PM
i think he is trying to figure out a way to calculate the shortest distance from any point..
cause by looking at his example image its showing how his code is determining the distance based on 2 possible registration points..
my theory would be .. you would almost need to use MovieClip.getBounds.. to get the four corners .. and if your below the top edge of the object then all you would do is
var targetBounds = target_mc.getBounds(this);
then that will return xMin,xMax,yMin,yMax values based on the stage... and then you can determine your distance based on those values instead of the registration point..
You need to calculate the angle between the MC X and Y coordinates and the mouse, then using the width or height divided by two you calculate the distance between the MC X,Y coordinate and its border according to the angle. Then you subtract the result from your c variable.
xxneon
02-20-2008, 06:00 PM
i was going to say .. something like this ..
if (_ymouse > targetBounds.yMin && _ymouse < targetBounds.yMax &&
_xmouse > targetBounds.xMax){
var distance = _xmouse-targetBounds.xMax;
}
understandably though this method is alot of if conditions.. to track the distance of the mouse from any where around the target object.
D I C E
02-20-2008, 06:32 PM
Thanks for all help guys!
I work on it now, and i try do what the xxneon, tell me: here is the code:
var x1:Number = _root._xmouse;
var y1:Number = _root._ymouse;
var x2:Number = this.hintManager.targetIten.getMovie()._x;
var y2:Number = this.hintManager.targetIten.getMovie()._y;
var targetBounds = this.hintManager.targetIten.getMovie().getBounds(t his);
var dist:Number = Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2));
if (y1 > targetBounds.yMin && y1 < targetBounds.yMax && x1 > targetBounds.xMax)
{
var dist = x1- targetBounds.xMax;
}
var porc:Number = dist / 500;
porc = Math.floor(porc * 100);
But, noting work at now. But the problem is, when the target is much wide, only the center of target, is the 0% of total discance and, i need all target return 0% for me :P
Anyone?
xxneon
02-20-2008, 07:19 PM
very ugly ... but it works.. this calculates the distance from the edge of the rectangle..
this.createTextField("txt",0,0,0,5,5);
txt.autoSize = true;
var tObjBounds = target_obj.getBounds(this); //just change 'target_obj' to the instance that you want to target for the distance..
function onMouseMove() {
var x = _xmouse;
var y = _ymouse;
if (y>tObjBounds.yMin && y<tObjBounds.yMax) {
if (x>tObjBounds.xMax) {
var distance = x-tObjBounds.xMax;
} else if (x<tObjBounds.xMin) {
var distance = tObjBounds.xMin-x;
}
}
if (x>tObjBounds.xMin && x<tObjBounds.xMax) {
if (y>tObjBounds.yMax) {
var distance = y-tObjBounds.yMax;
} else if (y<tObjBounds.yMin) {
var distance = tObjBounds.yMin-y;
}
}
if (x<tObjBounds.xMin && y<tObjBounds.yMin) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMin-x), 2)+Math.pow((tObjBounds.yMin-y), 2));
}
if (x>tObjBounds.xMax && y<tObjBounds.yMin) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMax-x), 2)+Math.pow((tObjBounds.yMin-y), 2));
}
if (x>tObjBounds.xMax && y>tObjBounds.yMax) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMax-x), 2)+Math.pow((tObjBounds.yMax-y), 2));
}
if (x<tObjBounds.xMin && y>tObjBounds.yMax) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMin-x), 2)+Math.pow((tObjBounds.yMax-y), 2));
}
txt.text = "dist: "+distance;
}
i'm sure there is a better way to do it.
D I C E
02-20-2008, 08:41 PM
very ugly ... but it works.. this calculates the distance from the edge of the rectangle..
this.createTextField("txt",0,0,0,5,5);
txt.autoSize = true;
var tObjBounds = target_obj.getBounds(this); //just change 'target_obj' to the instance that you want to target for the distance..
function onMouseMove() {
var x = _xmouse;
var y = _ymouse;
if (y>tObjBounds.yMin && y<tObjBounds.yMax) {
if (x>tObjBounds.xMax) {
var distance = x-tObjBounds.xMax;
} else if (x<tObjBounds.xMin) {
var distance = tObjBounds.xMin-x;
}
}
if (x>tObjBounds.xMin && x<tObjBounds.xMax) {
if (y>tObjBounds.yMax) {
var distance = y-tObjBounds.yMax;
} else if (y<tObjBounds.yMin) {
var distance = tObjBounds.yMin-y;
}
}
if (x<tObjBounds.xMin && y<tObjBounds.yMin) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMin-x), 2)+Math.pow((tObjBounds.yMin-y), 2));
}
if (x>tObjBounds.xMax && y<tObjBounds.yMin) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMax-x), 2)+Math.pow((tObjBounds.yMin-y), 2));
}
if (x>tObjBounds.xMax && y>tObjBounds.yMax) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMax-x), 2)+Math.pow((tObjBounds.yMax-y), 2));
}
if (x<tObjBounds.xMin && y>tObjBounds.yMax) {
var distance = Math.sqrt(Math.pow((tObjBounds.xMin-x), 2)+Math.pow((tObjBounds.yMax-y), 2));
}
txt.text = "dist: "+distance;
}
i'm sure there is a better way to do it.
:o:o:o
i try implement now!
inhan
02-21-2008, 01:06 PM
Hey guys, I have another one. Hope it helps. The main function here is "getDistance". Remaining is for displaying purposes.
var rect:MovieClip = this.createEmptyMovieClip("rect_mc", 0);
with (rect) {
_x = 50;
_y = 50;
beginFill(0x000000, 100);
lineTo(30, 0);
lineTo(30, 260);
lineTo(0, 260);
lineTo(0, 0);
endFill();
}
rect.onMouseMove = function() {
var distance:Number = getDistance(this);
trace("distance: "+distance);
};
function getDistance(fromMC:MovieClip):Number {
var bounds:Object = fromMC.getBounds(_root);
var X:Number = _level0._xmouse;
var Y:Number = _level0._ymouse;
var point1:Number;
var point2:Number;
var dist:Number;
if (fromMC.hitTest(_level0._xmouse, _level0._ymouse)) dist = 0;
else {
if (X < bounds.xMin) point1 = bounds.xMin - X;
else if (X > bounds.xMax) point1 = X - bounds.xMax;
if (Y < bounds.yMin) point2 = bounds.yMin - Y;
else if (Y > bounds.yMax) point2 = Y - bounds.yMax;
dist = Math.sqrt(Math.pow(point1,2)+Math.pow(point2,2));
if (X >= bounds.xMin && X <= bounds.xMax) dist = Y <= bounds.yMin ? bounds.yMin - Y : Y - bounds.yMax;
else if (Y >= bounds.yMin && Y <= bounds.yMax) dist = X <= bounds.xMin ? bounds.xMin - X : X - bounds.xMax;
}
return dist;
};
xxneon
02-21-2008, 01:24 PM
thanks inhan for optimizing it a bit.. i see you took care of the occational undefined distance that my code was getting .. its cause i was evaluating all with '<' or '>' .. i didnt have any '<=' or '>=' which i knew i had to do that but didnt have time to figure out which if conditions to add it to.
inhan
02-21-2008, 01:26 PM
That also had taken my attention while it returned NaN. A last-moment correction..
xxneon
02-21-2008, 01:33 PM
also i dont think this code would work on objects that rotate.. cause then you would have to have some additional calculations..
D I C E
02-21-2008, 02:30 PM
Hey inhan! Nice work, i do something like this, yesterday! BUT, now i have another little problem.
LOOK the image attached.
Using the actual method of getBounds, when target is curved, the box in the flash, is give-me the 0 distance, all long the box.
Any other idea?
xxneon
02-21-2008, 02:34 PM
with any objects that are not 4 sided square / rectangle would require more complex calculations to determine an accurate distance.. much like my comment about if an object is rotated..
D I C E
02-21-2008, 02:37 PM
also i dont think this code would work on objects that rotate.. cause then you would have to have some additional calculations..
exact xxneon! There is the big problem!
it's more accurate using trigo, but of course it's less understandable if you are not used to:
var hyp //the value to substract from the mouse/MC distance
this.onEnterFrame = function(){
var spotX = the_mc._x-_xmouse;
var spotY = the_mc._y-_ymouse;
var mouseangle = Math.atan2(the_mc._y-_ymouse, the_mc._x-_xmouse);
var mouseanglecompare = mouseangle/(Math.PI/180);
var ratio = Math.atan2(the_mc._height, the_mc._width);
var ratiocompare = ratio/(Math.PI/180);
if( (mouseanglecompare<ratiocompare) && (mouseanglecompare>ratiocompare*-1) ) {
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else if( (mouseanglecompare>Math.abs(ratiocompare-180)) && (mouseanglecompare<180) ){
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else if( (mouseanglecompare<ratiocompare-180) && (mouseanglecompare>-180) ){
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else{hyp = the_mc._height/2 / Math.sin(mouseangle);}
var distance = Math.sqrt((spotX*spotX)+(spotY*spotY))-Math.abs(hyp);
trace(distance)
}
xxneon
02-21-2008, 04:53 PM
ASWC .. this was sorta what i was thinking of doing .. just i would of had to look up the trig.. will this work with rotated objects?
No it's really basic right now but can be improved of course for rotating objects.
D I C E
02-21-2008, 05:18 PM
Humm, i try understand that but is very hard for me! if anyone can help me to improve this, to see rotate targets?! I´m appreciate !
it's more accurate using trigo, but of course it's less understandable if you are not used to:
var hyp //the value to substract from the mouse/MC distance
this.onEnterFrame = function(){
var spotX = the_mc._x-_xmouse;
var spotY = the_mc._y-_ymouse;
var mouseangle = Math.atan2(the_mc._y-_ymouse, the_mc._x-_xmouse);
var mouseanglecompare = mouseangle/(Math.PI/180);
var ratio = Math.atan2(the_mc._height, the_mc._width);
var ratiocompare = ratio/(Math.PI/180);
if( (mouseanglecompare<ratiocompare) && (mouseanglecompare>ratiocompare*-1) ) {
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else if( (mouseanglecompare>Math.abs(ratiocompare-180)) && (mouseanglecompare<180) ){
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else if( (mouseanglecompare<ratiocompare-180) && (mouseanglecompare>-180) ){
hyp = the_mc._width/2 / Math.cos(mouseangle);
}
else{hyp = the_mc._height/2 / Math.sin(mouseangle);}
var distance = Math.sqrt((spotX*spotX)+(spotY*spotY))-Math.abs(hyp);
trace(distance)
}
inhan
02-21-2008, 05:37 PM
The last time I used trigonometry was in high school (10-11 years ago) so at this point I'm disqualified from the game. Let masters speak now :)
you can tweak the code by subtracting the rotation value from the returned angle and output the right distance.
D I C E
02-21-2008, 06:05 PM
you can tweak the code by subtracting the rotation value from the returned angle and output the right distance.
But the problem is, the rotation of objects is not dynamic, is static, the PNG os targets, are "rotated"
so your importing pics that are rotated already. The trig for that would be a way more complicated, many go back the xxneon solution or look into creating an invisible ray and using hiTest(x,y,true) to return the distance.
xxneon
02-21-2008, 06:17 PM
yea i would think the only way you could do that is by using pixel value checking .. which this is just a theory .. but invisible line from the center of the loaded png to the mouse pointer .. and then do some math to test a pixel by pixel along that line till it reaches the edge of the png.. and store the value of the first pixel that is transparent with no color.. and then use that value to determine the difference in the invisible line.. but this is all theoretical and way over my head for the calculation standpoint..
xxneon
02-21-2008, 06:18 PM
aswc .. would hitTest(x,y,true) with a png evaluate true overtop of transparent area of the png?
D I C E
02-21-2008, 06:18 PM
so your importing pics that are rotated already. The trig for that would be a way more complicated, many go back the xxneon solution or look into creating an invisible ray and using hiTest(x,y,true) to return the distance.
haah thanks ASWC! Back from the beginning!
Ok, now going again, any other ideas?
Yes xxneon I'm pretty sure it would work. I might give it a try later on and post my results.
D I C E
02-21-2008, 06:46 PM
Yes xxneon I'm pretty sure it would work. I might give it a try later on and post my results.
i w8 your results!
xxneon
02-21-2008, 06:47 PM
what i meant was .. if you hitTest over the png .. and its transparent.. will it still say that the x,y values are hitting the png movieclip.. or will it treat it like true transparency and return false?
I perfectly understood xxneon and we will see how it works but if it doesn't I already see a work around using the bitmapClass that could work.
xxneon
02-21-2008, 07:01 PM
yea that was what i was thinking about when i had my theory in the previous post ..
xxneon
02-21-2008, 07:12 PM
did a quick test with a png .. and the hittest is true on any part of the png.. so it looks like bitmapdata is the next thing to try..
Very basic with an accuracy that I estimate at +-5%:
the_mc._rotation = 30;
var dist = 0;
var outerDist = 0;
this.onMouseUp = function(){
checkDist();
}
function checkDist(){
ray_mc._x=_xmouse;
ray_mc._y=_ymouse;
power=Math.sqrt((_xmouse-the_mc._x)*(_xmouse-the_mc._x)+(_ymouse-the_mc._y)*(_ymouse-the_mc._y))/40;
var adjacent:Number = the_mc._x-_xmouse;
var opposite:Number = the_mc._y-_ymouse;
angle =( Math.atan2(opposite, adjacent))*(180/Math.PI);
Xspeed=Math.cos(angle*Math.PI/180)*power;
Yspeed=Math.sin(angle*Math.PI/180)*power;
ray_mc.onEnterFrame=function(){
dist_x = the_mc._x-_xmouse;
dist_y = the_mc._y-_ymouse;
dist = Math.sqrt((dist_x*dist_x)+(dist_y*dist_y));
ray_mc._x+=Xspeed
ray_mc._y+=Yspeed
if(the_mc.hitTest(ray_mc._x, ray_mc._y, true)){
outerDist = Math.sqrt(((ray_mc._x-_xmouse)*(ray_mc._x-_xmouse))+((ray_mc._y-_ymouse)*(ray_mc._y-_ymouse)));
trace("Distance from the mouse to the edge: "+outerDist)
trace("Distance from the mouse to the center: "+dist)
Xspeed=0;
Yspeed=0;
delete this.onEnterFrame;
}}
}
the_mc would be the rotated mc, and ray_mc would be an mc that you use to check the distance. Remember, this is just theory. Now, you need to use the bitmapData class to draw on a MC the pics you load. Maybe I'll pass on this one to xxneon!
xxneon
02-21-2008, 09:25 PM
hah.. i would think you could almost get away with once the ray_mc has its first successful hittest.. then you could draw a Bitmap of that movieclip and then start doing a x,y getPixel32() and see if its a value for transparency..
import flash.display.BitmapData;
var bmp:BitmapData = new BitmapData(the_mc._width, the_mc._height, true, 0);
bmp.draw(the_mc);
the_mc._rotation = 30;
var dist = 0;
var outerDist = 0;
this.onMouseUp = function(){
checkDist();
}
function checkDist() {
ray_mc._x = _xmouse;
ray_mc._y = _ymouse;
power = Math.sqrt((_xmouse-the_mc._x)*(_xmouse-the_mc._x)+(_ymouse-the_mc._y)*(_ymouse-the_mc._y))/40;
var adjacent:Number = the_mc._x-_xmouse;
var opposite:Number = the_mc._y-_ymouse;
angle = (Math.atan2(opposite, adjacent))*(180/Math.PI);
Xspeed = Math.cos(angle*Math.PI/180)*power;
Yspeed = Math.sin(angle*Math.PI/180)*power;
ray_mc.onEnterFrame = function() {
dist_x = the_mc._x-_xmouse;
dist_y = the_mc._y-_ymouse;
dist = Math.sqrt((dist_x*dist_x)+(dist_y*dist_y));
ray_mc._x += Xspeed;
ray_mc._y += Yspeed;
if (the_mc.hitTest(ray_mc._x, ray_mc._y, true)) {
point = {x:ray_mc._x,y:ray_mc._y};
the_mc.globalToLocal(point);
var pixel = bmp.getPixel32(point.x >> 0, point.y >> 0);
if (pixelValue != 0) {
outerDist = Math.sqrt(((ray_mc._x-_xmouse)*(ray_mc._x-_xmouse))+((ray_mc._y-_ymouse)*(ray_mc._y-_ymouse)));
trace("Distance from the mouse to the edge: "+outerDist);
trace("Distance from the mouse to the center: "+dist);
Xspeed = 0;
Yspeed = 0;
delete this.onEnterFrame;
}
}
};
}
here you go .. not sure if it works .. but i did a simple test with the mouse moving over a simple png that i made and it was working.. for detecting when the mouse was over transparent areas.. ASWC wanna test it ??
xxneon
02-21-2008, 09:37 PM
i also noticed since i am using globalToLocal.. it returns the x,y value of inside the_mc at its normal state if it werent rotated .. even though its rotated .. so its pixel perfect :).. i hope that makes sense..
here is my little mouse test if you want to see it..
not working for me so far but we're close.
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.