// Find the closest points between two shapes using the GJK algorithm. static struct ClosestPoints GJK(const struct SupportContext *ctx, cpCollisionID *id) { #if DRAW_GJK || DRAW_EPA int count1 = 1; int count2 = 1; switch(ctx->shape1->klass->type) { case CP_SEGMENT_SHAPE: count1 = 2; break; case CP_POLY_SHAPE: count1 = ((cpPolyShape *)ctx->shape1)->count; break; default: break; } switch(ctx->shape2->klass->type) { case CP_SEGMENT_SHAPE: count1 = 2; break; case CP_POLY_SHAPE: count2 = ((cpPolyShape *)ctx->shape2)->count; break; default: break; } // draw the minkowski difference origin cpVect origin = cpvzero; ChipmunkDebugDrawDot(5.0, origin, RGBAColor(1,0,0,1)); int mdiffCount = count1*count2; cpVect *mdiffVerts = alloca(mdiffCount*sizeof(cpVect)); for(int i=0; i<count1; i++) { for(int j=0; j<count2; j++) { cpVect v = cpvsub(ShapePoint(ctx->shape2, j).p, ShapePoint(ctx->shape1, i).p); mdiffVerts[i*count2 + j] = v; ChipmunkDebugDrawDot(2.0, v, RGBAColor(1, 0, 0, 1)); } } cpVect *hullVerts = alloca(mdiffCount*sizeof(cpVect)); int hullCount = cpConvexHull(mdiffCount, mdiffVerts, hullVerts, NULL, 0.0); ChipmunkDebugDrawPolygon(hullCount, hullVerts, 0.0, RGBAColor(1, 0, 0, 1), RGBAColor(1, 0, 0, 0.25)); #endif struct MinkowskiPoint v0, v1; if(*id) { // Use the minkowski points from the last frame as a starting point using the cached indexes. v0 = MinkowskiPointNew(ShapePoint(ctx->shape1, (*id>>24)&0xFF), ShapePoint(ctx->shape2, (*id>>16)&0xFF)); v1 = MinkowskiPointNew(ShapePoint(ctx->shape1, (*id>> 8)&0xFF), ShapePoint(ctx->shape2, (*id )&0xFF)); } else {
list<ShapePoint> RectangleLayerShape::getShapePoints() { list<ShapePoint> points; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { points.push_back(ShapePoint(Point(x, y), value)); } } return points; }
XShape::XShape(shapefileObj *shpfile, const GeoPoint &file_center, int i, int label_field) :label(nullptr) { #ifdef ENABLE_OPENGL std::fill_n(index_count, THINNING_LEVELS, nullptr); std::fill_n(indices, THINNING_LEVELS, nullptr); #endif shapeObj shape; msInitShape(&shape); msSHPReadShape(shpfile->hSHP, i, &shape); bounds = ImportRect(shape.bounds); type = shape.type; num_lines = 0; const int min_points = min_points_for_type(shape.type); if (min_points < 0) { /* not supported, leave an empty XShape object */ points = nullptr; msFreeShape(&shape); return; } const unsigned input_lines = std::min((unsigned)shape.numlines, (unsigned)MAX_LINES); unsigned num_points = 0; for (unsigned l = 0; l < input_lines; ++l) { if (shape.line[l].numpoints < min_points) /* malformed shape */ continue; lines[num_lines] = std::min(shape.line[l].numpoints, 16384); num_points += lines[num_lines]; ++num_lines; } #ifdef ENABLE_OPENGL /* OpenGL: convert GeoPoints to ShapePoints, make them relative to the map's boundary center */ points = new ShapePoint[num_points]; ShapePoint *p = points; #else // !ENABLE_OPENGL /* convert all points of all lines to GeoPoints */ points = new GeoPoint[num_points]; GeoPoint *p = points; #endif for (unsigned l = 0; l < num_lines; ++l) { const pointObj *src = shape.line[l].point; num_points = lines[l]; for (unsigned j = 0; j < num_points; ++j, ++src) { #ifdef ENABLE_OPENGL const GeoPoint vertex(Angle::Degrees(src->x), Angle::Degrees(src->y)); const GeoPoint relative = vertex - file_center; *p++ = ShapePoint(ShapeScalar(relative.longitude.Native()), ShapeScalar(relative.latitude.Native())); #else *p++ = GeoPoint(Angle::Degrees(fixed(src->x)), Angle::Degrees(fixed(src->y))); #endif } } if (label_field >= 0) { const char *src = msDBFReadStringAttribute(shpfile->hDBF, i, label_field); label = import_label(src); } msFreeShape(&shape); }