Forum

> > CS2D > Scripts > Coordinates at X degrees rotation
Forums overviewCS2D overview Scripts overviewLog in to reply

English Coordinates at X degrees rotation

13 replies
To the start Previous 1 Next To the start

old Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
IMG:https://i1032.photobucket.com/albums/a409/wingbull/howto_zpsf48b089d.png


Explanation:

I know the player's coordinates. Let's call them P, with coordinates {0,0}. I also know what coordinates two points (Q and R) have at a rotation of 0 degrees; {10,0} and {-10,0}. The line between Q and R centers in the middle (at P), at every rotation.

How do I get the position of Q and R at X degrees rotation?

-

Would be nice to have a function for it, but pseudocode would do prolly.

old Re: Coordinates at X degrees rotation

Infinite Rain
Reviewer Off Offline

Quote
1
2
3
4
5
6
7
function GetPos(CenterPos, UpOffSet, LeftOffSet, RightOffSet, Dir)
     local x, y = CenterPos[1], CenterPos[2]
     local UpPos = {x + math.sin(math.rad(Dir)) * UpOffSet, y - math.cos(math.rad(Dir)) * UpOffSet}
     local LeftPos = {x + math.sin(math.rad(Dir-90)) * LeftOffSet, y - math.cos(math.rad(Dir-90)) * LeftOffSet}
     local RightPos = {x + math.sin(math.rad(Dir+90)) * RightOffSet, y - math.cos(math.rad(Dir+90)) * RightOffSet}
     return UpPos, LeftPos, RightPos
end

So, arguments:
CenterPos - The Center position (G)
UpOffSet - Off set to UP (from center position), (P)
LeftOffSet - Off set to LEFT (from center position) (R)
RightOffSet - Off set to RIGHT (from center position) (Q)

Return like this: local up, left, right = GetPos(blabla)
left up and right variables will be tables

Edit: Whoops, found some error, fixed.

BTW:
Example >


Working perfectly for me.
edited 2×, last 17.02.13 01:29:00 pm

old Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
Now I have the problem, that I don't know what the position of those Q and R points is, and how many there are.

This means they could be on a line, without 0,0 being the middle of it.

old Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Quote
All you have to do is to add (and deduct) half pi to the angle you want:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function points(P,A,r)
	--P = a point
	--A = an angle in radians
	--r = radius (absolute distance from P to Q and R)
	local Q = {}
	local R = {}

	Q.x = P.x+math.cos(A-math.pi/2)*r
	Q.y = P.y+math.sin(A-math.pi/2)*r

	R.x = P.x+math.cos(A+math.pi/2)*r
	R.y = P.y+math.sin(A+math.pi/2)*r

	return Q,R
end

A slight optimization can be done to this code. Since we know that the distance between both angles is pi, the relative coordinates to P for both Q and R are the opposite:
1
2
3
4
5
6
7
8
9
10
11
12
function points(P,A,r)
	Q = {}
	R = {}

	Q.x = P.x+math.cos(A-math.pi/2)*r
	Q.y = P.y+math.sin(A-math.pi/2)*r

	R.x = P.x*2-Q.x
	R.y = P.y*2-Q.y

	return Q, R
end
This saves you from calculating cos and sin again, which are considered to be expensive computing operations.

Edit:
If the number of points you have isn't always 2 but the point P is still at the center of them:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function points(P,A,r,p)
	--P = a point
	--A = an angle in radians
	--r = radius (absolute distance from P to Q and R)
	--p = number of points
	local t = {}
	local ad = math.pi*2/p --this is the distance in radians that separates each point

	for i=1, p do
		t[i] = {}
		t[i].x = P.x + math.cos(A-(math.pi/2)+ad*(i-1)) * r
		t[i].y = P.y + math.sin(A-(math.pi/2)+ad*(i-1)) * r
	end
	return t
end
Sadly, I can't think of any optimizations for this (In fact, I don't even know if it works)
edited 2×, last 17.02.13 03:00:53 pm

old Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
Okay I guess I've completely fucked up stuff then; here's what the code looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function points(P,A,r)
	--P = a point
	--A = an angle in radians
	--r = radius (absolute distance from P to Q and R)
	Q = {}
	Q[1] = P[1]+math.cos(A-math.pi/2)*r
	Q[2] = P[2]+math.sin(A-math.pi/2)*r
	return Q
end

function _mechaAttack(id, mk)
	local x, y = player(id, 'x'), player(id, 'y')
	local type = mecha.type[id][1][mk]
	local xoffset = mecha.turrets[type][1]
	local yoffset = mecha.turrets[type][2]
	local weapon = mecha.turrets[type][3]
	local dist = mecha.turrets[type][4]
	local b = math.sqrt(xoffset^2 + yoffset^2)
	local rot = player(id, 'rot')
	if player(id, 'rot') < 0 then
		rot = player(id, 'rot') + 360
	end
	local a = points({x, y}, rot, b)
	parse('spawnprojectile '..id..' '..weapon..' '..a[1]..' '..a[2]..' '..dist..' '..player(id, 'rot'))
end

old Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Quote
{x,y} should be {x=x, y=y}
rot stores the rotation you got from CS2D, this won't work correctly as CS2D uses a bizarre angle notation expressed in degrees where 0° is pointing up and the values decrease when rotating counter-clockwise and increase clockwise so that -180° and 180° are pointing down.

points() expect degrees expressed in radians where 0° is pointing to the right and the values increase counter-clockwise and decrease clockwise so that -PI and PI are pointing to the left.

I think it's up to you to figure out a function that converts between both notations because I forgot how to.

old Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
user Infinite Rain has written
Just tell us what you want to do with this function, maybe we'll be more helpful that way.


The script should add a mecha, and you can change what kind of projectiles it shoots and where they shoot from. The mecha should rotate with your player, so your rocket turret things should shoot from different coordinates every time.

old Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
@user Flacko

Currently, the rocket turrets have their own rotation axis or so it seems. If the player rotates, the rocket turret positions (green dots in the OP image) should rotate with him.

IMG:https://i1032.photobucket.com/albums/a409/wingbull/aaaa_zpsc07c051a.png


O(x) is the Offset x from the player, if the player's facing upwards, in pixels
O(y) is the Offset y "" "" ""

A is the angle (difference from facing upwards)

r is the radius

P(black) is the circle's center point
P(pink) is where the turret {O(x), O(y)} would go

-

Currently, the center point is the player. If you add the X and Y offset to that, it creates a seperate circle with the same radius etc, but it doesn't get rotated with the player. In the image, Black is how it currently is, Pink is how it should be.

This means that the other pink point to the left should still be able to exist. It shouldn't be like "add 90 degrees to the normal angle", but "add/take X degrees to/from the normal angle, taking the triangle formed by P(black)-P(pink)-r in mind".

old Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Quote
1
2
3
4
5
6
7
8
9
10
11
function calc_point(P, O, A)
	--P = player x, player y in pixels
	--O = offset x, offset y in pixels
	--A = player angle in radians
	local a = math.atan2(O.y, O.x) -- it would be better to cache this value somewhere
	local d = math.sqrt(O.y*O.y+O.x*O.x)
	return {
		x = math.cos(A+a)*d,
		y = math.sin(A+a)*d
	}
end
First you need to calculate the arc tangent:

The tangent of an angle is defined as Opposite / Adjacent
In our case we can think of it as Y / X

Therefore, the arc tangent, (the inverse operation) will return that same angle if we pass the correct value of Y / X.

If I recall correctly, atan2(Y,X) is just a shortcut for atan(Y/X)

O(x) and O(y) form a right triangle so this is applicable here too: atan2(O(y),O(x)) = the angle from P black to P pink

Then you just have to calculate the absolute distance from P black to P pink using the Pythagorean theorem to multiply the sine and cosine values you got from the angle.

old Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Quote
user Flacko has written
1
2
3
4
5
6
7
8
function calc_point(P, O, A)
	local a = math.atan2(O.y, O.x) -- it would be better to cache this value somewhere
	local d = math.sqrt(O.y*O.y+O.x*O.x)
	return {
		x = math.cos(A+a)*d,
		y = math.sin(A+a)*d
	}
end


The player position doesn't come back in the script. It currently only works around the point (0,0).
To the start Previous 1 Next To the start
Log in to reply Scripts overviewCS2D overviewForums overview