Creating a circle of objects -
[XST]O_x - 21.07.2013
I'm interested on the last couple of months on how is it possible to create a "circle" of objects around a certain point, with a certain radius from the point.
I know it has something to do with the trigonmetric functions, and I know what each one of them does, but I just don't know how to implement it code-wise.
I've seen some filterscript of explosions created around the player, but I can't seem to find it now.
Re: Creating a circle of objects -
Bakr - 21.07.2013
This has everything you need:
http://stackoverflow.com/questions/8...-circumference
Re: Creating a circle of objects -
[XST]O_x - 21.07.2013
Quote:
Originally Posted by Bakr
|
So it will be something like:
pawn Код:
stock CreateCircleAroundPoint(objectid, Float:x, Float:y, Float:z, Float:radius)
{
new Float:x2, Float:y2;
for(new i = 0; i < 360; i++)
{
x2 = x + radius * acos(i);
y2 = y + radius * asin(i);
CreateObject(objectid, x2, y2, z...);
}
return 1;
}
?
Re: Creating a circle of objects -
MP2 - 21.07.2013
Not acos/asin, just floatcos/floatsin. I'm pretty sure sin is for x, but I forget.
Re: Creating a circle of objects -
Bakr - 21.07.2013
That would create a complete circle around the origin (x, y). If you only want a specific amount of objects (like 10) around the origin, you will have to adjust the formula accordingly.
Re: Creating a circle of objects -
[XST]O_x - 21.07.2013
Quote:
Originally Posted by MP2
Not acos/asin, just floatcos/floatsin. I'm pretty sure sin is for x, but I forget.
|
What's the difference? I always wondered.
And why floatsin/floatcos? 'i' is an integer, not a float.
Quote:
Originally Posted by Bakr
That would create a complete circle around the origin (x, y). If you only want a specific amount of objects (like 10) around the origin, you will have to adjust the formula accordingly.
|
Yeah I'll play around with it. Thanks for the help!
Re: Creating a circle of objects -
Antonio144 - 21.07.2013
floatsin returns sine of an angle (which is a float), whereas asin is an inverse function of sine (sine^-1). For example:
floatsin(60, degrees) ~ 0.866,
asin(0.866) ~ 60°.
This creates a specific number or objects equally distributed around a point.
pawn Код:
stock CreateCircleAroundpoint(objectid, Float:x, Float:y, Float:z, Float:radius, OBJECT_NUMBER)
{
new Float:x2, Float:y2, Float:angle = 360/(OBJECT_NUMBER), Float:a = 0.0;
for(new i=0; i<OBJECT_NUMBER; i++)
{
printf("%f",a);
x2 = x + floatcos(a,degrees) * radius;
y2 = y + floatsin(a,degrees) * radius;
a += angle;
CreateObject(objectid, x2, y2, z, 0.0,0.0,0.0);
}
}
Re: Creating a circle of objects -
Pottus - 21.07.2013
Quote:
Originally Posted by Antonio144
floatsin returns sine of an angle (which is a float), whereas asin is an inverse function of sine (sine^-1). For example:
floatsin(60, degrees) ~ 0.866,
asin(0.866) ~ 60°.
This creates a specific number or objects equally distributed around a point.
pawn Код:
stock CreateCircleAroundpoint(objectid, Float:x, Float:y, Float:z, Float:radius, OBJECT_NUMBER) { new Float:x2, Float:y2, Float:angle = 360/(OBJECT_NUMBER), Float:a = 0.0; for(new i=0; i<OBJECT_NUMBER; i++) { printf("%f",a); x2 = x + floatcos(a,degrees) * radius; y2 = y + floatsin(a,degrees) * radius; a += angle; CreateObject(objectid, x2, y2, z, 0.0,0.0,0.0); } }
|
Lets create a shitload of objects without any reference of their object ids that way our function fills all the object slots and crashes clients isn't that clever? Even though the rest of the code looks correct we need to add some stuff here so keep track of what those object ids are.
pawn Код:
#include <a_samp>
#include <zcmd>
// Invalid point group ref
#define INVALID_POINT_GROUP (0xFFFF)
// Max number of objects creatable around player
#define MAX_POINT_OBJECT_GROUPS 20
// Max number of objects creatable
#define MAX_POINT_OBJECTS 500
// Group states
#define INACTIVE_GROUP 0
#define ACTIVE_GROUP 1
// Individual object data (reference to group and objectid)
enum POINTDATA
{
PointObjectID,
PointGroupID
}
// Variables for objects
new PointObjectGroups[MAX_POINT_OBJECT_GROUPS];
// Group reference variable
new PointObject[MAX_POINT_OBJECTS][POINTDATA];
// Initialize objectids to INVALID_OBJECT_ID
public OnFilterScriptInit()
{
for(new i = 0; i < MAX_POINT_OBJECT_GROUPS; i++) { PointObject[i][PointObjectID] = INVALID_OBJECT_ID; }
return 1;
}
// Create the objects around a point
stock CreateCircleAroundpoint(objectid, Float:x, Float:y, Float:z, Float:radius, OBJECT_NUMBER)
{
// Find a valid group
for(new i = 0; i < MAX_POINT_OBJECT_GROUPS; i++)
{
// Group used continue
if(PointObjectGroups[i] == ACTIVE_GROUP) continue;
// Variables
new Float:x2, Float:y2, Float:angle = 360/(OBJECT_NUMBER), Float:a = 0.0, k, count;
// loop through objects
for(new j = 0; j < OBJECT_NUMBER; j++)
{
// Find a free object slot
for(; k < MAX_POINT_OBJECTS; k++)
{
// Found object slot
if(PointObject[k][PointObjectID] == INVALID_OBJECT_ID)
{
// Create object here
x2 = x + floatcos(a,degrees) * radius;
y2 = y + floatsin(a,degrees) * radius;
a += angle;
PointObject[k][PointObjectID] = CreateObject(objectid, x2, y2, z, 0.0,0.0,0.0);
PointObject[k][PointGroupID] = i;
count++;
// No need to keep iterating break out of loop here
break;
}
}
}
// Objects created? Return the groupid
if(count)
{
PointObjectGroups[i] = ACTIVE_GROUP;
return i;
}
// No objects? Return INVALID_POINT_GROUP
else return INVALID_POINT_GROUP;
}
// No groups left
print("Error: Tried to create too many point object groups!");
return INVALID_POINT_GROUP;
}
// Remove a point object group
forward RemovePointObjectGroup(index);
public RemovePointObjectGroup(index)
{
// Make sure the point is valid
if(PointObjectGroups[index] != INVALID_POINT_GROUP)
{
new count;
// Find all objects associated with group
for(new i = 0; i < MAX_POINT_OBJECTS; i++)
{
// Found an object delete
if(PointObject[i][PointGroupID] == index)
{
count++;
DestroyObject(PointObject[i][PointObjectID]);
PointObject[i][PointObjectID] = INVALID_OBJECT_ID;
PointObject[i][PointGroupID] = INACTIVE_GROUP;
}
}
// Group is now inactive return the number of objects removed
PointObjectGroups[index] = INVALID_POINT_GROUP;
return count;
}
// Group was invalid
print("Error: Tried to delete an invalid group!");
return INVALID_POINT_GROUP;
}
// Tests the system
CMD:testcmd(playerid, arg[])
{
new Float:x, Float:y, Float:z;
GetPlayerPos(playerid, x, y, z);
new GID = CreateCircleAroundpoint(954, x, y, z, 2.0, 16);
if(GID != INVALID_POINT_GROUP) SetTimerEx("RemovePointObjectGroup", 20000, false, "i", GID);
return 1;
}
Re: Creating a circle of objects -
[XST]O_x - 22.07.2013
Quote:
Originally Posted by [uL]Pottus
Lets create a shitload of objects without any reference of their object ids that way our function fills all the object slots and crashes clients isn't that clever? Even though the rest of the code looks correct we need to add some stuff here so keep track of what those object ids are.
pawn Код:
#include <a_samp> #include <zcmd>
// Invalid point group ref #define INVALID_POINT_GROUP (0xFFFF)
// Max number of objects creatable around player #define MAX_POINT_OBJECT_GROUPS 20
// Max number of objects creatable #define MAX_POINT_OBJECTS 500
// Group states #define INACTIVE_GROUP 0 #define ACTIVE_GROUP 1
// Individual object data (reference to group and objectid) enum POINTDATA { PointObjectID, PointGroupID }
// Variables for objects new PointObjectGroups[MAX_POINT_OBJECT_GROUPS];
// Group reference variable new PointObject[MAX_POINT_OBJECTS][POINTDATA];
// Initialize objectids to INVALID_OBJECT_ID public OnFilterScriptInit() { for(new i = 0; i < MAX_POINT_OBJECT_GROUPS; i++) { PointObject[i][PointObjectID] = INVALID_OBJECT_ID; } return 1; }
// Create the objects around a point stock CreateCircleAroundpoint(objectid, Float:x, Float:y, Float:z, Float:radius, OBJECT_NUMBER) { // Find a valid group for(new i = 0; i < MAX_POINT_OBJECT_GROUPS; i++) { // Group used continue if(PointObjectGroups[i] == ACTIVE_GROUP) continue; // Variables new Float:x2, Float:y2, Float:angle = 360/(OBJECT_NUMBER), Float:a = 0.0, k, count;
// loop through objects for(new j = 0; j < OBJECT_NUMBER; j++) { // Find a free object slot for(; k < MAX_POINT_OBJECTS; k++) { // Found object slot if(PointObject[k][PointObjectID] == INVALID_OBJECT_ID) { // Create object here x2 = x + floatcos(a,degrees) * radius; y2 = y + floatsin(a,degrees) * radius; a += angle; PointObject[k][PointObjectID] = CreateObject(objectid, x2, y2, z, 0.0,0.0,0.0); PointObject[k][PointGroupID] = i; count++;
// No need to keep iterating break out of loop here break; } } }
// Objects created? Return the groupid if(count) { PointObjectGroups[i] = ACTIVE_GROUP; return i; } // No objects? Return INVALID_POINT_GROUP else return INVALID_POINT_GROUP; } // No groups left print("Error: Tried to create too many point object groups!"); return INVALID_POINT_GROUP; }
// Remove a point object group forward RemovePointObjectGroup(index); public RemovePointObjectGroup(index) { // Make sure the point is valid if(PointObjectGroups[index] != INVALID_POINT_GROUP) { new count;
// Find all objects associated with group for(new i = 0; i < MAX_POINT_OBJECTS; i++) { // Found an object delete if(PointObject[i][PointGroupID] == index) { count++; DestroyObject(PointObject[i][PointObjectID]); PointObject[i][PointObjectID] = INVALID_OBJECT_ID; PointObject[i][PointGroupID] = INACTIVE_GROUP; } } // Group is now inactive return the number of objects removed PointObjectGroups[index] = INVALID_POINT_GROUP; return count; } // Group was invalid print("Error: Tried to delete an invalid group!"); return INVALID_POINT_GROUP; }
// Tests the system CMD:testcmd(playerid, arg[]) { new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); new GID = CreateCircleAroundpoint(954, x, y, z, 2.0, 16); if(GID != INVALID_POINT_GROUP) SetTimerEx("RemovePointObjectGroup", 20000, false, "i", GID); return 1; }
|
Wow... Thanks for the organized code, but can you tell me what's the difference? Why is there a need to keep track on the objects?
Quote:
Originally Posted by Antonio144
floatsin returns sine of an angle (which is a float), whereas asin is an inverse function of sine (sine^-1). For example:
floatsin(60, degrees) ~ 0.866,
asin(0.866) ~ 60°.
This creates a specific number or objects equally distributed around a point.
pawn Код:
stock CreateCircleAroundpoint(objectid, Float:x, Float:y, Float:z, Float:radius, OBJECT_NUMBER) { new Float:x2, Float:y2, Float:angle = 360/(OBJECT_NUMBER), Float:a = 0.0; for(new i=0; i<OBJECT_NUMBER; i++) { printf("%f",a); x2 = x + floatcos(a,degrees) * radius; y2 = y + floatsin(a,degrees) * radius; a += angle; CreateObject(objectid, x2, y2, z, 0.0,0.0,0.0); } }
|
Now it all makes sense. I thought asin and floatsin are the same. I guess asin is arcsine then. Thanks for that

And what is OBJECT_NUMBER? The number of objects to be created?
Re: Creating a circle of objects -
Kar - 22.07.2013
more objects created = more gaps between the circle are filled, depending on the size (width) of the objects ofc