1 直線の認識方法

 

 iPhoneアプリでtouch処理を使用する場合、画面上で既に表示されている物を、

   認識させる必要があります。

   種々の方法がありますが、その中で直線を認識させる方法についてです。

   直線を数式で表すと、下記の数式1)に成ります。

 

   数式1)     Y=aX+b

 

 結論から言えば、数式1)のbの値に範囲を与え、その範囲でX、Yの等式が成立

  するか判断すれば、直線の認識処理は完成です。

 

 

 上の画像の青い円の中心にある線の1点を認識しようとしています。

 

 両側の円は、該当線をtouchしたと認識させたい範囲を表し、中央の円は認識

 した位置です。

 

 

 こういった面倒な方法を行う理由ですが、上の画像のように直線式が垂直に近く

 成る程、Xの値に対するYの値の(逆も同様です)範囲が広くなり実際のtouch

 処理で正しい場所をtouchしたと認識させるのが難しくなるからです。

 

 (画像上の赤線がXの座標に対するY座標の取り得る範囲に成ります)

 

ダウンロードはこちらから


PG例
touchLine判断処理.rtf.zip
圧縮Zipフォーマット [1.9 KB]
ダウンロード

 

 (プログラム例) ダウンロードファイルと同じです

 

//

//  xxxx.h

//

//  Created by 水谷 多加志 on 11/02/13.

//  Copyright 2011. All rights reserved.

//

 

#import <UIKit/UIKit.h>

 

 

int kvStartX[10];

int kvStartY[10];

 

 

@interface xxxx : UIView {

 

}

 

@end

 

 

 

//

//  xxxx.m

//

//  Created by 水谷 多加志 on 11/02/13.

//  Copyright 2011. All rights reserved.

//

 

#import "xxx.h"

 

@implementation xxxx

 

- (id)initWithFrame:(CGRect)frame {

 

    self = [super initWithFrame:frame];

    if (self) {

        // Initialization code.

    }

    return self;

}

 

 

// Only override drawRect: if you perform custom drawing.

// An empty implementation adversely affects performance during animation.

- (void)drawRect:(CGRect)rect {

 

// コンテキストを設定

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetLineWidth(context,1.0);

// 外枠

CGContextMoveToPoint(context,108.8f,0);

CGContextAddLineToPoint(context,51.2f,1728);

CGContextStrokePath(context);

CGContextMoveToPoint(context,207.8f+58.0f,0);

CGContextAddLineToPoint(context,268.8+58.0f,1728);

CGContextStrokePath(context);

// 線分1

CGContextMoveToPoint(context,134.4f,0);

CGContextAddLineToPoint(context,83.2f,1728);

CGContextStrokePath(context);

// 線分2

CGContextMoveToPoint(context,118.2f+58.0f,0);

CGContextAddLineToPoint(context,95.6f+58.0f,1728);

CGContextStrokePath(context);

 

// 線分3

CGContextMoveToPoint(context,153.4f+58.0f,0);

CGContextAddLineToPoint(context,166.0f+58.0f,1728);

CGContextStrokePath(context);

 

// 線分4

CGContextMoveToPoint(context,185.4f+58.0f,0);

CGContextAddLineToPoint(context,236.4f+58.0f,1728);

CGContextStrokePath(context);

// touchした部分に円を描画

CGContextStrokeEllipseInRect(context, CGRectMake(kvStartX[0]+2, kvStartY[0]+2, 4, 4));

}

 

 

- (void)dealloc {

    [super dealloc];

}

 

- (void)touchesBegan:(NSSet *) touches withEvent:(UIEvent *)event {

// Mult touch

NSSet *touchCnt = [event allTouches];

int cnt = [touchCnt count];

for (int i=0; i<cnt; i++) {

// touch座標点

UITouch *touch =  [[touchCnt allObjects] objectAtIndex:i];

CGPoint touchLocation = [touch locationInView:self];

kvStartX[i] = touchLocation.x;

kvStartY[i] = touchLocation.y;

}

// touchした部分を判断

for (int i=0; i<cnt; i++) {

float wX;

float wY;

float wM1;

float wM2;

wX = (float)kvStartX[i];

wY = (float)kvStartY[i];

NSLog(@"x=%f,y=%f",wX,wY);

// 線判断

wM1 = -33.75f*wX+4136.0f;

wM2 = -33.75f*wX+4936.0f;

NSLog(@"wM1=%f",wM1);

NSLog(@"wM2=%f",wM2);

// 範囲判断

if (wY>wM1 && wY<wM2 ) {

NSLog(@"線分1OK!");

break;

}

wM1 = -90.0f*wX+13952.0f;

wM2 = -90.0f*wX+17152.0f;

NSLog(@"wM1=%f",wM1);

NSLog(@"wM2=%f",wM2);

// 範囲判断

if (wY>wM1 && wY<wM2 ) {

NSLog(@"1 OK");

break;

}

// 範囲判断

wM1 = 108.0f*wX-21064.0f;

wM2 = 108.0f*wX-23864.0f;

NSLog(@"wM1=%f",wM1);

NSLog(@"wM2=%f",wM2);

if (wY<wM1 && wY>wM2 ) {

NSLog(@"2 OK");

break;

}

wM1 = 31.8f*wX-7324.0f;

wM2 = 31.8f*wX-7924.0f;

NSLog(@"wM1=%f",wM1);

NSLog(@"wM2=%f",wM2);

if (wY<wM1 && wY>wM2 ) {

NSLog(@"3 OK");

break;

}

}

// touchした部分を描画

[self setNeedsDisplay];

 

}

 

@end