Forum

> > CS2D > Scripts > Coordinates at X degrees rotation
ForenübersichtCS2D-Übersicht Scripts-ÜbersichtEinloggen, um zu antworten

Englisch Coordinates at X degrees rotation

13 Antworten
Zum Anfang Vorherige 1 Nächste Zum Anfang

alt Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
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.

alt Re: Coordinates at X degrees rotation

Infinite Rain
Reviewer Off Offline

Zitieren
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.
2× editiert, zuletzt 17.02.13 13:29:00

alt Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
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.

alt Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Zitieren
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)
2× editiert, zuletzt 17.02.13 15:00:53

alt Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
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

alt Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Zitieren
{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.

alt Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
user Infinite Rain hat geschrieben
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.

alt Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
@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".

alt Re: Coordinates at X degrees rotation

Flacko
User Off Offline

Zitieren
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.

alt Re: Coordinates at X degrees rotation

Alistaire
User Off Offline

Zitieren
user Flacko hat geschrieben
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).
Zum Anfang Vorherige 1 Nächste Zum Anfang
Einloggen, um zu antworten Scripts-ÜbersichtCS2D-ÜbersichtForenübersicht