#include "draw.h"
#include "sample.h"
#include "settings.h"
#include "box2d/math_functions.h"
#include <GLFW/glfw3.h>
class ConvexHull : public Sample
{
public:
enum
{
e_count = b2_maxPolygonVertices
};
explicit ConvexHull( Settings& settings )
: Sample( settings )
{
if ( settings.restart == false )
{
g_camera.m_center = { 0.5f, 0.0f };
g_camera.m_zoom = 25.0f * 0.3f;
}
m_generation = 0;
m_auto = false;
m_bulk = false;
Generate();
}
void Generate()
{
#if 0#else
float angle = b2_pi * RandomFloat();
b2Rot r = b2MakeRot( angle );
b2Vec2 lowerBound = { -4.0f, -4.0f };
b2Vec2 upperBound = { 4.0f, 4.0f };
for ( int i = 0; i < e_count; ++i )
{
float x = 10.0f * RandomFloat();
float y = 10.0f * RandomFloat();
b2Vec2 v = b2Clamp( { x, y }, lowerBound, upperBound );
m_points[i] = b2RotateVector( r, v );
}
m_count = e_count;
#endif
m_generation += 1;
}
void Keyboard( int key ) override
{
switch ( key )
{
case GLFW_KEY_A:
m_auto = !m_auto;
break;
case GLFW_KEY_B:
m_bulk = !m_bulk;
break;
case GLFW_KEY_G:
Generate();
break;
default:
break;
}
}
void Step( Settings& settings ) override
{
Sample::Step( settings );
g_draw.DrawString( 5, m_textLine, "Options: generate(g), auto(a), bulk(b)" );
m_textLine += m_textIncrement;
b2Hull hull;
bool valid = false;
float milliseconds = 0.0f;
if ( m_bulk )
{
#if 1
for ( int i = 0; i < 10000; ++i )
{
Generate();
hull = b2ComputeHull( m_points, m_count );
if ( hull.count == 0 )
{
continue;
}
valid = b2ValidateHull( &hull );
if ( valid == false || m_bulk == false )
{
m_bulk = false;
break;
}
}
#else#endif
}
else
{
if ( m_auto )
{
Generate();
}
hull = b2ComputeHull( m_points, m_count );
if ( hull.count > 0 )
{
valid = b2ValidateHull( &hull );
if ( valid == false )
{
m_auto = false;
}
}
}
if ( valid == false )
{
g_draw.DrawString( 5, m_textLine, "generation = %d, FAILED", m_generation );
m_textLine += m_textIncrement;
}
else
{
g_draw.DrawString( 5, m_textLine, "generation = %d, count = %d", m_generation, hull.count );
m_textLine += m_textIncrement;
}
if ( milliseconds > 0.0f )
{
g_draw.DrawString( 5, m_textLine, "milliseconds = %g", milliseconds );
m_textLine += m_textIncrement;
}
m_textLine += m_textIncrement;
g_draw.DrawPolygon( hull.points, hull.count, b2_colorGray );
for ( int32_t i = 0; i < m_count; ++i )
{
g_draw.DrawPoint( m_points[i], 5.0f, b2_colorBlue );
g_draw.DrawString( b2Add( m_points[i], { 0.1f, 0.1f } ), "%d", i );
}
for ( int32_t i = 0; i < hull.count; ++i )
{
g_draw.DrawPoint( hull.points[i], 6.0f, b2_colorGreen );
}
}
static Sample* Create( Settings& settings )
{
return new ConvexHull( settings );
}
b2Vec2 m_points[b2_maxPolygonVertices];
int32_t m_count;
int32_t m_generation;
bool m_auto;
bool m_bulk;
};
static int sampleIndex = RegisterSample( "Geometry", "Convex Hull", ConvexHull::Create );