## [INFO/LIB] Detect objects in a cone / Get FPS

The place to discuss scripting and game modifications for X³: Reunion.
Gazz
Posts: 12430
Joined: Fri, 13. Jan 06, 17:39

### [INFO/LIB] Detect objects in a cone / Get FPS

(Get FPS: see below)

For a long time I've been looking for a way to do this but nothing was even remotely fast and effective enough.
- A string of increasingly larger find-bubbles? Not a real cone, lots of work to remove all the duplicates, lots of overlap with the bubbles and thus a lot of CPU time wasted.

- Full blown trigonometry for every object in the sector. Hahaha! Sure pal.

What I finally came up with (for my RADAR sensor cone thingy) takes no more than 1 Find and 1 very short loop as a filter.
There is no range limit and every object is computed exactly once.

This calculation uses 2 points to define the origin and direction of the cone.

In my case it was
1. the ship
2. a point 5000m behind it.
This means the cone extends to the front.

00 ObjArray = Find blah
01 Point = Punkt behind ship 5000
02
03 index = size of array
04 Filter:
05 While index
06 dec index
07 Obj = ObjArray (index)
08 Dist.Ship = distance between Ship and Obj
09 Dist.Point = distance between Point and Obj
10 skip if not Dist.Ship + 4700 > Dist.Point
11 remove element from array ObjArray at index index
12 end

The number 4700 determines the angle of the cone.
The full list is found here.
4860 : 30°
4710 : 45°
4630 : 50°
4380 : 65°
4300 : 80°
3860 : 90°
2520 : 135°

With no more than 3 instructions (lines 5-7) I can determine if the object is in the cone or not.
Compare that to doing full trigonometry in 3D for every single object when the ship itself can be pointing any angle to begin with...

Note that if you reverse the formula you can get the angle value. How far your ship needs to turn to align itself with object X...

. . . same function, other resolution.
At long ranges (005 - 600 km) the cone looks pretty and linear but a close-up on the zero-crossing reveals that it is really a parabola.
Using the "4700" angle, the base of the parabola is 145 m behind the ship.
If you need higher accuracy, displace the 2 points of reference.

You will have to experiment a little with different angles... or find a radically different approach. (tell me if you do =)

Which way you filter the result is completely up to you. You could get ships that are neither in front nor behind your ship within an angle of x°...

I can imagine several uses for navigation or combat scripts but it certainly works for my case. =)
Last edited by Gazz on Tue, 29. Apr 08, 22:42, edited 10 times in total.
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.

Moderator (Script&Mod)
Posts: 13944
Joined: Sun, 20. Nov 05, 23:45
here the correct Link to the Post: (you have linked the German Script Library-Collection, not my Post with the Script itself )
http://forum.egosoft.com/viewtopic.php? ... 02#2059502

and here a short overview over the Input/Output Values:
• Input:
• 1: alpha , Var/Number , 'Angle alpha (0-65536)' - Angle Alpha (Number from 0 to 65536)
• 2: beta , Var/Number , 'Angle beta (0-65536)' - Angle Beta (Number from 0 to 65536) (use Alpha & Beta of a Ship to get a position in front or behind of it )
• 3: dis , Var/Number , 'Distance in m' - Like the Text says - the Dinstance from the RefPos ^^ (when use with Ships: Positive Int -> in front of a Ship, Negative Int -> behind a ship )
• 4: pos0.arr , Value , 'position array' - RefPos as X3-Position-Array (IF null THEN RefPos = 0/0/0) ; Improvement by Gazz: you can use an Object as RefPos. In this case there are no alpha- and beta-angles necessary, they will be taken from the RefObj

Output:
• ARRAY ( X , Y , Z ) X3-Position array

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help

Gazz
Posts: 12430
Joined: Fri, 13. Jan 06, 17:39
Get FPS

A quick and dirty library script to return the current FPS as an integer.

Timing in X3 is highly FPS-dependant so this may have some uses.

This is too small to warrant it's own topic so I'll just dump it here. =)

I created it to find out if the player is on SETA.
If FPS in this sector suddenly drop to 1/10 then I assume that he uses SETA.

This assumption can be false if he has a gfx board with an SWG issue but there are ways to detect if the player is in a fight...

My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.

s9ilent
Posts: 2011
Joined: Wed, 29. Jun 05, 01:45
Thats the same way I do it.
I project a point from the ship, and get the relative ratio's of the distances.

http://members.optuszoo.com.au/whyistha ... cripts.zip

Odd... I thought I put it on the sticky page as well....

Any way my script uses swl.fn.face projects a point x units in front of the ship (It can easily be modified to behind), and then gets the ratio of the distances. And the ratio is exactly equal to 1000*sin Theta, where theta is the angle between where your facing and the object in question

In it's current state the script is designed for a single target check. However I've also seperated the projection script into it's own, so you can easily just use the projection script and then loop this bit (except changing your return value obviously)
033 \$displpacement = \$destination -> get distance to: x=\$new.x y=\$new.y z=\$new.z
034
035 skip if \$dist != 0
036 |return [TRUE]
037
038 \$ratio = \$displpacement * 1000 / \$dist
039
040 skip if not \$ratio <= \$accuracy
041 |\$ret = [TRUE]
042
043 return \$ret