I have four point say _pointA _pointB _pointC _pointD. I want to find the nearest point from the current point. I had something like this but it sometimes gives wrong reasult.
Problem : When i near to pointA it gives pointC
CGPoint neastPoint=CGPointZero;
for (int i=0; i<3; i++) {
CGFloat x;
CGFloat y;
CGFloat currntDistance;
if (i==0){
x=(pointA.x-currentPoint.x) *(pointA.x-currentPoint.x);
y=(pointA.y-currentPoint.y)*(pointA.y-currentPoint.y);
currntDistance =sqrtf(x+y);
distance=currntDistance;
neastPoint=pointA;
}
else if (i==1){
x=(pointB.x-currentPoint.x) *(pointB.x-currentPoint.x);
y=(pointB.y-currentPoint.y)*(pointB.y-currentPoint.y);
currntDistance =sqrtf(x+y);
if (distance>currntDistance) {
distance=currntDistance;
neastPoint=pointB;
}
}
else if (i==2){
x=(pointC.x-currentPoint.x) *(pointC.x-currentPoint.x);
y=(pointC.y-currentPoint.y)*(pointC.y-currentPoint.y);
currntDistance =sqrtf(x+y);
if (distance>currntDistance) {
distance=currntDistance;
neastPoint=pointC;
}
}
else {
x=(pointD.x-currentPoint.x) *(pointD.x-currentPoint.x);
y=(pointD.y-currentPoint.y)*(pointD.y-currentPoint.y);
currntDistance =sqrtf(x+y);
if (distance>currntDistance) {
distance=currntDistance;
neastPoint=pointD;
}
}
CurrentPoint : {44, 33.140846}
Point A : {71, 178}
Point B : {134, 178}
Point C : {133, 71}
Point D : {75, 67}
Nearast Point : {133, 71}
With the points that you have given, pointD is the closest to currentPoint.
It is not found by your code because
for (int i=0; i<3; i++) {
should be
for (int i=0; i<4; i++) {
to check all 4 points. As others have noticed, you can simplify your code,
for example
CGFloat distance = FLT_MAX; // start with some large value
CGPoint nearestPoint;
CGPoint points[] = { pointA, pointB, pointC, pointD };
for (int i = 0; i < 4; i++) {
CGFloat currentDistance = hypotf(points[i].x - currentPoint.x, points[i].y - currentPoint.y);
if (currentDistance < distance) {
distance = currentDistance;
nearestPoint = points[i];
}
}
Pseudo :
Point[] allPoints = {poinA,pontB,pointC,....,pointN}
int distance = Int.MAX_VALUE;
Point nearestPoint = null;
for(int i = 0 ; i < allPoints.count;i++){
if(pointA != allPoints[i]){
int currentDistance = getDistance(pointA,allPoints[i]);
if(currentDistance < distance){
distance = currentDistance;
nearestPoint = allPoints[i];
}
}
}
print("Nearest point is " + nearestPoint);
Related
I have a contour which consists of curved segments and straigth segments. Is there any possibility to segment the contour into the curved and straigth parts?
So this is an example for a contour
I would like to have a segmentation like this:
Do you have any idea how I could solve such a problem
Thank you very much and best regards
Yes I got the solution with the link #PSchn posted. I just go through the contour points and defined a border. Everything under the border is a "curved segment" everthing else is a straigth segment. Thank you for your help!!
vector<double> getCurvature(vector<Point> const& tContourPoints, int tStepSize)
{
int iplus;
int iminus;
double acurvature;
double adivisor;
Point2f pplus;
Point2f pminus;
// erste Ableitung
Point2f a1stDerivative;
// zweite Ableitung
Point2f a2ndDerivative;
vector< double > rVecCurvature( tContourPoints.size() );
if ((int)tContourPoints.size() < tStepSize)
{
return rVecCurvature;
}
for (int i = 0; i < (int)tContourPoints.size(); i++ )
{
const Point2f& pos = tContourPoints[i];
iminus = i-tStepSize;
iplus = i+tStepSize;
if(iminus < 0)
{
pminus = tContourPoints[iminus + tContourPoints.size()];
}
else
{
pminus = tContourPoints[iminus];
}
if(iplus > (int)tContourPoints.size())
{
pplus = tContourPoints[iplus - (int)tContourPoints.size()];
}
else
{
pplus = tContourPoints[iplus];
}
a1stDerivative.x = (pplus.x - pminus.x) / ( iplus-iminus);
a1stDerivative.y = (pplus.y - pminus.y) / ( iplus-iminus);
a2ndDerivative.x = (pplus.x - 2*pos.x + pminus.x) / ((iplus-iminus)/2*(iplus-iminus)/2);
a2ndDerivative.y = (pplus.y - 2*pos.y + pminus.y) / ((iplus-iminus)/2*(iplus-iminus)/2);
adivisor = a2ndDerivative.x*a2ndDerivative.x + a2ndDerivative.y*a2ndDerivative.y;
if ( abs(adivisor) > 10e-8 )
{
acurvature = abs(a2ndDerivative.y*a1stDerivative.x - a2ndDerivative.x*a1stDerivative.y) / pow(adivisor, 3.0/2.0 ) ;
}
else
{
acurvature = numeric_limits<double>::infinity();
}
rVecCurvature[i] = acurvature;
}
return rVecCurvature;
}
Once I get the curvature I defined a border and went through my contour:
acurvature = getCurvature(aContours_img[0], 50);
if(acurvature.size() > 0)
{
// aSegmentChange =1 --> curved segment
// aSegmentChange =0 --> straigth segment
if( acurvature[0] < aBorder)
{
aSegmentChange = 1;
}
else
{
aSegmentChange = 0;
}
// Kontur segmentieren
for(int i = 0; i < (int)acurvature.size(); i++)
{
aSegments[aSegmentIndex].push_back(aContours_img[0][i]);
aCurveIndex[aSegmentIndex].push_back(aSegmentChange);
if( acurvature[i] < aBorder && aSegmentChange == 0 )
{
aSegmentIndex++;
aSegmentChange = 1;
}
if( acurvature[i] > aBorder && aSegmentChange == 1 )
{
aSegmentIndex++;
aSegmentChange = 0;
}
if(aSegmentIndex >= (int)aSegments.size()-1)
{
aSegments.resize(aSegmentIndex+1);
aCurveIndex.resize(aSegmentIndex+1);
}
}
}
This is my contour
And this is the result of segmentation
How to get from a opencv Mat pointcloud to a pcl::pointcloud? The color is not important for me only the points itself.
you can do this like:
pcl::PointCloud<pcl::PointXYZ>::Ptr SimpleOpenNIViewer::MatToPoinXYZ(cv::Mat OpencVPointCloud)
{
/*
* Function: Get from a Mat to pcl pointcloud datatype
* In: cv::Mat
* Out: pcl::PointCloud
*/
//char pr=100, pg=100, pb=100;
pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);//(new pcl::pointcloud<pcl::pointXYZ>);
for(int i=0;i<OpencVPointCloud.cols;i++)
{
//std::cout<<i<<endl;
pcl::PointXYZ point;
point.x = OpencVPointCloud.at<float>(0,i);
point.y = OpencVPointCloud.at<float>(1,i);
point.z = OpencVPointCloud.at<float>(2,i);
// when color needs to be added:
//uint32_t rgb = (static_cast<uint32_t>(pr) << 16 | static_cast<uint32_t>(pg) << 8 | static_cast<uint32_t>(pb));
//point.rgb = *reinterpret_cast<float*>(&rgb);
point_cloud_ptr -> points.push_back(point);
}
point_cloud_ptr->width = (int)point_cloud_ptr->points.size();
point_cloud_ptr->height = 1;
return point_cloud_ptr;
}
And also the otherway
cv::Mat MVW_ICP::PoinXYZToMat(pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr){
cv::Mat OpenCVPointCloud(3, point_cloud_ptr->points.size(), CV_64FC1);
for(int i=0; i < point_cloud_ptr->points.size();i++){
OpenCVPointCloud.at<double>(0,i) = point_cloud_ptr->points.at(i).x;
OpenCVPointCloud.at<double>(1,i) = point_cloud_ptr->points.at(i).y;
OpenCVPointCloud.at<double>(2,i) = point_cloud_ptr->points.at(i).z;
}
return OpenCVPointCloud;
}
To convert from a range image captured by a Kinect sensor and represented by depthMat to a pcl::PointCloud you can try this function. The calibration parameters are those used here.
{
pcl::PointCloud<pcl::PointXYZ>::Ptr MatToPoinXYZ(cv::Mat depthMat)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr ptCloud (new pcl::PointCloud<pcl::PointXYZ>);
// calibration parameters
float const fx_d = 5.9421434211923247e+02;
float const fy_d = 5.9104053696870778e+02;
float const cx_d = 3.3930780975300314e+02;
float const cy_d = 2.4273913761751615e+02;
unsigned char* p = depthMat.data;
for (int i = 0; i<depthMat.rows; i++)
{
for (int j = 0; j < depthMat.cols; j++)
{
float z = static_cast<float>(*p);
pcl::PointXYZ point;
point.z = 0.001 * z;
point.x = point.z*(j - cx_d) / fx_d;
point.y = point.z *(cy_d - i) / fy_d;
ptCloud->points.push_back(point);
++p;
}
}
ptCloud->width = (int)depthMat.cols;
ptCloud->height = (int)depthMat.rows;
return ptCloud;
}
}
I am new in game development. I am creating a bubble shooting game in x-code using cocos2dx.
All things are working properly but sometimes the collision does not work. The playerBuble does not collide in the last line, it collides with the last one. Where’s the problem in my code?
bool collided = false;
int collidedX = 0;
int collidedY = 0;
CCPoint playerBubblePosition = playerBubble->getPosition();
// Breadth first Search through the array starting from the bottom left
for (int y = GRID_HEIGHT-1; y >= 0; y--)
{
if (collided)
break;
int maxWidth = GRID_WIDTH;
if (y % 2 != 0) // odd rows have GRID_WIDTH -1 bubbles
{
maxWidth -= 1;
}
for (int x = 0; x < maxWidth; x++)
{
Bubble* bubble = m_pBubbles[x][y];
//
if ((y != 0 &&( bubble->getType() == EMPTY) || bubble->getFalling())
continue;
if ((ccpDistance(bubble->getPosition(), (playerBubblePosition)) < (BUBBLE_RADIUS))
{
collidedX = x;
collidedY = y;
collided = true;
break;
}
}
}
I am loading a png in processing. This png has a lot of unused pixels around the actual image. Luckily all those pixels are completely transparent. My goal is to crop the png to only show the image and get rid of the unused pixels. The first step would be to calculate the bounds of the image. Initially i wanted to check every pixel for alpha value and see if that pixel is the highest or lowest coordinate for bounds. like this:
------
------
--->oo
oooooo
oooooo
Then i realized i only needed to do this until the first non-alpha pixel and repeat it backwards for highest coordinate bound. Like this:
------
-->ooo
oooooo
ooo<--
------
This would mean less calculating for the same result. However the code i got out of it still seems to be very complex. Here it is:
class Rect { //class for storing the boundries
int xMin, xMax, yMin, yMax;
Rect() {
}
}
PImage gfx;
void setup() {
size(800, 600);
gfx = loadImage("resources/test.png");
Rect _bounds = calcBounds(); //first calculate the boundries
cropImage(_bounds); //then crop the image using those boundries
}
void draw() {
}
Rect calcBounds() {
Rect _bounds = new Rect();
boolean _coordFound = false;
gfx.loadPixels();
//x min bounds
for (int i = 0; i < gfx.width; i++) { //rows
for (int i2 = 0; i2 < gfx.height; i2++) { //columns
if (alpha(gfx.pixels[(gfx.width * i2) + i]) != 0) {
_bounds.xMin = i;
_coordFound = true;
break;
}
}
if (_coordFound) {
break;
}
}
//x max bounds
_coordFound = false;
for (int i = gfx.width - 1; i >= 0; i--) { //rows
for (int i2 = gfx.height - 1; i2 >= 0; i2--) { //columns
if (alpha(gfx.pixels[(gfx.width * i2) + i]) != 0) {
_bounds.xMax = i;
_coordFound = true;
break;
}
}
if (_coordFound) {
break;
}
}
//y min bounds
_coordFound = false;
for (int i = 0; i < gfx.height; i++) { //columns
for (int i2 = 0; i2 < gfx.width; i2++) { //rows
if (alpha(gfx.pixels[(gfx.width * i) + i2]) != 0) {
_bounds.yMin = i;
_coordFound = true;
break;
}
}
if (_coordFound) {
break;
}
}
//y max bounds
_coordFound = false;
for (int i = gfx.height - 1; i >= 0; i--) { //columns
for (int i2 = gfx.width -1; i2 >= 0; i2--) { //rows
if (alpha(gfx.pixels[(gfx.width * i) + i2]) != 0) {
_bounds.yMax = i;
_coordFound = true;
break;
}
}
if (_coordFound) {
break;
}
}
return _bounds;
}
void cropImage(Rect _bounds) {
PImage _temp = createImage((_bounds.xMax - _bounds.xMin) + 1, (_bounds.yMax - _bounds.yMin) + 1, ARGB);
_temp.copy(gfx, _bounds.xMin, _bounds.yMin, (_bounds.xMax - _bounds.xMin) + 1, (_bounds.yMax - _bounds.yMin)+ 1, 0, 0, _temp.width, _temp.height);
gfx = _temp; //now the image is cropped
}
Isnt there a more efficient/faster way to calculate the bounds of the image?
And i do still want the boundries coordinates afterward instead of just cutting away at the image during calculation.
If you store the last completely empty line found for e.g. the horizontal minimum and maximum scan in a variable, you can use that to constrain your vertical scanning to only the area that has not yet been checked for being empty, instead of having to scan full columns. Depending on the amount and shape of the croppable area that can save you quite a bit - See the schematic for a visual explanation of the modified algorithm:
By the way, in your //x min bounds scan you seem to be iterating over the width in both for loops, should be height in one though? (unless your images are all square of course :))
How to you get the area of a MKPolygon or MKOverlay in iOS?
I have been able to breakup the Polygon into triangles and do some math to get the area. But, doesn't work well with irregular polygons.
I was thinking about doing something like the "A more complex case" here: http://www.mathopenref.com/coordpolygonarea2.html
I was hoping there is a simpler solution with MapKit.
Thanks,
Tim
Here's the implementation I'm using.
#define kEarthRadius 6378137
#implementation MKPolygon (AreaCalculation)
- (double) area {
double area = 0;
NSMutableArray *coords = [[self coordinates] mutableCopy];
[coords addObject:[coords firstObject]];
if (coords.count > 2) {
CLLocationCoordinate2D p1, p2;
for (int i = 0; i < coords.count - 1; i++) {
p1 = [coords[i] MKCoordinateValue];
p2 = [coords[i + 1] MKCoordinateValue];
area += degreesToRadians(p2.longitude - p1.longitude) * (2 + sinf(degreesToRadians(p1.latitude)) + sinf(degreesToRadians(p2.latitude)));
}
area = - (area * kEarthRadius * kEarthRadius / 2);
}
return area;
}
- (NSArray *)coordinates {
NSMutableArray *points = [NSMutableArray arrayWithCapacity:self.pointCount];
for (int i = 0; i < self.pointCount; i++) {
MKMapPoint *point = &self.points[i];
[points addObject:[NSValue valueWithMKCoordinate:MKCoordinateForMapPoint(* point)]];
}
return points.copy;
}
double degreesToRadians(double radius) {
return radius * M_PI / 180;
}
In Swift 3:
let kEarthRadius = 6378137.0
extension MKPolygon {
func degreesToRadians(_ radius: Double) -> Double {
return radius * .pi / 180.0
}
func area() -> Double {
var area: Double = 0
var coords = self.coordinates()
coords.append(coords.first!)
if (coords.count > 2) {
var p1: CLLocationCoordinate2D, p2: CLLocationCoordinate2D
for i in 0..<coords.count-1 {
p1 = coords[i]
p2 = coords[i+1]
area += degreesToRadians(p2.longitude - p1.longitude) * (2 + sin(degreesToRadians(p1.latitude)) + sin(degreesToRadians(p2.latitude)))
}
area = abs(area * kEarthRadius * kEarthRadius / 2)
}
return area
}
func coordinates() -> [CLLocationCoordinate2D] {
var points: [CLLocationCoordinate2D] = []
for i in 0..<self.pointCount {
let point = self.points()[i]
points.append(MKCoordinateForMapPoint(point))
}
return Array(points)
}
}
I figured this out by doing a little loop through the points in the polygon. For every 3 points, I check if the center of that triangle is in the polygon. If it is continue, if not, connect the polygon so that there are no dips in the polygon. Once done, get the triangles in the polygon and do the math to get the area. Then subtract the triangles that were removed.
Hope this helps someone.