#import <vector> #import <algorithm> #define - Swift等价物</algorithm> </vector>

时间:2015-04-20 06:12:39

标签: objective-c swift

这个翻译对我来说很难。我从来没有处理#define语句,在processValue()函数中它们看起来像嵌套数组或者其他东西,但我知道如何处理它们。那么#import <vector> #import <algorithm>呢?如果我已经拥有UIKit,我可以忽略这些吗?

我决定将两个Obj-C自定义类的所有代码放在单个ViewController.swift文件中。我认识到常见的方法和属性,但除了我失去了,因为这涉及到很多数学方法。

有人可以帮我把这个烂摊子翻译成Swift吗?

//Detector.h     

#import <Foundation/Foundation.h>    
#define MAX_PERIODS_TO_STORE 20
#define AVERAGE_SIZE 20
#define INVALID_DETECT_PERIOD -1

@interface Detector : NSObject {  
float upVals[AVERAGE_SIZE];
float downVals[AVERAGE_SIZE];
int upValIndex;
int downValIndex;

float lastVal;
float periodStart;
double periods[MAX_PERIODS_TO_STORE];
double periodTimes[MAX_PERIODS_TO_STORE];

int periodIndex;
bool started;
float freq;
float average;

bool wasDown;
}

@property (nonatomic, assign) float periodStart; 


-(float) addNewValue:(float) newVal atTime:(double) time; 
-(float) getAverage; 
-(void) reset; 
@end


//Detector.m

#import <QuartzCore/QuartzCore.h>
#import "Detector.h"
#import <vector>
#import <algorithm>

#define MAX_PERIOD 1.5
#define MIN_PERIOD 0.1
#define INVALID_ENTRY -100

@implementation Detector

@synthesize periodStart;


- (id) init
{
self = [super init];
if (self != nil) {
// set everything to invalid
[self reset];
}
return self;
}

-(void) reset {
for(int i=0; i<MAX_PERIODS_TO_STORE; i++) {
    periods[i]=INVALID_ENTRY;
}
for(int i=0; i<AVERAGE_SIZE; i++) {
    upVals[i]=INVALID_ENTRY;
    downVals[i]=INVALID_ENTRY;
}   
  freq=0.5;
  periodIndex=0;
  downValIndex=0;
  upValIndex=0;
}

-(float) addNewValue:(float) newVal atTime:(double) time {
// we keep track of the number of values above and below zero
if(newVal>0) {
    upVals[upValIndex]=newVal;
    upValIndex++;
    if(upValIndex>=AVERAGE_SIZE) {
        upValIndex=0;
    }
}
if(newVal<0) {
    downVals[downValIndex]=-newVal;
    downValIndex++;
    if(downValIndex>=AVERAGE_SIZE) {
        downValIndex=0;
    }       
}
// work out the average value above zero
float count=0;
float total=0;
for(int i=0; i<AVERAGE_SIZE; i++) {
    if(upVals[i]!=INVALID_ENTRY) {
        count++;
        total+=upVals[i];
    }
}
float averageUp=total/count;
// and the average value below zero
count=0;
total=0;
for(int i=0; i<AVERAGE_SIZE; i++) {
    if(downVals[i]!=INVALID_ENTRY) {
        count++;
        total+=downVals[i];
    }
}
float averageDown=total/count;

// is the new value a down value?
if(newVal<-0.5*averageDown) {
    wasDown=true;
}

// is the new value an up value and were we previously in the down state?
if(newVal>=0.5*averageUp && wasDown) {
    wasDown=false;
// work out the difference between now and the last time this happenned
    if(time-periodStart<MAX_PERIOD && time-periodStart>MIN_PERIOD) {
        periods[periodIndex]=time-periodStart;
        periodTimes[periodIndex]=time;
        periodIndex++;
        if(periodIndex>=MAX_PERIODS_TO_STORE) {
            periodIndex=0;
        }
    }
// track when the transition happened
    periodStart=time;
} 
// return up or down
if(newVal<-0.5*averageDown) {
    return -1;
} else if(newVal>0.5*averageUp) {
    return 1;
}
return 0;
}

-(float) getAverage {
double time=CACurrentMediaTime();
double total=0;
double count=0;
for(int i=0; i<MAX_PERIODS_TO_STORE; i++) {
// only use upto 10 seconds worth of data
    if(periods[i]!=INVALID_ENTRY  && time-periodTimes[i]<10) {
        count++;
        total+=periods[i];
    }
}
// do we have enough values?
if(count>2) {
    return total/count;
}
return INVALID_DETECT_PERIOD;
}

@end


//Filter.h

#import <Foundation/Foundation.h>

#define NZEROS 10
#define NPOLES 10

@interface Filter : NSObject {    
float xv[NZEROS+1], yv[NPOLES+1];  
}

-(float) processValue:(float) value;  

@end


//Filter.m

#import "Filter.h"

#define GAIN    1.894427025e+01


@implementation Filter

-(float) processValue:(float) value {   // the function processValue that was declared in .h 
xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10]; 
xv[10] = value / GAIN;
yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10]; 
yv[10] =   (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4])
+ ( -0.0000000000 * yv[0]) + (  0.0357796363 * yv[1])
+ ( -0.1476158522 * yv[2]) + (  0.3992561394 * yv[3])
+ ( -1.1743136181 * yv[4]) + (  2.4692165842 * yv[5])
+ ( -3.3820859632 * yv[6]) + (  3.9628972812 * yv[7])
+ ( -4.3832594900 * yv[8]) + (  3.2101976096 * yv[9]);
return yv[10];
}

@end

//尝试Swift翻译

import UIKit
import Foundation
import AVFoundation


#define GAIN    1.894427025e+01
#define MAX_PERIODS_TO_STORE 20
#define AVERAGE_SIZE 20
#define INVALID_DETECT_PERIOD -1

class ViewController: UIViewController {

// Set up Camera
let session = AVCaptureSession()
// If we find a device we'll store it here for later use
var camera : AVCaptureDevice?


var detector = Detector.self
var filter = Filter.self


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}



}

class Filter: NSObject {

var xv:Float
var yv:Float

func processValue(value: Float) -> Float {
    xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10]; xv[10] = value / GAIN;
    yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10];
    yv[10] =   (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4])
    + ( -0.0000000000 * yv[0]) + (  0.0357796363 * yv[1])
    + ( -0.1476158522 * yv[2]) + (  0.3992561394 * yv[3])
    + ( -1.1743136181 * yv[4]) + (  2.4692165842 * yv[5])
    + ( -3.3820859632 * yv[6]) + (  3.9628972812 * yv[7])
    + ( -4.3832594900 * yv[8]) + (  3.2101976096 * yv[9]);
    return yv[10];
}

}

class Detector: NSObject {

var upVals: Float
var downVals: Float
var upValIndex: Int
var downValIndex: Int
var lastVal: Float
var periodStart: Float
var periods: Double
var periodTimes: Double
var periodIndex: Int
var started: Bool
var freq: Float
var average: Float
var wasDown: Bool


func reset() {
    for var i=0; i < MAX_PERIODS_TO_STORE; i++ {
        periods[i]=INVALID_ENTRY
    }
    for var i=0; i<AVERAGE_SIZE; i++ {
        upVals[i]=INVALID_ENTRY
        downVals[i]=INVALID_ENTRY
    }
    freq=0.5;
    periodIndex=0;
    downValIndex=0;
    upValIndex=0;
}

func addNewValue(newVal:Float, atTime:Double) -> Float {     // the function addNewValue that was declared in .h
// we keep track of the number of values above and below zero
if newVal > 0 {
upVals[upValIndex] = newVal
upValIndex++
if(upValIndex>=AVERAGE_SIZE) {
upValIndex = 0
}
}
if newVal < 0 {
downVals[downValIndex] =- newVal
downValIndex++
if downValIndex >= AVERAGE_SIZE {
downValIndex = 0
}
}
// work out the average value above zero
var count: Float
var total: Float
for var i=0; i < AVERAGE_SIZE; i++) {
if upVals[i]!=INVALID_ENTRY {
count++
total+=upVals[i]
}
}
var averageUp = total/count
// and the average value below zero
count=0;
total=0;
for var i=0; i < AVERAGE_SIZE; i++ {
if downVals[i]!=INVALID_ENTRY {
count++
total+=downVals[i]
}
}
var averageDown = total/count

// is the new value a down value?
if newVal < (-0.5*averageDown) {
wasDown = true
}

// is the new value an up value and were we previously in the down state?
if newVal >= (0.5*averageUp) && (wasDown) {
wasDown = false
// work out the difference between now and the last time this happenned
if time-periodStart < MAX_PERIOD && time-periodStart > MIN_PERIOD {
periods[periodIndex]=time-periodStart
periodTimes[periodIndex]=time
periodIndex++
if periodIndex >= MAX_PERIODS_TO_STORE {
            periodIndex = 0
}
}
// track when the transition happened
periodStart = time
}
// return up or down
if newVal < (-0.5*averageDown) {
return -1
} else if newVal > (0.5*averageUp) {
return 1
}
return 0
}




}

1 个答案:

答案 0 :(得分:0)

C / C ++ / Obj-C中的

#define用于创建全局常量。在Swift中,可以通过以下方式轻松翻译它们:

let GAIN = 1.894427025e+01
let AVERAGE_SIZE = 20
let INVALID_DETECT_PERIOD = -1

当然,他们不必在全局范围(或​​Swift中的模块范围)中声明。如果您不想在类或模块之间共享它们,则在类中或甚至在方法/函数内声明它们会更好。始终尽量限制范围。

宏实际上不是C / C ++ / Obj-C的一部分,宏在预处理期间被其值替换。有更好的方法可以使用const在C / C ++ / Obj-C中定义全局常量,但宏仍然被广泛使用。由于宏不是语言本身的一部分,您可以将它们放在文件中的任何位置(在首次使用之前),它们不受范围的限制。

标题<vector><algorithm>未包含在UIKit中,但是,我很确定您不需要它们,因为我看不到任何功能从您的代码中使用的那些标头。 <vector>与C ++容器类型vector(元素列表)相关。 <algorithms>与容器操作有关。我不认为Swift无论如何都会使用模板化的C ++类型。

数组的初始化在Swift和C中是不同的。在C中,数组是&#34;愚蠢的&#34;。首先声明数组,给它一个大小,然后为每个元素赋值。

float xv[NZEROS+1]

在swift中,您可以直接使用值初始化数组。

var xv = [Float](count: NZEROS + 1, repeatedValue: 0)