mirror of
https://github.com/love2d/love.git
synced 2026-08-12 16:40:57 +02:00
Box2D implemented its own convex hull algorithm, Graham just messes things up
--HG-- branch : box2d-update
This commit is contained in:
@@ -115,7 +115,6 @@
|
||||
A946D7F910424E57002BF36C /* wrap_World.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B6A10420ACA007D418B /* wrap_World.cpp */; };
|
||||
A946D7FA10424E57002BF36C /* wrap_RevoluteJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B6610420ACA007D418B /* wrap_RevoluteJoint.cpp */; };
|
||||
A946D7FB10424E57002BF36C /* wrap_PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B6210420ACA007D418B /* wrap_PrismaticJoint.cpp */; };
|
||||
A946D7FC10424E57002BF36C /* GrahamScanConvexHull.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6AF610420AC7007D418B /* GrahamScanConvexHull.cpp */; };
|
||||
A946D7FE10424E57002BF36C /* wrap_MouseJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B5C10420ACA007D418B /* wrap_MouseJoint.cpp */; };
|
||||
A946D7FF10424E57002BF36C /* wrap_Physics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B5E10420ACA007D418B /* wrap_Physics.cpp */; };
|
||||
A946D80210424E57002BF36C /* PrismaticJoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6B0210420AC8007D418B /* PrismaticJoint.cpp */; };
|
||||
@@ -442,8 +441,6 @@
|
||||
A93E6AF210420AC7007D418B /* DistanceJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DistanceJoint.h; sourceTree = "<group>"; };
|
||||
A93E6AF310420AC7007D418B /* GearJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GearJoint.cpp; sourceTree = "<group>"; };
|
||||
A93E6AF410420AC7007D418B /* GearJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GearJoint.h; sourceTree = "<group>"; };
|
||||
A93E6AF610420AC7007D418B /* GrahamScanConvexHull.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GrahamScanConvexHull.cpp; sourceTree = "<group>"; };
|
||||
A93E6AF710420AC8007D418B /* GrahamScanConvexHull.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GrahamScanConvexHull.h; sourceTree = "<group>"; };
|
||||
A93E6AFA10420AC8007D418B /* Joint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joint.cpp; sourceTree = "<group>"; };
|
||||
A93E6AFB10420AC8007D418B /* Joint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joint.h; sourceTree = "<group>"; };
|
||||
A93E6AFC10420AC8007D418B /* MouseJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseJoint.cpp; sourceTree = "<group>"; };
|
||||
@@ -572,9 +569,9 @@
|
||||
A96F417814127EFD0067FE9A /* b2EdgeAndCircleContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndCircleContact.cpp; sourceTree = "<group>"; };
|
||||
A96F417914127EFD0067FE9A /* b2EdgeAndCircleContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndCircleContact.h; sourceTree = "<group>"; };
|
||||
A96F417A14127EFD0067FE9A /* b2EdgeAndPolygonContact.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeAndPolygonContact.cpp; sourceTree = "<group>"; };
|
||||
A96F417B14127EFD0067FE9A /* b2EdgeAndPolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; path = b2EdgeAndPolygonContact.h; sourceTree = "<group>"; };
|
||||
A96F417B14127EFD0067FE9A /* b2EdgeAndPolygonContact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeAndPolygonContact.h; sourceTree = "<group>"; };
|
||||
A96F417E14127FC20067FE9A /* b2EdgeShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b2EdgeShape.cpp; sourceTree = "<group>"; };
|
||||
A96F417F14127FC20067FE9A /* b2EdgeShape.h */ = {isa = PBXFileReference; fileEncoding = 4; path = b2EdgeShape.h; sourceTree = "<group>"; };
|
||||
A96F417F14127FC20067FE9A /* b2EdgeShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2EdgeShape.h; sourceTree = "<group>"; };
|
||||
A96F41811412AFB70067FE9A /* wrap_WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_WeldJoint.cpp; sourceTree = "<group>"; };
|
||||
A96F41821412AFC60067FE9A /* wrap_WeldJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_WeldJoint.h; sourceTree = "<group>"; };
|
||||
A96F41841412AFEB0067FE9A /* WeldJoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeldJoint.cpp; sourceTree = "<group>"; };
|
||||
@@ -1231,7 +1228,6 @@
|
||||
A9B6432B13BF837800DC3C7E /* FrictionJoint.h */,
|
||||
A93E6AF310420AC7007D418B /* GearJoint.cpp */,
|
||||
A93E6AF410420AC7007D418B /* GearJoint.h */,
|
||||
A93E6AF510420AC7007D418B /* graham */,
|
||||
A93E6AFA10420AC8007D418B /* Joint.cpp */,
|
||||
A93E6AFB10420AC8007D418B /* Joint.h */,
|
||||
A93E6AFC10420AC8007D418B /* MouseJoint.cpp */,
|
||||
@@ -1302,15 +1298,6 @@
|
||||
path = box2d;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A93E6AF510420AC7007D418B /* graham */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
A93E6AF610420AC7007D418B /* GrahamScanConvexHull.cpp */,
|
||||
A93E6AF710420AC8007D418B /* GrahamScanConvexHull.h */,
|
||||
);
|
||||
path = graham;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A93E6B7410420ACB007D418B /* sound */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1730,7 +1717,6 @@
|
||||
A946D7F910424E57002BF36C /* wrap_World.cpp in Sources */,
|
||||
A946D7FA10424E57002BF36C /* wrap_RevoluteJoint.cpp in Sources */,
|
||||
A946D7FB10424E57002BF36C /* wrap_PrismaticJoint.cpp in Sources */,
|
||||
A946D7FC10424E57002BF36C /* GrahamScanConvexHull.cpp in Sources */,
|
||||
A946D7FE10424E57002BF36C /* wrap_MouseJoint.cpp in Sources */,
|
||||
A946D7FF10424E57002BF36C /* wrap_Physics.cpp in Sources */,
|
||||
A946D80210424E57002BF36C /* PrismaticJoint.cpp in Sources */,
|
||||
|
||||
@@ -20,9 +20,6 @@
|
||||
|
||||
#include "Physics.h"
|
||||
|
||||
// Convex Hull Scan
|
||||
#include "graham/GrahamScanConvexHull.h"
|
||||
|
||||
// LOVE
|
||||
#include <common/math.h>
|
||||
#include "wrap_Body.h"
|
||||
@@ -102,35 +99,18 @@ namespace box2d
|
||||
love::luax_assert_argc(L, 2 * 3);
|
||||
|
||||
b2PolygonShape* s = new b2PolygonShape();
|
||||
|
||||
std::vector<point2d> points(s->m_vertexCount);
|
||||
std::vector<point2d> convex_hull;
|
||||
|
||||
b2Vec2 * vecs = new b2Vec2[vcount];
|
||||
|
||||
for(int i = 0;i<vcount;i++)
|
||||
{
|
||||
float x = (float)lua_tonumber(L, -2);
|
||||
float y = (float)lua_tonumber(L, -1);
|
||||
point2d tmp(x, y);
|
||||
points.push_back(tmp);
|
||||
vecs[i] = (Physics::scaleDown(b2Vec2(x, y)));
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
// Compute convex hull.
|
||||
GrahamScanConvexHull()(points, convex_hull);
|
||||
|
||||
int count = convex_hull.size();
|
||||
|
||||
if(count < 3)
|
||||
return luaL_error(L, "Polygon degenerated to less than three points.");
|
||||
|
||||
b2Vec2 * vecs = new b2Vec2[count];
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
vecs[i].Set(convex_hull[i].x, convex_hull[i].y);
|
||||
vecs[i] = Physics::scaleDown(vecs[i]);
|
||||
}
|
||||
|
||||
s->Set(vecs, count);
|
||||
s->Set(vecs, vcount);
|
||||
|
||||
PolygonShape * p = new PolygonShape(s);
|
||||
delete[] vecs;
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#include "GrahamScanConvexHull.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
bool GrahamScanConvexHull::operator()(const std::vector < point2d >& pnt, std::vector< point2d >& final_hull)
|
||||
{
|
||||
final_hull.clear();
|
||||
|
||||
if (pnt.size() <= 3)
|
||||
{
|
||||
std::copy(pnt.begin(), pnt.end(), std::back_inserter(final_hull));
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int j = 0;
|
||||
gs_point2d tmp_pnt;
|
||||
|
||||
for(unsigned int i = 0; i < pnt.size(); i++)
|
||||
{
|
||||
point.push_back(gs_point2d(pnt[i].x,pnt[i].y,0.0));
|
||||
|
||||
if (point[i].y < point[j].y)
|
||||
j = i;
|
||||
else if (point[i].y == point[j].y)
|
||||
if (point[i].x < point[j].x)
|
||||
j = i;
|
||||
}
|
||||
|
||||
tmp_pnt = point[0];
|
||||
point[0] = point[j];
|
||||
point[j] = tmp_pnt;
|
||||
|
||||
anchor = point[0];
|
||||
|
||||
for (unsigned int i = 1; i < point.size(); i++)
|
||||
{
|
||||
point[i].angle = cartesian_angle(point[i].x - anchor.x, point[i].y - anchor.y);
|
||||
}
|
||||
|
||||
sort(++point.begin(),point.end(),GSPoint2DCompare(&anchor));
|
||||
|
||||
graham_scan(final_hull);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void GrahamScanConvexHull::graham_scan(std::vector< point2d >& final_hull)
|
||||
{
|
||||
const std::size_t HEAD = 0;
|
||||
const std::size_t PRE_HEAD = 1;
|
||||
|
||||
std::deque<gs_point2d> pnt_queue;
|
||||
|
||||
pnt_queue.push_front(point[0]);
|
||||
pnt_queue.push_front(point[1]);
|
||||
|
||||
unsigned int i = 2;
|
||||
|
||||
while(i < point.size())
|
||||
{
|
||||
if (pnt_queue.size() > 1)
|
||||
{
|
||||
if (orientation(pnt_queue[PRE_HEAD],pnt_queue[HEAD],point[i]) == counter_clock_wise)
|
||||
pnt_queue.push_front(point[i++]);
|
||||
else
|
||||
pnt_queue.pop_front();
|
||||
}
|
||||
else
|
||||
pnt_queue.push_front(point[i++]);
|
||||
}
|
||||
|
||||
for(std::deque<gs_point2d>::iterator it = pnt_queue.begin(); it != pnt_queue.end(); it++)
|
||||
{
|
||||
final_hull.push_back(point2d((*it).x, (*it).y));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline double GrahamScanConvexHull::cartesian_angle(double x, double y)
|
||||
{
|
||||
if ((x > 0.0) && (y > 0.0)) return (atan( y / x) * _180DivPI);
|
||||
else if ((x < 0.0) && (y > 0.0)) return (atan(-x / y) * _180DivPI) + 90.0;
|
||||
else if ((x < 0.0) && (y < 0.0)) return (atan( y / x) * _180DivPI) + 180.0;
|
||||
else if ((x > 0.0) && (y < 0.0)) return (atan(-x / y) * _180DivPI) + 270.0;
|
||||
else if ((x == 0.0) && (y > 0.0)) return 90.0;
|
||||
else if ((x < 0.0) && (y == 0.0)) return 180.0;
|
||||
else if ((x == 0.0) && (y < 0.0)) return 270.0;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
inline int GrahamScanConvexHull::orientation(const gs_point2d& p1, const gs_point2d& p2, const gs_point2d& p3)
|
||||
{
|
||||
return orientation(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y);
|
||||
}
|
||||
|
||||
|
||||
inline int GrahamScanConvexHull::orientation(const double x1, const double y1,
|
||||
const double x2, const double y2,
|
||||
const double px, const double py)
|
||||
{
|
||||
double orin = (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1);
|
||||
|
||||
if (is_equal(orin,0.0))
|
||||
return 0; /* Orientaion is neutral aka collinear */
|
||||
else if (orin < 0.0)
|
||||
return -1; /* Orientaion is to the right-hand side */
|
||||
else
|
||||
return +1; /* Orientaion is to the left-hand side */
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline bool GrahamScanConvexHull::is_equal(const double v1, const double& v2, const double epsilon)
|
||||
{
|
||||
double diff = v1 - v2;
|
||||
return (-epsilon <= diff) && (diff <= epsilon);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
**************************************************************************
|
||||
* Class: Graham Scan Convex Hull *
|
||||
* By Arash Partow - 2001 *
|
||||
* URL: http://www.partow.net *
|
||||
* *
|
||||
* Copyright Notice: *
|
||||
* Free use of this library is permitted under the guidelines and *
|
||||
* in accordance with the most current version of the Common Public *
|
||||
* License. *
|
||||
* http://www.opensource.org/licenses/cpl.php *
|
||||
* *
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INCLUDE_GRAHAMSCANCONVEXHULL_H
|
||||
#define INCLUDE_GRAHAMSCANCONVEXHULL_H
|
||||
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct point2d
|
||||
{
|
||||
point2d(double _x = 0.0 , double _y = 0.0) : x(_x), y(_y){}
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
class ConvexHull
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~ConvexHull(){};
|
||||
virtual bool operator()(const std::vector<point2d>& pnt, std::vector<point2d>& final_hull) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct gs_point2d
|
||||
{
|
||||
public:
|
||||
gs_point2d(double _x = 0.0, double _y = 0.0, double _angle = 0.0) : x(_x), y(_y), angle(_angle){}
|
||||
double x;
|
||||
double y;
|
||||
double angle;
|
||||
};
|
||||
|
||||
const double _180DivPI = 57.295779513082320876798154814105000;
|
||||
const int counter_clock_wise = +1;
|
||||
const int clock_wise = -1;
|
||||
|
||||
|
||||
class GSPoint2DCompare
|
||||
{
|
||||
public:
|
||||
|
||||
GSPoint2DCompare(gs_point2d* _anchor):anchor(_anchor){};
|
||||
|
||||
bool operator()(const gs_point2d& p1, const gs_point2d& p2)
|
||||
{
|
||||
if (p1.angle < p2.angle) return true;
|
||||
else if (p1.angle > p2.angle) return false;
|
||||
else if (is_equal(p1,p2)) return false;
|
||||
else if (lay_distance(anchor->x, anchor->y, p1.x, p1.y) < lay_distance(anchor->x, anchor->y, p2.x, p2.y))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline bool is_equal(const gs_point2d p1, gs_point2d p2)
|
||||
{
|
||||
return is_equal(p1.x,p2.x) && is_equal(p1.y,p2.y);
|
||||
}
|
||||
|
||||
inline bool is_equal(const double v1, const double& v2, const double epsilon = 1.0e-12)
|
||||
{
|
||||
double diff = v1 - v2;
|
||||
return (-epsilon <= diff) && (diff <= epsilon);
|
||||
}
|
||||
|
||||
inline double lay_distance(const double& x1, const double& y1, const double& x2, const double& y2)
|
||||
{
|
||||
double dx = (x1 - x2);
|
||||
double dy = (y1 - y2);
|
||||
return (dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
gs_point2d* anchor;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class GrahamScanConvexHull : public ConvexHull
|
||||
{
|
||||
public:
|
||||
|
||||
GrahamScanConvexHull(){};
|
||||
~GrahamScanConvexHull(){};
|
||||
|
||||
virtual bool operator()(const std::vector < point2d >& pnt, std::vector< point2d >& final_hull);
|
||||
|
||||
private:
|
||||
|
||||
void graham_scan(std::vector< point2d >& final_hull);
|
||||
|
||||
inline double cartesian_angle(double x, double y);
|
||||
|
||||
inline int orientation(const gs_point2d& p1,
|
||||
const gs_point2d& p2,
|
||||
const gs_point2d& p3);
|
||||
|
||||
inline int orientation(const double x1, const double y1,
|
||||
const double x2, const double y2,
|
||||
const double px, const double py);
|
||||
|
||||
inline bool is_equal(const double v1, const double& v2, const double epsilon = 1.0e-12);
|
||||
|
||||
std::vector<gs_point2d> point;
|
||||
gs_point2d anchor;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user