Jump to content


Photo

Jumping to random position within limits


  • Please log in to reply
5 replies to this topic

#1 SNWrestler

SNWrestler

    GMC Member

  • New Member
  • 290 posts

Posted 05 March 2011 - 01:13 AM

So situaion is at event creation I have Jump to location for an explosion object. You view it inside a binocular.

I want to do one of 2 things,

1. Have it jump to a position within a circle (preferred), the horizontal diameter is 19-684; vertical diameter is 27-691.

2. Have it jump to a position within a square (I understand the circle might take some tough trig) dimensions are X=111 to 622; Y= 131 to 690

Im thinking it would be something to the effect of D&D jump to position 'X_111<X<622' some of the collective genius here would help, thanks

Edit: Yes I reported my topic, wrong forum

Edited by SNWrestler, 05 March 2011 - 01:40 AM.

  • 0

#2 wolfrider219

wolfrider219

    GMC Member

  • New Member
  • 118 posts

Posted 05 March 2011 - 01:54 AM

To jump to a random place in a circle; put the object in the center of the circle, then move it a random distance (within the diameter of the circle) in a random direction.

The center of the circle is at 351,359 and the radius of your circle is 332, so:
var dir;
dir = round(random(360));
x = 351+lengthdir_x(round(random(332)),dir);
y = 359+lengthdir_y(round(random(332)),dir);
I havn't tested it, but it should work (I think).
  • 0

#3 wosci

wosci

    GMC Member

  • GMC Member
  • 201 posts

Posted 05 March 2011 - 11:38 AM

This is an easy one, for the cirkle:
//length=half of the horizontal radius from original position length*(691/684)=half of the vertical radius
var length, dir;
dir=random(360)
length=random(332.5)

//making the position
x+=(9.5+length)*cos(degtorad(dir))
y+=(13.5+length*(691/684))*sin(degtorad(dir))
The code above is built for relative jumping, so put the cirkle wherever you like
or when you have 1 fixed position use this code:
//length=half of the horizontal radius from original position length*(691/684)=half of the vertical radius
var length, dir;
dir=random(360)
length=random(332.5)

//making the position
x=<insert original x position here>+(9.5+length)*cos(degtorad(dir))
y=<insert original y position here>+(13.5+length*(691/684))*sin(degtorad(dir))


for the square:
x=111+random(511)
y=131+random(559)
This is fixed to X=111 to 622; Y= 131 to 690

If you have any questions, ask them.

Edited by wosci, 05 March 2011 - 11:46 AM.

  • 0

#4 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1592 posts
  • Version:GM8.1

Posted 05 March 2011 - 09:13 PM

for the square:

x=111+random(511)
y=131+random(559)
This is fixed to X=111 to 622; Y= 131 to 690

Correct.

//making the position
x=<insert original x position here>+(9.5+length)*cos(degtorad(dir))
y=<insert original y position here>+(13.5+length*(691/684))*sin(degtorad(dir))[/code]

It will work, but it will not have an even distribution. Assuming random() distrubutes values evenly, there will be a lot of values in areas near the center and few in areas near the edge.
My suggestion (assuming a circle at the origin with radius 1):
x = random(2) - 1;
x *= abs(x);   //  The approximation I gave should be close enough. Mess with it if you want. The goal is an even distribution of points. When testing this one, watch for uneven distribution on the sides and middle.
y = (random(2) - 1) * sqrt(1 - x * x);

  • 0

#5 slayer 64

slayer 64

    GMC Member

  • GMC Member
  • 3278 posts
  • Version:GM8.1

Posted 05 March 2011 - 10:18 PM

it will not have an even distribution. Assuming random() distrubutes values evenly, there will be a lot of values in areas near the center and few in areas near the edge.
My suggestion (assuming a circle at the origin with radius 1):

x = random(2) - 1;
x *= abs(x);   //  The approximation I gave should be close enough. Mess with it if you want. The goal is an even distribution of points. When testing this one, watch for uneven distribution on the sides and middle.
y = (random(2) - 1) * sqrt(1 - x * x);

that's an interesting technique. never seen it before. just as you said, it favors the middle a lot =/
i set up a test. the green dots are distributed most evenly.
Posted Image
radius=100

draw_set_color(c_black)
draw_circle(200,110,radius,1)
draw_circle(440,110,radius,1)
draw_circle(320,300,radius,1)

draw_set_color(c_blue)
draw_text(5,5,"evenly placed")

repeat 2000
{
    x=random(2)-1
    x*=abs(x)
    y=(random(2)-1)*sqrt(abs(1-x*x))
    
    x*=radius
    y*=radius
    
    draw_circle(200+x,110+y,2,0)
}

draw_set_color(c_red)
draw_text(5,35,"maybe not even")

repeat 2000
{
    a=random(360)
    r=random(radius)
    
    x=lengthdir_x(r,a)
    y=lengthdir_y(r,a)
    
    draw_circle(440+x,110+y,2,0)
}
draw_set_color(c_green)
draw_text(5,55,"perfect")

repeat 2000
{
    do
    {
        x=-radius+random(radius*2)
        y=-radius+random(radius*2)
    }
    until point_distance(0,0,x,y)<radius
    
    draw_circle(320+x,300+y,2,0)
}

  • 0

#6 Gamer3D

Gamer3D

    Human* me = this;

  • GMC Member
  • 1592 posts
  • Version:GM8.1

Posted 05 March 2011 - 11:30 PM

that's an interesting technique. never seen it before. just as you said, it favors the middle a lot =/
i set up a test. the green dots are distributed most evenly.


Yes, the green dots are distributed evenly, but the loop could, in theory, run indefinitely, so it is dangerous.

The mine is based on the idea that we can distribute along the y axis evenly quite easily.

EDIT:
A little messing around found an acceptable (looks even, but is not truely even) function for the distribution:
x = arcsin(random(1.946) - 0.973) * 0.7474448;
y = (random(2) - 1) * sqrt(1 - x * x);
Again, this is for a unit circle at the origin. Add and multiply to move and resize it.

Edited by Gamer3D, 07 March 2011 - 10:18 PM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users