0

Pythonアルゴリズム(ここでは、境界ボックスに収まるように線分を拡張する)をiPhoneアプリケーションに変換しようとしていますが、startPoint.x>次にendPointxの場合にのみ機能します。

ここで何を変更しますか?理解できません..

左上から右下に線を引くとうまくいきます!しかし、右上から左下に線を引くと失敗します。ですから、それは一方向にしか機能しません。右から左への場合、いくつかの変数を変更する必要があると思います。

MINは(0,0)で、MAXはデバイスによって異なりますが、iPhone Retinaの場合(300,568)

    - (NSMutableArray *) extendAlgorithm:(CGPoint)start withEnd:(CGPoint)end withBorderMin:(CGPoint)min andBorderMax:(CGPoint)max {

    int x1 = (int) start.x;     int y1 = (int) start.y;
    int x2 = (int) end.x;       int y2 = (int) end.y;
    int xmin = (int) min.x;     int ymin = (int) min.y;
    int xmax = (int) max.x;     int ymax = (int) max.y;

    if(y1 == y2) {
        return [[NSMutableArray alloc] initWithObjects:
                [NSNumber numberWithDouble:xmin],
                [NSNumber numberWithDouble:y1],
                [NSNumber numberWithDouble:xmax],
                [NSNumber numberWithDouble:y1],
                nil];
    }

    if(x1 == x2) {
        return [[NSMutableArray alloc] initWithObjects:
                [NSNumber numberWithDouble:x1],
                [NSNumber numberWithDouble:ymin],
                [NSNumber numberWithDouble:x1],
                [NSNumber numberWithDouble:ymax],
                nil];
    }

    double y_for_xmin = y1 + (y2 - y1) * (xmin - x1) / (x2 - x1);
    double y_for_xmax = y1 + (y2 - y1) * (xmax - x1) / (x2 - x1);

    double x_for_ymin = x1  + (x2 - x1) * (ymin - y1) / (y2 - y1);
    double x_for_ymax = x1  + (x2 - x1) * (ymax - y1) / (y2 - y1);

    if(ymin <= y_for_xmin <= ymax) {

        if(xmin <= x_for_ymax <= xmax) {
            return [[NSMutableArray alloc] initWithObjects:
                    [NSNumber numberWithDouble:xmin],
                    [NSNumber numberWithDouble:y_for_xmin],
                    [NSNumber numberWithDouble:x_for_ymax],
                    [NSNumber numberWithDouble:ymax],
                    nil];
        }

        if(xmin <= x_for_ymin <= xmax) {
            return [[NSMutableArray alloc] initWithObjects:
                    [NSNumber numberWithDouble:xmin],
                    [NSNumber numberWithDouble:y_for_xmin],
                    [NSNumber numberWithDouble:x_for_ymin],
                    [NSNumber numberWithDouble:ymin],
                    nil];
        }
    }

    if(ymin <= y_for_xmax <= ymax) {

        if(xmin <= x_for_ymin <= xmax) {
            return [[NSMutableArray alloc] initWithObjects:
                    [NSNumber numberWithDouble:x_for_ymin],
                    [NSNumber numberWithDouble:ymin],
                    [NSNumber numberWithDouble:xmax],
                    [NSNumber numberWithDouble:y_for_xmax],
                    nil];
        }

        if(xmin <= x_for_ymax <= xmax) {
            return [[NSMutableArray alloc] initWithObjects:
                    [NSNumber numberWithDouble:x_for_ymax],
                    [NSNumber numberWithDouble:ymax],
                    [NSNumber numberWithDouble:xmax],
                    [NSNumber numberWithDouble:y_for_xmax],
                    nil];
        }
    }

    return nil;
}
4

2 に答える 2

1
if (ymin <= y_for_xmin <= ymax)

あなたが期待することをしません(おそらくPythonでは、しかし間違いなくCではそうではありません)、あなたはこれを次のように書く必要があります

if (ymin <= y_for_xmin && y_for_xmin <= ymax)

あなたのアルゴリズムがすべてのケースをカバーしているかどうかわからないので、私は独立してアルゴリズムを見つけようとしました。これは私が得たものです:

- (NSArray *) extendAlgorithm:(CGPoint)start withEnd:(CGPoint)end withBorderMin:(CGPoint)min andBorderMax:(CGPoint)max
{
    CGFloat u1 = MAXFLOAT;
    CGFloat u2 = -MAXFLOAT;
    CGFloat tmp;
    if (end.x != start.x) {
        tmp = (max.x - start.x)/(end.x - start.x);
        if (tmp > 0 && tmp < u1)
            u1 = tmp;
        else if (tmp < 0 && tmp > u2)
            u2 = tmp;
        tmp = (min.x - start.x)/(end.x - start.x);
        if (tmp > 0 && tmp < u1)
            u1 = tmp;
        else if (tmp < 0 && tmp > u2)
            u2 = tmp;
    }
    if (end.y != start.y) {
        tmp = (max.y - start.y)/(end.y - start.y);
        if (tmp > 0 && tmp < u1)
            u1 = tmp;
        else if (tmp < 0 && tmp > u2)
            u2 = tmp;
        tmp = (min.y - start.y)/(end.y - start.y);
        if (tmp > 0 && tmp < u1)
            u1 = tmp;
        else if (tmp < 0 && tmp > u2)
            u2 = tmp;
    }
    CGPoint newStart, newEnd;
    newStart.x = start.x + u2 * (end.x - start.x);
    newStart.y = start.y + u2 * (end.y - start.y);
    newEnd.x = start.x + u1 * (end.x - start.x);
    newEnd.y = start.y + u1 * (end.y - start.y);
    NSLog(@"%@, %@", NSStringFromCGPoint(newStart), NSStringFromCGPoint(newEnd));

    return [[NSArray alloc] initWithObjects:
            [NSNumber numberWithDouble:newStart.x],
            [NSNumber numberWithDouble:newStart.y],
            [NSNumber numberWithDouble:newEnd.x],
            [NSNumber numberWithDouble:newEnd.y],
            nil];
}

(アイデアは、ラインを考慮することです

(x, y) = (start.x, start.y) + u * (end.x - start.x, end.y - start.y)

次に、線が境界を横切るパラメータを決定しますu1。 )u2

于 2013-03-26T18:04:21.190 に答える
0

アルゴリズムについては何もチェックしていませんが、飛び出すのは次の行です。

double y_for_xmin = y1 + (y2 - y1) * (xmin - x1) / (x2 - x1);
// ...

その式の終わりは整数除算です(xmin、x1、x2などをintにキャストします)。それらは整数の結果になり、切り捨てられます。したがって、1/2 == 0.5のようなものを期待している場合は、そこで(int)0に驚かれることでしょう。

スタック変数をCGFloatとして宣言してみてください。これは、CGPoint構造体での方法です。

于 2013-03-26T17:36:37.527 に答える