Home   Help Search Login Register  

Author Topic: Geometrie (Geometry or Geometrics?): Distance and Angle to Objects  (Read 1829 times)

0 Members and 3 Guests are viewing this topic.

csde-PiLLe

  • Guest
Hey everyone,

I am trying to create an airstrike script. To have it hit EXACTLY where I want it to hit, I decided to solve this using a "Barrier Trigger" shortly before the target.

The script is going to be started by a trigger, the player will not have control over what is hit. As soon as the player enters a "Lookout Position", the script will start.

First, it will pause for ~30, then the circling plane should break its cycle and doMove to a position behind the target. As the distance between Target and Plane is 5600 Meters (at closest), it should always hit the "barrier trigger", which is 100 Meters deep and 1000 Meters wide.

The script will wait for a condition raised by the trigger (doBombing) and then start creating bomblets in a height of 200.

(btw: is it meters or feet, as I always refer to it as "meters")

Now for the tricky part:

As of now, the bomblets will be created in rows, to allow for a slight delay (thus lowering cpu usage a bit). Currently, the northmost row will be created first, then, delayed by 0.2, the next row is created.

I have included a random error and realistic dud probability (I somewhere read that about 17% of all (US-)bomblets are duds).

I want to create the rows directionally, so if the plane comes in more from the northnortheast, the whole bomblet pattern should be rotated to match the incoming planes direction.

I really do not know which direction the plane will come in from, and as I do not know how to insert waypoints or make the plane "Abort Cycling", I cannot insert a waypoint preparing for an (almost) identical entry angle.

As the target lies in a valley, I also plan to include a few security triggers/scripts, which I find equally challenging. If the plane is about to crash, it should pull up to get over the surrounding cliffs.

MY QUESTION, after I have explained all this:

How to I calculate the angles and changes in x/y positions needed to make the cluster look as if it was dropped by the plane and how to I calculate the changes (setvelocity, setdirection) for the plane to ensure it gets over the cliffs safely?

I have included an earlier version of the script in order to allow you to understand what I am talking about ;)

Code: [Select]
~30

;Number of Rows to drop -1;
_rows=20;

;row counter
_count=0;

;_width not used yet. Will be used someday to influnce the number of lines dropped.
_width=5;

;_wdisplace is Distance between lines
_wdisplace = 20;

;_hdisplace is Distance between rows

_hdisplace = 15;

;Randow error (OFP-Distances). Affects only row displacement.
_randerr = 5;

;Dud Probability per bomblet.
_dudprob = 0.02;

;Get Position of Carpet Start Center.
_xloc=getmarkerpos "bpoint" select 0;
_yloc=getmarkerpos "bpoint" select 1;

;Drop Height. Be careful not to kill your "attacker";
_zloc=50;

;Variables
_dudornot=0;
_displaced=0;
_sign=0;


#createbomblets

;Auto Proceed To Next Row
_xloc=_xloc+_hdisplace;

;Begin creating one row of bomblets

_displaced = random _randerr;
_sign = random 1;
?_sign>0.5:_displaced=(_displaced * -1);
_dudornot = random 1;
?_dudornot>_dudprob:_bomblet5 = "HEAT120" camcreate [_xloc, (_yloc+((_wdisplace+_displaced)*2)), _zloc];

_displaced = random _randerr;
_sign = random 1;
?_sign>0.5:_displaced=(_displaced * -1);
_dudornot = random 1;
?_dudornot>_dudprob:_bomblet1 = "HEAT120" camcreate [_xloc, (_yloc+(_wdisplace+_displaced)), _zloc];

_displaced = random _randerr;
_sign = random 1;
?_sign>0.5:_displaced=(_displaced * -1);
_dudornot = random 1;
?_dudornot>_dudprob:_bomblet2 = "HEAT120" camcreate [_xloc, (_yloc+_displaced), _zloc];

_displaced = random _randerr;
_sign = random 1;
?_sign>0.5:_displaced=(_displaced * -1);
_dudornot = random 1;
?_dudornot>_dudprob:_bomblet3 = "HEAT120" camcreate [_xloc, (_yloc-(_wdisplace+_displaced)), _zloc];

_displaced = random _randerr;
_sign = random 1;
?_sign>0.5:_displaced=(_displaced * -1);
_dudornot = random 1;
?_dudornot>_dudprob:_bomblet4 = "HEAT120" camcreate [_xloc, (_yloc-((_wdisplace+_displaced)*2)), _zloc];

;Wait 0.2 seconds before generating next row.
~0.02
_count=_count+1;
?_count>_rows:goto "end";
goto "createbomblets";
#end;

« Last Edit: 16 Apr 2004, 04:33:33 by csde-PiLLe »

Offline myke13021

  • Contributing Member
  • **
  • Myke
there are a few Airstrike scripts in the ED depot...look here:

http://www.ofpec.com/editors/browse.php?browsewhat=2&category=2_4

csde-PiLLe

  • Guest
Thanks for your answer myke.

However, I want to do the scripting myself. I just need help in calculation, as .. umm.. I was sick when we learned that in school....

;)

It took me about 30 mins to write this, and it is my first OFP-Script. From that you will derive that I have a programming background, and I sure do ;)

I am an application developer, mostly C/C++ and JAVA, so the hardest part was to read everything up in the official command reference and use some "object creation" feedback from OFPEC ;)

I am quite sure I will need some experience in calculating the effects of rotation (as to position and angle) in the near future, so I decided to try this in OFP - where you can literally SEE what your code does ;)

And if I used a third-party-script, I might not be able to reproduce that ;)

Thanks anyway
PiLLe

Offline myke13021

  • Contributing Member
  • **
  • Myke
well, basically i meant you can LOOK at these scripts and see how they did it...maybe it gives you some ideas.

I do this also...when i'm about to make a script but i don't know how exactly i should do it...i look for a third party script which does something similar. So i can see how they did and i get an idea how i could do it.

But i agree with you...when you do it on your own, at the end you have something where you can be 100% proud of it.

I'm sorry i can't help you more directly...but maybe the getdir command with some maths could do the job....and i guess you're way better in math than me  ;D

csde-PiLLe

  • Guest
I am not, thats why I need help here ;)

The last time I ever used Sinus, Cosinus, Arc and stuff was in school, and I did forget most of it.

I remember recalling the cosinus of 90° is 0 and sinus is 1, so cosinus is the length of the horizontal line from the 0° radius to the point where the radius i am calculating for touches the circle.

Sinus accordingly has to be the vertical line.

Now how do I convert this knowledge into something useful?

I have tried to solve it...

Its quite easy to have things created in a grid. That way you can simply add 1 to the x coordinate and have the next object created 1 meter away. But if the degree is rotated by 45 degrees, how do I calculate the positions for the next objects?

In my script, I use row and line displacement. And as hard as I tried, in the end the bomblets always fall in a perfectly aligned unrotated square :( just closer to each other.

Actually, this script is not the only thing I want to do. I have created a paratrooper script for use with the Big Antonov. Right now, the Antonov is flying in a straight line from west to east. When it passes a trigger, I have the group leaders eject their groupmembers one by one, 2 groups at a time. That works. I simply remove them from the vehicle, place them shortly behind the plane (like 15 meters from the plane pos, 4 meters below the plane position). Then I assign the planes velocity (-5) and have the game calculate their fall until they have dropped by 15 meters (the plane is flying in 200).

At that point, their chutes are opened and the game handles the rest.

Using decent delay, this pretty much looks like a real paratrooper insertion. But, as with my bomblets, the script wont work if the plane is not flying within 2° or 3° from straight east, as my calculation will spawn them in the tail section or something else. So, as with my bomblet script, I need help on how to calculate the correct position.

Cheers
PiLLe

Tom Norman

  • Guest
Alright, no dramas, I can help you with this.  I have written this system into it's own script because I use it so often, I'll attach it to this message in a minute, but first I'll try to explain it.  Also, I should tell you that if you just set your parachutist's positions to outside the plane, they will not respond correctly when you give them a movement order.  You should first either 'eject' them, or better still give them the 'getout' command.  If you eject them, it tends to have the unsightly side effect of spawning an empty parachute

The system you will need to use to derive your new X,Y,Z position (the point at which you want to move yourparachutists or bomblets) is as follows:  You will first need a start point, in your example this will be the X,Y,Z position of your plane.  You will also need to specify the angle and distance from the plane's grid to the point in space you want to spawn your bomblets or drop your parachutists.  In the example of the parachutists, to drop them right out of the back door, the angle would be the plane's direction minus 180, and the distance would probably be about half the length of the plane.  Now, to calculate the grid of your intended spawn point from the plane's X,Y,Z position you need to take X and add it to the sin of the angle specified, multiplied by the distance you set (X + (Sin Angle * Distance)).  I hope I'm not losing you.  This newly calculated figure is the X element for the spawn point grid.  I know this confused the hell out of me when I was relearning it all for Flashpoint scripting, but you strike me as an intelligent chap so I'll crack on and see where it leaves us.  To derive the new Y element for the spawn point's grid, we need to do the same again, except using Cosine this time.  So, take the plane's grid Y value and add it to the cosine of your specified angle multiplied by the desired distance (it goes without saying, the distance and angle must be common to both the X and Y calculations...it's best just to use a local variable so you can chop and change at will).  Now you have the X and Y value's for your spawn point.  This point is 2 dimentional at the moment because it has no Z value (altitude), but it is mathematically perfect.  It is the point on the horizontal plane exactly at the specified distance and angle from the plane's grid.  Now you just need to fill in the Z value, which obviously requires no maths at all.  You can set it to a constant altitude if you like, or if you want to relate it to your example, you can just set it to the plane's altitude (plus or minus).

Below is a script I wrote a while back for this very purpose.  It doesn't take into account the plane's direction though, it's not for you to just cut out and fit into your script, because I know you want to do it yourself.  I'm just trying to give you, in script form, exactly what I've already tried to explain.

Code: [Select]
;This script finds the grid (X,Y,Z) of a position, given it's angle and distance from any object.
;
;_Unit - The initial object from which the new position is to be found.
;_Ang - The direction (degrees) from from the initial object to the intended new position.
;_Dist - The distance from from the initial object to the intended new position.
;
;Final value produced:
;_TgtPos - The grid (X,Y,Z) of the new position.

_Unit = _this select 0
_Ang = _this select 1
_Dist = _this select 2

_TgtPos = [((getPos _Unit select 0) + ((sin _Ang) * _Dist)),((getPos _Unit select 1) + ((cos _Ang) * _Dist)),(getPos _Unit select 2)]

Exit

Offline Raptorsaurus

  • Editors Depot Staff
  • *****
Sound like you need to have a trigonometry review.  There are some trig tutorials in the editor depot.  Also, you can do some web surfing to find some on-line trig lessons.  Also, you can get some used math books fairly inexpensively and go through those.   The basic trig formulas to remember are:

sin (angle) = opposite side / hyp
cos (angle) = adjacent side / hyp
tan (angle = opposite side / adjacent side

But why do you not just camcreat the bomblets a liitle under the planes current position as it flys:

Code: [Select]
_bomblet = "heat73" createvehicle [getPos _plane select 0, getPos _plane select 1,(getPos _plane select 2) - 5]
As for keeping the plane from hitting the ground do this in the first waypoint "on activation field":

_plane flyinheight 100

The AI are fairly good at not hitting the ground as long as the flyinheight is above 50 m (units are all in meters in this game, except the "speed" command returns speed in km/h.  The setvelocity and velocity commands are in m/s, so take care to keep this in mind.

Hope this helps.

Tom Norman

  • Guest
Just to enhance on Raptorsaurus' comments, flyinheight can be specified in a unit's init field, thus negating the need for an initial waypoint if you have no purpose for one.  Just enter 'this flyinheight 100' in the unit's init field.  Also, the units in the game are not metres or feet.  They're something else.  I think I worked out a while back that 100 metre's on the game map is roughly equal to 131 game units.  So 1 metre is equal to 1.31 game unit's.

csde-PiLLe

  • Guest
Thanks Tom and Raptorsaurus,

it works pretty well. At least when I do it on paper ;)

I used some mm-paper to layout a grid and then rotated it. I then dotted the bomblet layout on the rotated grid and tried to determine angles and distances in normal orientation, just to counter-check what you told me. Seems like you two did your homework, as opposed to me ;)

That is the problem with stuff you learn but don't have to use: You forget most of it. When I received my motorboat & sailing license, I still knew most of it. But in those 8 years I forgot most of it. I could have figured this out myself somehow, but having someone explain it to you makes things a LOT easier.

Since when on a river or small lake, you dont need up to the stars very often ;)

Thanks a lot.

Cheers
PiLLe

Tom Norman

  • Guest
You're welcome.  I remember when I was in school and I thought I'd never use this stuff, so I didn't make any effort to retain it after my exams.  Now I work on an artillery command post, calculating firing data for the guns.  Ironic isn't it.  I also have to remember all that gibberish about the electromagnetic spectrum from physics.  Radio waves are part of the electrmagnetic spectrum and therefore travel at the speed of light, which is a value necessary in the calculation of wavelength and frequency.  Next thing you know, I'll be expected to remember all that stuff about poetry I learnt in English...but it's alright, me speak the perfect Queen's England already, not like what some people do.   ;)

Offline Sui

  • Former Staff
  • ****
    • OFPEC
*the bar doors slam open and Sui throws his 2c down on the table*

Right... it really depends all on how far you want to take the realism with the dispersion pattern...

OFP scripting is now powerful enough for you to be able to set the velocity and point of origin of each of your bomblets to create pretty much any dispersion you're after.

If I recall toadlife wrote a good trig tute that's floating around in the editor's depot somewhere. Failing that I can probably offer some quick and dirty advice.

If I get time later I'll pull out photoshop and come up with some quick 'graphical' tutes...

As well as sin/cos I also recommend the atan2 function for getting relative bearings from objects.
That might be useful for calculating the velocity of the bomblets from their point of origin. This is assuming you want to assign them a velocity more complex than just using the velocity of the bomber... ;)

Tom Norman

  • Guest
Ermm...Sui, it's alright mate, I've already covered it.   ???

Tom Norman

  • Guest
Oh, hang on, cancel my last.  You're talking about using tangent to find an angle too aren't you?  Here's a script snippit to take a look at if you want to do that:

Code: [Select]
;This script produces the direction in degrees of one object from another.
;
;_Unit - The initial object from which the direction to target is calculated.
;_Tgt - The target object itself, the direction to this object from the starting object is to be found.
;
;Final value produced:
;_Ang - The direction of the target object (_Tgt) from the active object (_Unit).

_Unit = _this select 0
_Tgt = _this select 1

? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) > 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1)))
? (((GetPos _Tgt select 1) - (GetPos _Unit select 1)) < 0): _Ang = ATan (((GetPos _Tgt select 0) - (GetPos _Unit select 0)) / ((GetPos _Tgt select 1) - (GetPos _Unit select 1))) + 180
? _Ang < 0: _Ang = _Ang + 360

Exit

csde-PiLLe

  • Guest
Well, Sui, as Tom wrote, he already gave me the necessary input to drop my carpet in the right position.

I simply drop the carpet , centered on my target, rotated in the direction of the plane.

The whole concept of my mission stands or falls with the success of the bombing, e.g. the plant being destroyed. As it is a night mission, noone will see the bomblets fall, so I can simply create them at an altitude and let them fall.

Additionally, the plant has to be destroyed... so I just spawn some additional shells in 3 predefined positions, which will take it out even if the "carpet" bomblets fail to do so.

I dont need to give them any velocity, just make sure that the plane passes shortly before everything blows up, so it will seem as if the plane dropped the carpet.

As for the paratroopers, they receive the velocity of the plane minus 25 % (body drag) and then open their chutes after a sec or so.

I then let the game handle the falling. All I need to do is to make sure that they are put into the right position (behind the plane's ramp) and low enough not to get caught by the planes tail.

The only thing I am concerned about is the tendency of ofp-chutes to land in the water. Therefore I am currently considering "moving" my scenario to a new island. Or i just have to drop fewer chutes faster ;)

As I mentioned somewhere before, that is what originally got me into OFP-Scripting. It is a great tool for me, where I can see what my code does, without having to write the display part in the first place ;)

And it is great fun ;)

Cheers
PiLLe

Offline Sui

  • Former Staff
  • ****
    • OFPEC
Yeah... sort of. I'm talking about stuff like this:

(getpos object select 0) + (sin (getdir object + offset) * distance),(getpos object select 1) + (cos (getdir object - offset) * distance), (getpos object select 2) + height

Which will give you a relative position on an object. This means that the position that code gives you stays relative to the object. If you don't use the getdir and the offset, all you get is a position relative to north, which is no good when the direction of your object is changing ;)

Good for situations where the direction of movement is going to be changing, such as this one.

As for the relative bearing, try this:

(((getpos object1 Select 0) - (getpos object2 Select 0)) ATan2 ((getpos object1 Select 1) - (getpos object2 Select 1)))

No need for variables or more than one line of code ;)

I'll see if I can come up with a graphical way to represent that... it's pretty nasty to try to understand when all I do is dump numbers on people :P

A combination of the two will give you a realistic placement of bomblets (rather than just creating a couple of lines), and realistic, tear shaped dispersal pattern...

[edit] Crossed posts... see the reply now ;)[/edit]

Fair enough mate. If simple is all you need, then by all means keep it that way... :)

I always tend to try to over complicate things... now I feel like going and writing another bloody cluster bomb script. You've gotten me into the mood ;D
« Last Edit: 16 Apr 2004, 12:11:18 by Sui »