Использование функции C в Objective-C (для iPhone) - PullRequest
3 голосов
/ 03 февраля 2010

вот и все. Я сам по себе признанный новичок в программировании для iPhone (с гораздо более длительным опытом работы в Perl и в Интернете - 30 лет) ... но на прошлой неделе сделал решающий шаг и купил пару хороших книг. Прочитав и прочитав более 1000 страниц - и прекрасно понимая это, я уже на пути к хорошему первому приложению для Native iPhone. Моя проблема заключается в следующем: я не знаю, как выполнить простую процедуру Geographic (lat / long) точка-полигон в Objective-C. У меня есть 2 способа сделать это. Один в C (первый пример кода) и один в JavaScript (второй пример кода):

// this is the poly.h file

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy);


// this is the poly.c file

#include "poly.h"
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy){
 int i, j, c = 0;
 for (i = 0, j = nvert-1; i < nvert; j = i++) {
 if ( ((verty[i]>testy) != (verty[j]>testy)) &&
  (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
    c = !c;
 }
 return c;
}

или это (в Javascript):

function _isPointInPoly(poly, pt){
 for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
  ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
  && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
  && (c = !c);
 return c;
}

(любой из них будет работать, если я смогу их преобразовать)

Итак, чтобы попробовать это ... Я поместил .h файл и .c файл в xcode с моим проектом iPhone. Единственный вопрос сейчас заключается в том, как вызвать это из Objective-C и получить результат ..:)

Кстати: всю прошлую ночь я искал Великого Бога в Google, чтобы получить ответ на этот вопрос, но просто ПОПРОБОВАТЬ, чтобы найти «включая C в приложении Objective-C для iPhone» и т. Д. делать с этим! :) Просто сообщаю, что я попробовал Google, прежде чем писать здесь.

Хорошо, мои проблемы:

  1. Как мне вызвать pnpoly из Objective-C?
  2. Какими типами я его называю? (Int хорошо, но поплавок * vertx - это, очевидно, массив чисел с плавающей запятой, которых NSArray не - что я могу найти)

(РЕДАКТИРОВАТЬ: ЗДЕСЬ БОЛЬШЕ ИНФОРМАЦИИ. Я прошу о помощи в построении массивов, которые будут переданы как хорошо)

Вопрос задан не полностью.

Процедура (в объективе-c) будет выглядеть следующим образом: (при условии, что это закодировано правильно)

NSMutableArray *latitudeArray = [[NSMutableArray alloc] init];
NSMutableArray *longitudeArray = [[NSMutableArray alloc] init];

// coordinates surrounding 1 inifite loop.

[latitudeArray addObject:@"37.32812557141369"];
[longitudeArray addObject:@"-122.0320253896318"];
[latitudeArray addObject:@"37.32821852349916"];
[longitudeArray addObject:@"-122.0289014325174"];
[latitudeArray addObject:@"37.33021046381746"];
[longitudeArray addObject:@"-122.0289300638158"];
[latitudeArray addObject:@"37.33042111092124"];
[longitudeArray addObject:@"-122.0279574092159"];
[latitudeArray addObject:@"37.33395972491337"];
[longitudeArray addObject:@"-122.0279263955651"];
[latitudeArray addObject:@"37.33363270879559"];
[longitudeArray addObject:@"-122.0320527775551"];
[latitudeArray addObject:@"37.32812557141369"];
[longitudeArray addObject:@"-122.0320253896318"];


int nvert = [[latitudeArray count] intvalue];

// 37.33189399206268 x -122.0296274412866 should return true

float testx =37.33189399206268;
float testy =-122.0296274412866;

int y_or_n = pnpoly(int nvert, float *vertx, float *verty, float testx, float testy);

Мне следовало дать понять, что я изучаю Objective-c, но НАЙДЕЛ эту подпрограмму C - поэтому не был уверен, как создать переменные C для вызова или подпрограммы для вызова.

Я знаю, что это требует много ... но это действительно озадачивает меня. Может кто-нибудь мне помочь? Большое спасибо.

Янн

Ответы [ 3 ]

7 голосов
/ 03 февраля 2010

Вы можете просто позвонить. Objective-C - это просто интерфейс для API C и способ переписывания методов в виде функций (в некотором приближении, во всяком случае ...), так что вы можете вызывать функцию C так же, как в коде C.

- (int)doWhatever {
  // ...
  int hitTest = pnPoly(/*blah*/);
  return hitTest;
}

Вы можете без проблем использовать примитивные типы C, такие как int и float, в Objective-C. Так что вызывайте функцию с плавающей точкой :). Если вам нужно хранить такие значения в классах коллекции Foundation, таких как NSArray, вы можете заключить их в класс с именем NSNumber.

NSNumber *someFloat = [NSNumber numberWithFloat: f];
float usefulValue = [someFloat floatValue];
3 голосов
/ 04 февраля 2010

Вот пример того, как это будет использоваться:

int nCoords = 4;
float vertexXCoords[n] = {0.0, 0.0, 20.0, 20.0};
float vertexYCoords[n] = {0.0, 20.0, 20.0, 0.0};
NSPoint testPoint = NSMakePoint(5, 10);

BOOL testPointIsInPoly = pnpoly(nCoords, xCoords, yCoords, testPoint.x, testPoint.y);

Обратите внимание, что здесь нет ничего специфического для Objective-C.Это код C (хотя он использует типы C Cocoa BOOL и NSPoint).Поскольку Objective-C является строгим надмножеством C, любой допустимый код C также является допустимым Objective-C.Это также тот случай, когда уникальные возможности Objective-C не будут особенно полезны.(Численные расчеты в целом менее сложны и более читабельны на простом языке C).

1 голос
/ 03 февраля 2010

target C - это расширенный набор C, поэтому вы можете вызывать процедуры на C. Если вы часто вызываете эту процедуру, вставьте ее или сделайте макрос.

...