Comparing two floats ranges?

Hello

I'm trying to compare two float ranges and it seems to be a hit and miss. I'm trying to use a object origin and dimensions comparing it to another set for collisions. Something is wrong but I'm not sure what.

Vivienne


Added update code below.
Last edited on
The same problem.


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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

    /// Temporary structure
    struct WorldOjectCollisionMap
    {
        float size_x;
        float size_y;
        float size_z;
        float origin_x;
        float origin_y;
        float origin_z;
        int lod;
    };

    /// Set world limit of objects to test for collision
    int WorldOjectCollisionMapLimit=600;
    WorldOjectCollisionMap CollisionBounds[WorldOjectCollisionMapLimit];

    /// Saved Collision Objects to 0
    int SaveCollisionObjects=0;

    Node * RockNodes = scene_ -> CreateChild("RockNodes");

    ///Loop 1,000 times to find a suitable location (In this case 40)
    for(unsigned int i=0; i<300; i++)
    {


        Spotx=rand()%10000;
        Spotz=rand()%10000;

        randomSpotx=((float)Spotx/100)-50.0f;
        randomSpotz=((float)Spotz/100)-50.0f;

        /// Add a Rock to the seen - Rock Node
        Node * RockNode = RockNodes -> CreateChild("RockNode");

        StaticModel * RockStaticModel = RockNode->CreateComponent<StaticModel>();

        unsigned int pick = Random(1);

        /// Pick a random rock
        pick+=1;

        /// Select rock type 1
        if(pick==1)
        {
            RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/BoxTree.mdl"));
            //RockStaticModel->ApplyMaterialList("Resources/Models/Rock1.txt");

        }

        /// Select rock type 2
        if(pick==2)
        {
            RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/BoxTree.mdl"));
            //  RockStaticModel->ApplyMaterialList("Resources/Models/Rock2.txt");

        }


        /// Create Nodes and COmponents
        RockStaticModel->SetCastShadows(true);

        BoundingBox  staticmodelbox = RockStaticModel->GetBoundingBox();
        Vector3  staticmodelboxcenter= staticmodelbox.HalfSize();


        /// Select a possible position to place a Rock
        Vector3 selectPosition=Vector3(randomSpotx,terrain->GetHeight(Vector3(randomSpotx,0.0f,randomSpotz))+staticmodelboxcenter.y_,randomSpotz);

        bool collision=false;

        if(SaveCollisionObjects>0)
        {
            cout << SaveCollisionObjects;
            cout << "\r\n";

            for(unsigned int idx=0; idx<SaveCollisionObjects; idx++)
            {

                collision=false;

                cout << "x check - "<< randomSpotx-staticmodelboxcenter.z_;
                cout << "<= "<< CollisionBounds[idx].origin_x+CollisionBounds[idx].size_x;
                cout << "&&"<< CollisionBounds[idx].origin_x-CollisionBounds[idx].size_x;
                cout << ">="<< randomSpotx+staticmodelboxcenter.x_;
                cout << "\r\n";

                cout << "z check - "<< randomSpotx-staticmodelboxcenter.z_;
                cout << "<= "<< CollisionBounds[idx].origin_z+CollisionBounds[idx].size_z;
                cout << "&&"<< CollisionBounds[idx].origin_z-CollisionBounds[idx].size_z;
                cout << ">="<< randomSpotz+staticmodelboxcenter.z_;
                cout << "\r\n";

                /// Check x boundary for overlapping
                if
                (
                    ((randomSpotx-staticmodelboxcenter.x_)<=(CollisionBounds[idx].origin_x+CollisionBounds[idx].size_x))&&
                    ((CollisionBounds[idx].origin_x-CollisionBounds[idx].size_x)>=(randomSpotx+staticmodelboxcenter.x_)))
                {
                    /// Set collision true
                    collision=true;
                    break;
                }

                /// Check z boundary for overlapping
                if
                (
                    ((randomSpotz-staticmodelboxcenter.z_)<=(CollisionBounds[idx].origin_z+CollisionBounds[idx].size_z))&&
                    ((CollisionBounds[idx].origin_z-CollisionBounds[idx].size_z)>=(randomSpotz+staticmodelboxcenter.z_)))
                {

                    /// Set collision true
                    collision=true;
                    break;
                }
            }
        }


        /// Test collision
        if(collision==false)
        {

            /// Save coordinates
            CollisionBounds[SaveCollisionObjects].size_x=staticmodelboxcenter.x_;
            CollisionBounds[SaveCollisionObjects].size_y=staticmodelboxcenter.y_;
            CollisionBounds[SaveCollisionObjects].size_z=staticmodelboxcenter.z_;
            CollisionBounds[SaveCollisionObjects].origin_x=randomSpotz;
            CollisionBounds[SaveCollisionObjects].origin_y=terrain->GetHeight(Vector3(randomSpotx,0.0f,randomSpotz))+staticmodelboxcenter.y_;
            CollisionBounds[SaveCollisionObjects].origin_z=randomSpotz;
            CollisionBounds[SaveCollisionObjects].lod=0;

            cout << "Save\r\n";
            /// Save object
            SaveCollisionObjects++;

            /// Set Rock position
            RockNode->SetPosition(selectPosition);
            //RockNode->SetRotation(Quaternion(360,Vector3(0.0f,1.0f,0.0f)));

        }
        else
        {
            cout << "Collision\r\n";

            /// Erase the node
            RockNode->RemoveAllComponents();
            RockNode->Remove();
        }

    }
Last edited on
File output

[code]
[Wed Dec 24 19:49:32 2014] INFO: Opened log file /home/vivienne/.local/share/urho3d/logs/ExistenceClient.log
[Wed Dec 24 19:49:32 2014] INFO: Created 3 worker threads
[Wed Dec 24 19:49:32 2014] INFO: Added resource path /media/home2/vivienne/Existence/Bin/CoreData/
[Wed Dec 24 19:49:32 2014] INFO: Added resource path /media/home2/vivienne/Existence/Bin/Data/
[Wed Dec 24 19:49:33 2014] INFO: Set screen mode 1440x900 fullscreen
[Wed Dec 24 19:49:33 2014] INFO: Initialized input
[Wed Dec 24 19:49:33 2014] INFO: Initialized user interface
[Wed Dec 24 19:49:33 2014] INFO: Initialized renderer
[Wed Dec 24 19:49:33 2014] INFO: Set audio mode 44100 Hz stereo interpolated
[Wed Dec 24 19:49:33 2014] INFO: Added resource path /media/home2/vivienne/Existence/Bin/Resources/
[Wed Dec 24 19:49:35 2014] INFO: Loading scene from /media/home2/vivienne/Existence/Bin/Resources/Scenes/charactercreationroom1.xml
[Wed Dec 24 19:49:35 2014] WARNING: Forcing top alignment because parent element has vertical layout
Save
1
x check - 30<= 26.65&&19.15>=37.5
z check - 30<= 26.65&&19.15>=-30.65
Collision
1
x check - -36.81<= 26.65&&19.15>=-29.31
z check - -36.81<= 26.65&&19.15>=-20.71
Collision
1
x check - -53.43<= 26.65&&19.15>=-45.93
z check - -53.43<= 26.65&&19.15>=33.18
Collision
1
x check - 22.75<= 26.65&&19.15>=30.25
z check - 22.75<= 26.65&&19.15>=-34.54
Collision
1
x check - 21.46<= 26.65&&19.15>=28.96
z check - 21.46<= 26.65&&19.15>=32.84
Save
2
x check - -2.84<= 26.65&&19.15>=4.66
z check - -2.84<= 26.65&&19.15>=51.05
Collision
2
x check - 14.34<= 26.65&&19.15>=21.84
z check - 14.34<= 26.65&&19.15>=25.9
x check - 14.34<= 32.84&&25.34>=21.84
z check - 14.34<= 32.84&&25.34>=25.9
Collision
2
x check - -30.63<= 26.65&&19.15>=-23.13
z check - -30.63<= 26.65&&19.15>=-44.6
Collision
2
x check - 30.4<= 26.65&&19.15>=37.9
z check - 30.4<= 26.65&&19.15>=35.94
x check - 30.4<= 32.84&&25.34>=37.9
z check - 30.4<= 32.84&&25.34>=35.94
Save
3
x check - -36.95<= 26.65&&19.15>=-29.45
z check - -36.95<= 26.65&&19.15>=-0.23
Collision
3
x check - 17.79<= 26.65&&19.15>=25.29
z check - 17.79<= 26.65&&19.15>=-30.96
Collision
3
x check - -36.09<= 26.65&&19.15>=-28.59
z check - -36.09<= 26.65&&19.15>=32.03
Collision
3
x check - 31.14<= 26.65&&19.15>=38.64
z check - 31.14<= 26.65&&19.15>=-33.9
Collision
3
x check - 36.12<= 26.65&&19.15>=43.62
z check - 36.12<= 26.65&&19.15>=36.01
x check - 36.12<= 32.84&&25.34>=43.62
z check - 36.12<= 32.84&&25.34>=36.01
x check - 36.12<= 35.94&&28.44>=43.62
z check - 36.12<= 35.94&&28.44>=36.01
Save
4
x check - -16.99<= 26.65&&19.15>=-9.49
z check - -16.99<= 26.65&&19.15>=22.39
Collision
4
x check - -35.07<= 26.65&&19.15>=-27.57
z check - -35.07<= 26.65&&19.15>=37.78
Collision
4
x check - -5.99<= 26.65&&19.15>=1.51
z check - -5.99<= 26.65&&19.15>=52.9
Collision
4
x check - -44.18<= 26.65&&19.15>=-36.68
z check - -44.18<= 26.65&&19.15>=1.83
Collision
4
x check - -11.65<= 26.65&&19.15>=-4.15
z check - -11.65<= 26.65&&19.15>=3.34
Collision
4
x check - 6.05<= 26.65&&19.15>=13.55
z check - 6.05<= 26.65&&19.15>=-28.94
Collision
4
x check - 38.46<= 26.65&&19.15>=45.96
z check - 38.46<= 26.65&&19.15>=-35.54
Collision
4
x check - -39.14<= 26.65&&19.15>=-31.64
z check - -39.14<= 26.65&&19.15>=14.05
Collision
4
x check - 29.11<= 26.65&&19.15>=36.61
z check - 29.11<= 26.65&&19.15>=-44.99
Collision
4
x check - 8.21<= 26.65&&19.15>=15.71
z check - 8.21<= 26.65&&19.15>=20.77
Collision
4
x check - 29.7<= 26.65&&19.15>=37.2
z check - 29.7<= 26.65&&19.15>=32.51
x check - 29.7<= 32.84&&25.34>=37.2
z check - 29.7<= 32.84&&25.34>=32.51
x check - 29.7<= 35.94&&28.44>=37.2
z check - 29.7<= 35.94&&28.44>=32.51
x check - 29.7<= 36.01&&28.51>=37.2
z check - 29.7<= 36.01&&28.51>=32.51
Save
5
x check - 22.81<= 26.65&&19.15>=30.31
z check - 22.81<= 26.65&&19.15>=-27.74
Collision
5
x check - 3.82<= 26.65&&19.15>=11.32
z check - 3.82<= 26.65&&19.15>=47.97
Collision
5
x check - 6.57<= 26.65&&19.15>=14.07
z check - 6.57<= 26.65&&19.15>=-40.26
Collision
5
x check - 16.34<= 26.65&&19.15>=23.84
z check - 16.34<= 26.65&&19.15>=3.94
Collision
5
x check - -1.98<= 26.65&&19.15>=5.52
z check - -1.98<= 26.65&&19.15>=24.13
Collision
5
x check - -34.92<= 26.65&&19.15>=-27.42
z check - -34.92<= 26.65&&19.15>=24.21
Collision
5
x check - 0.66<= 26.65&&19.15>=8.16
z check - 0.66<= 26.65&&19.15>=20.34
Collision
5
x check - -20.62<= 26.65&&19.15>=-13.12
z check - -20.62<= 26.65&&19.15>=17.74
Collision
5
x check - -39.07<= 26.65&&19.15>=-31.57
z check - -39.07<= 26.65&&19.15>=28.98
Collision
5
x check - 23.35<= 26.65&&19.15>=30.85
z check - 23.35<= 26.65&&19.15>=-8.25
Collision
5
x check - 2.32<= 26.65&&19.15>=9.82
z check - 2.32<= 26.65&&19.15>=23.06
Collision
5
x check - -41.52<= 26.65&&19.15>=-34.02
z check - -41.52<= 26.65&&19.15>=24.43
Collision
5
x check - 39.39<= 26.65&&19.15>=46.89
z check - 39.39<= 26.65&&19.15>=12.37
Collision
5
x check - -18.29<= 26.65&&19.15>=-10.79
z check - -18.29<= 26.65&&19.15>=-27.63
Collision
5
x check - -28.11<= 26.65&&19.15>=-20.61
z check - -28.11<= 26.65&&19.15>=-27.33
Collision
5
x check - 7.15<= 26.65&&19.15>=14.65
z check - 7.15<= 26.65&&19.15>=19.47
Collision
5
x check - -52.8<= 26.65&&19.15>=-45.3
z check - -52.8<= 26.65&&19.15>=-27.77
Collision
5
x check - -30.28<= 26.65&&19.15>=-22.78
z check - -30.28<= 26.65&&19.15>=15.02
Collision
5
x check - -29.28<= 26.65&&19.15>=-21.78
z check - -29.28<= 26.65&&19.15>=47.31
Collision
5
x check - -42.29<= 26.65&&19.15>=-34.79
z check - -42.29<= 26.65&&19.15>=29.99
Collision
5
x check - 10.19<= 26.65&&19.15>=17.69
z check - 10.19<= 26.65&&19.15>=47.56
Collision
5
x check - -43.53<= 26.65&&19.15>=-36.03
z check - -43.53<= 26.65&&19.15>=35.63
Collision
5
x check - -29.82<= 26.65&&19.15>=-22.32
z check - -29.82<= 26.65&&19.15>=-2.9
Collision
5
x check - -7.88<= 26.65&&19.15>=-0.380001
z check - -7.88<= 26.65&&19.15>=-44.12
Collision
5
x check - 28.36<= 26.65&&19.15>=35.86
z check - 28.36<= 26.65&&19.15>=40.24
x check - 28.36<= 32.84&&25.34>=35.86
z check - 28.36<= 32.84&&25.34>=40.24
x check - 28.36<= 35.94&&28.44>=35.86
z check - 28.36<= 35.94&&28.44>=40.24
x check - 28.36<= 36.01&&28.51>=35.86
z check - 28.36<= 36.01&&28.51>=40.24
x check - 28.36<= 32.51&&25.01>=35.86
z check - 28.36<= 32.51&&25.01>=40.24
Save
6
x check - -13.62<= 26.65&&19.15>=-6.12
z check - -13.62<= 26.65&&19.15>=-8.07
Collision
6
x check - 2.06<= 26.65&&19.15>=9.56
z check - 2.06<= 26.65&&19.15>=6.11
Collision
6
x check - 18.63<= 26.65&&19.15>=26.13
z check - 18.63<= 26.65&&19.15>=-33.78
Collision
6
x check - -42.77<= 26.65&&19.15>=-35.27
z check - -42.77<= 26.65&&19.15>=-38.4
Collision
6
x check - -22.66<= 26.65&&19.15>=-15.16
z check - -22.66<= 26.65&&19.15>=-46.11
Collision
6
x check - 36.54<= 26.65&&19.15>=44.04
z check - 36.54<= 26.65&&19.15>=45.74
x check - 36.54<= 32.84&&25.34>=44.04
z check - 36.54<= 32.84&&25.34>=45.74
x check - 36.54<= 35.94&&28.44>=44.04
z check - 36.54<= 35.94&&28.44>=45.74
x check - 36.54<= 36.01&&28.51>=44.04
z check - 36.54<= 36.01&&28.51>=45.74
x check - 36.54<= 32.51&&25.01>=44.04
z check - 36.54<= 32.51&&25.01>=45.74
x check - 36.54<= 40.24&&32.74>=44.04
z check - 36.54<= 40.24&&32.74>=45.74
Save
7
x check - -24.36<= 26.65&&19.15>=-16.86
z check - -24.36<= 26.65&&19.15>=44.99
Collision
7
[/CODE]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <utility>
#include <algorithm>

using range = std::pair<float,float> ;

range make_range( float a, float b ) { return { std::min(a,b), std::max(a,b) } ; }

bool intersects( range a, range b )
{
    if( a > b ) std::swap(a,b) ;
    return a.second >= b.first ;
}

int main()
{
    std::cout << std::boolalpha << intersects( make_range(1,2), make_range(3,8) ) << '\n' // false
              << intersects( make_range(1,4), make_range(3,8) ) << '\n' // true
              << intersects( make_range(3,5), make_range(1,4) ) << '\n'  // true
              << intersects( make_range(4.1,5), make_range(4,1) ) << '\n' ;  // false
}

http://coliru.stacked-crooked.com/a/41f2230060808f11
I'm getting this error.

/media/home2/vivienne/Existence/Source/ExistenceApps/ExistenceClient/ExistenceClient.cpp|178|error: expected nested-name-specifier before ‘range’|

I'm using Codeblocks 10.05 and GCC 4.6

1
2
3
4
5
6
7
8
9
vivienne@vivienne-System-Product-Name:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) 
vivienne@vivienne-System-Product-Name:~$ 

The errors are from the C++11 constructs.

GCC 4.6 may support them with the -std=c++11 option.

Otherwise, equivalent code compatible with legacy C++ would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <utility>
#include <algorithm>

// using range = std::pair<float,float> ; // C++11
typedef std::pair<float,float> range ;

// range make_range( float a, float b ) { return { std::min(a,b), std::max(a,b) } ; } // C++11
range make_range( float a, float b ) { return range( std::min(a,b), std::max(a,b) ) ; }

bool intersects( range a, range b )
{
    if( a > b ) std::swap(a,b) ;
    return a.second >= b.first ;
}

int main()
{
    std::cout << std::boolalpha << intersects( make_range(1,2), make_range(3,8) ) << '\n' // false
              << intersects( make_range(1,4), make_range(3,8) ) << '\n' // true
              << intersects( make_range(3,5), make_range(1,4) ) << '\n'  // true
              << intersects( make_range(4.1,5), make_range(4,1) ) << '\n' ;  // false
}

http://coliru.stacked-crooked.com/a/da3e40086376b91b
Thank you. Testing it out replacing the code I made that half worked.
This is using my code plus the modified version. I looped through creating 600 objects.

It seems to be far less then 600 so I don't know if it's the base <floats> or should I change the beginning spot selector to be more precise.

1
2
3
4
5
 Spotx=rand()%10000;
        Spotz=rand()%10000;

        randomSpotx=((float)Spotx/100)-50.0f;
        randomSpotz=((float)Spotz/100)-50.0f;

This is the kind of distribution you would get. At a cursory glance, seems ok.

-24.6  +22.0  - 7.3  +12.4  - 0.5  +21.0  - 2.2  - 9.0  +19.0  +38.4  
+26.4  +22.6  + 9.3  +25.5  +42.1  -49.0  -39.1  +48.6  - 4.7  - 1.8  
+10.4  + 0.0  -35.7  -30.7  - 2.7  -11.1  +45.1  -27.0  -13.7  -10.3  
-34.4  -24.8  +25.3  -28.1  +37.6  +38.3  + 6.4  -14.6  -20.7  +39.0  
+37.3  -44.3  +11.5  - 3.4  +31.2  + 3.7  -38.8  + 5.5  + 2.2  + 6.5  
+17.3  +26.2  +20.1  +31.6  + 9.0  +30.9  +34.0  + 4.1  -46.1  -29.7  
+ 7.3  +33.1  -41.0  -17.4  +18.4  +46.6  -29.1  -25.1  +45.5  -36.3  
-36.2  +32.8  -30.6  -11.1  +42.9  +14.1  + 6.1  -46.0  +33.2  +21.9  
-26.0  -36.0  - 1.9  +44.1  + 9.1  -42.9  -11.4  - 6.9  -25.3  - 7.5  
-23.1  - 4.4  +39.1  -14.0  +28.2  + 7.5  +46.0  +12.7  - 4.1  + 5.0

http://coliru.stacked-crooked.com/a/d43dcff6228d2112
I appreciate your help, JLBorges.

I agree. At curious glance everything seems fine.

This is the results of looping 10 times. At each cube point is .5 half size 1 one meter full size.
If you account for that. There should be no collision from the following list.

42.98 39.09
-41.92 -28.05
-37.73 -15.68
-8.5 -34.87
22.62 -45.74
25.78 -5.45
23.42 -4.75
-27.06 24.39
14.34 -2.72
42.6 -42.92

The image of the cubes is created here.

http://i.imgur.com/eeTIsgt.png

Code Snippet Below
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
 /// Temporary structure
    struct WorldOjectCollisionMap
    {
        float size_x;
        float size_y;
        float size_z;
        float origin_x;
        float origin_y;
        float origin_z;
        int lod;
    };

    /// Set world limit of objects to test for collision
    int WorldOjectCollisionMapLimit=600;
    WorldOjectCollisionMap CollisionBounds[WorldOjectCollisionMapLimit];

    /// Saved Collision Objects to 0
    int SaveCollisionObjects=0;

    Node * RockNodes = scene_ -> CreateChild("RockNodes");

    ///Loop 1,000 times to find a suitable location (In this case 40)
    for(unsigned int i=0; i<10; i++)
    {

        /// Pick a random spot
        Spotx=rand()%10000;
        Spotz=rand()%10000;

        randomSpotx=((float)Spotx/100)-50.0f;
        randomSpotz=((float)Spotz/100)-50.0f;

        /// Add a Rock to the seen - Rock Node
        Node * RockNode = RockNodes -> CreateChild("RockNode");

        StaticModel * RockStaticModel = RockNode->CreateComponent<StaticModel>();

        RockStaticModel->SetModel(cache->GetResource<Model>("Resources/Models/Box.mdl"));
        RockStaticModel->ApplyMaterialList("Resources/Models/Box.txt");

        /// Create Nodes and COmponents
        RockStaticModel->SetCastShadows(true);

        BoundingBox  staticmodelbox = RockStaticModel->GetBoundingBox();
        Vector3  staticmodelboxcenter= staticmodelbox.HalfSize();

        cout << randomSpotx << " " << randomSpotz << endl;

        /// Select a possible position to place a Rock
        Vector3 selectPosition=Vector3(randomSpotx,terrain->GetHeight(Vector3(randomSpotx,0.0f,randomSpotz))+staticmodelboxcenter.y_,randomSpotz);

        bool collision=false;

        if(SaveCollisionObjects>0)
        {
            for(unsigned int idx=0; idx<SaveCollisionObjects; idx++)
            {

                /// Check x boundary for overlapping
                if(intersects( make_range(randomSpotx-staticmodelboxcenter.x_,randomSpotx+staticmodelboxcenter.x_), make_range(CollisionBounds[idx].origin_x-CollisionBounds[idx].size_x,CollisionBounds[idx].origin_x+CollisionBounds[idx].size_x)))

                {
                    /// Set collision true
                    collision=true;
                    break;
                }

                /// Check z boundary for overlapping
                if(intersects( make_range(randomSpotz-staticmodelboxcenter.z_,randomSpotz+staticmodelboxcenter.z_), make_range(CollisionBounds[idx].origin_z-CollisionBounds[idx].size_z,CollisionBounds[idx].origin_z+CollisionBounds[idx].size_z)))
                {

                    /// Set collision true
                    collision=true;
                    break;
                }
            }
        }


        /// Test collision
        if(collision==false)
        {
            /// Save coordinates
            CollisionBounds[SaveCollisionObjects].size_x=staticmodelboxcenter.x_;
            CollisionBounds[SaveCollisionObjects].size_y=staticmodelboxcenter.y_;
            CollisionBounds[SaveCollisionObjects].size_z=staticmodelboxcenter.z_;
            CollisionBounds[SaveCollisionObjects].origin_x=randomSpotx;
            CollisionBounds[SaveCollisionObjects].origin_y=terrain->GetHeight(Vector3(randomSpotx,0.0f,randomSpotz))+staticmodelboxcenter.y_;
            CollisionBounds[SaveCollisionObjects].origin_z=randomSpotz;
            CollisionBounds[SaveCollisionObjects].lod=0;

            /// Save object
            SaveCollisionObjects++;

            /// Set Rock position
            RockNode->SetPosition(selectPosition);
            RockNode->SetRotation(Quaternion(Random(360),Vector3(0.0f,1.0f,0.0f)));
        }
        else
        {

            /// Erase the node
            RockNode->RemoveAllComponents();
            RockNode->Remove();
        }

    }

Last edited on
I created a small C with input values and it seemed to work. So, I guess the random generator don't create truly random values. I'm trying to avoid 1000 objects to only get 50 out of it.

I was thinking of creating a better method. Is to create a base set of coordinates still random.

Then use this function to path find points to place objects. If you notice any error can you tell me.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/// Headers and etc
#include <iostream>

#include <algorithm>


#define NORTH 1
#define NORTHEAST 2
#define EAST 3
#define SOUTHEAST 4
#define SOUTH  5
#define SOUTHWEST 6
#define WEST 7
#define NORTHWEST 8

using namespace std;


/// Distance Funcion
float computedistance(int x1, int y1, int x2, int y2)
{
    float  xrange= x1-x2;
    float  yrange= y1-y2;

    return sqrt((xrange*xrange)+(yrange*yrange));
}


/// Main loop
int main()
{


    /// Need variables
    float lengthlimitdistance=10.0f;

    float origin_x=0.0f;
    float origin_y=0.0f;

    float difference_y=0.0f;
    float difference_x=0.0f;

    float position_x=0.0f;
    float position_y=0.0f;

    float newposition_x=0.0f;
    float newposition_y=0.0f;
    float olddistance=0.0f;

    srand (time(NULL));

    position_x=origin_x;
    position_y=origin_y;

    do
    {
        /// Pick a random directoin
        int direction=rand()%8+1;

        /// Select coordinate change based on random direction
        switch (direction)
        {
        case NORTH:
            difference_x=0;
            difference_y=1;
            break;
        case NORTHEAST:
            difference_x=1;
            difference_y=1;
            break;
        case EAST:
            difference_x=+1;
            difference_y=0;
            break;
        case SOUTHEAST:
            difference_x=1;
            difference_y=-1;
            break;
        case SOUTH:
            difference_x=0;
            difference_y=-1;
            break;
        case SOUTHWEST:
            difference_x=-1;
            difference_y=-1;
            break;
        case WEST:
            difference_x=-1;
            difference_y=0;
            break;
        case NORTHWEST:
            difference_x=-1;
            difference_y=1;
            break;
        }

        /// If distance less then current distance then while continue loop
        if(computedistance(position_x+difference_x, origin_x, position_y+difference_y,origin_y)<olddistance)
        {
            continue;
        }
        else
        {
            /// Create a new position
            newposition_x=position_x+difference_x;
            newposition_y=position_y+difference_y;

            ///  Copy newposition to current positon
            position_x=newposition_x;
            position_y=newposition_y;

            /// Get distance
            olddistance=computedistance(position_x, origin_x, position_y, origin_y);

            /// Output X, Y
            cout << position_x << " " << position_y << "\r\n";
        }

        /// Output distance
        cout << olddistance << "\r\n";
    }
    while(olddistance<lengthlimitdistance);


    return 1;
}
Last edited on
Seems fine to me.

The same logic, re-factored into functions:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <utility>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iomanip>

typedef std::pair<float,float> position ;

float square_of_distance_from_origin0( float x, float y ) // origin0 is (0.0,0.0)
{ return x*x + y*y ; }

float square_of_distance_from_origin0( position p ) // origin0 is (0.0,0.0)
{ return square_of_distance_from_origin0( p.first, p.second ) ; }

float square_of_distance_from_origin( position p, position origin )
{
    const float  xrange = p.first - origin.first ;
    const float  yrange = p.second - origin.second ;

    return xrange*xrange + yrange*yrange ;
}

/// random direction: delta -1, 0, +1
int random_delta()
{
    static const int N = 3 ;
    static const int delta[N] = { -1, 0, +1 } ;
    return delta[ std::rand() % N ] ;
}

/// Select coordinate change based on random direction
position next_position( position p )
{ return position( p.first + random_delta(), p.second + random_delta() ) ; }

/// Select coordinate change based on random direction
/// such that distance from (0.0,0.0) is not less then current distance from (0.0,0.0)
position next_away_position( position p )
{
    const float old_dist = square_of_distance_from_origin0(p) ;
    while(true)
    {
        position next( p.first + random_delta(), p.second + random_delta() ) ;
        if( square_of_distance_from_origin0(next) >= old_dist ) return next ;
    }
}

/// Select coordinate change based on random direction
/// such that distance from position from is not less then current distance from position from
position next_away_position( position p, position from )
{
    // transform coordinate system such that position from becomes position(0,0)
    p.first -= from.first ;
    p.second -= from.second ;

    // generate next away_position
    position next = next_away_position(p) ;

    // transform coordinate system back
    next.first += from.first ;
    next.second += from.second ;

    return next ;
}

position random_walk_away( position origin, float square_of_max_distance )
{
    position pos = origin ;
    std::cout << std::fixed << std::setprecision(1) << std::showpos
              << '[' << pos.first << ',' << pos.second << "] (origin)\n" ;
    int n = 0 ;
    do
    {
        pos = next_away_position( pos, origin ) ;
        std::cout << '[' << pos.first << ',' << pos.second << "] " ;
        if( ++n == 8 ) { std::cout << '\n' ; n = 0 ; }
    }
    while( square_of_distance_from_origin(pos,origin) < square_of_max_distance ) ;

    return pos ;
}

int main()
{
    const float max_distance = 10.0f;
    const float square_of_max_distance = max_distance*max_distance ;
    std::srand( std::time(0) );

    const position test[] = { position(0.0,0.0), position(3.0,5.0), position( -3.0, 5.0 ), position( -3.0, -5.0 ) } ;
    for( std::size_t i = 0 ; i < sizeof(test) / sizeof( test[0] ) ; ++i )
    {
        const position p = random_walk_away( test[i], square_of_max_distance ) ;
        std::cout << "\n[" << p.first << ',' << p.second << "] (final)\n\n" ; ;
    }
}

g++-4.6 --version | head -n1 && g++-4.6 -std=c++98 -O3 -Wall -Wextra -pedantic-errors -lsupc++ main.cpp && ./a.out
g++-4.6 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 4.6.4
[+0.0,+0.0] (origin)
[+1.0,+1.0] [+2.0,+2.0] [+1.0,+3.0] [+1.0,+3.0] [+1.0,+4.0] [+2.0,+5.0] [+3.0,+6.0] [+2.0,+7.0] 
[+1.0,+8.0] [+1.0,+9.0] [+1.0,+9.0] [+2.0,+9.0] [+2.0,+9.0] [+1.0,+10.0] 
[+1.0,+10.0] (final)

[+3.0,+5.0] (origin)
[+3.0,+6.0] [+3.0,+6.0] [+4.0,+6.0] [+5.0,+5.0] [+6.0,+6.0] [+7.0,+6.0] [+8.0,+6.0] [+9.0,+7.0] 
[+10.0,+6.0] [+11.0,+6.0] [+12.0,+7.0] [+12.0,+7.0] [+12.0,+8.0] [+12.0,+8.0] [+13.0,+8.0] 
[+13.0,+8.0] (final)

[-3.0,+5.0] (origin)
[-2.0,+6.0] [-1.0,+7.0] [+0.0,+6.0] [+0.0,+7.0] [+1.0,+7.0] [+2.0,+8.0] [+2.0,+9.0] [+3.0,+10.0] 
[+4.0,+11.0] [+5.0,+10.0] [+5.0,+10.0] [+6.0,+10.0] 
[+6.0,+10.0] (final)

[-3.0,-5.0] (origin)
[-3.0,-5.0] [-3.0,-4.0] [-2.0,-4.0] [-1.0,-5.0] [+0.0,-4.0] [+1.0,-4.0] [+1.0,-3.0] [+2.0,-4.0] 
[+3.0,-5.0] [+4.0,-5.0] [+4.0,-5.0] [+5.0,-5.0] [+5.0,-6.0] [+5.0,-7.0] [+5.0,-8.0] [+5.0,-8.0] 
[+6.0,-7.0] [+6.0,-7.0] [+6.0,-8.0] [+6.0,-9.0] [+6.0,-9.0] [+7.0,-10.0] 
[+7.0,-10.0] (final)

http://coliru.stacked-crooked.com/a/046b8ff2fd1b3394
Topic archived. No new replies allowed.