2011年12月20日 星期二

Gestures and View Transform

To use the UIGestureRecognizer for pinch and rotate gesture,
we first create it:
// Create a rotation gesture
UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleRotateEvent:)];
[rotate setDelegate:self];
[redBox addGestureRecognizer:rotate];
Then write the handleRotateEvent: method: // Called when the rotate gesture is recognized
- (void)handleRotateEvent:(UIRotationGestureRecognizer*)rotateGesture
{
// If our gesture ended, reset the box
if([rotateGesture state] == UIGestureRecognizerStateEnded) {
[self resetBox];
}
else {
// Store the value of our rotation gesture, then
// call our central update box tranform method
// Update box transform will also apply any transforms by the pinch gesture
rotation = rotateGesture.rotation;
[self updateBoxTransform];
}
}
In the updateBoxTransform, we directly use the rotation value to view’s transform: - (void)updateBoxTransform
{
// Create a new transform based on the scale (scale determined by pinch gesture)
CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);

// Rotate the transform based on the rotation gesture value
transform = CGAffineTransformRotate(transform, rotation);
//-- contineously using the gesture's rotation
// Apply the transform to our red box
redBox.transform = transform;
}
Here we initialize a transform with Identity and scale, each time.
The following paragraph uses another approach for the rotation:


   - (void)handleRotateEvent:(UIRotationGestureRecognizer *)gestureRecognizer
{
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform =
CGAffineTransformRotate( [ [gestureRecognizer view] transform], [gestureRecognize rotation] );
[gestureRecognizer setRotation:0]; //-- reset gesture's rotation
}
}
Since the source of transform is from the view object, we have to [gestureRecognizer setRotation:0]; such that we provide a fresh rotation quantum and add to the view’s transform

2011年11月25日 星期五

Discussions about using "Singleton" and "Archiving/Unarchiving"

This is a practical situation encountered --- We want a "Singleton" object which has the ability of "Archiving/Unarchiving", should we implement these two design patterns together? There is a discussion in Stack Overflow.
My thoughts : Maybe it is unnecessary to implement them in the same class, as "wbyoung" said, two lines of code do the same work.

2011年8月8日 星期一

deleting trailing whitespace

When using git to maintain versions of XCode4 projects,  often we need to "delete trailing whitespace" before we add or commit file to the git tree. While XCode4 leaves lots of line with trailing white spaces. How to remove them?

By Bash commands :

find -E . -type f -regex ".*\.(h|m|mm)" -print0 | xargs -0 sed -i -E "s/[[:space:]]*$//"

 

 Note:

-E for find: Interpret pattern after -regex with Extended Regular Expression(ERE) syntax,  should be placed before {directory}

".*\.(h|m|mm)" : match file name with  .h, .m, .mm at the end, which is ERE syntax.

-E for sed: Interpret pattern using ERE syntax, the [:sapce:] represents the Whitespace character set: [ \t\r\n\v\f]


Thus, we can delete trailing white space with one command line in the project top directory ! Simple and clear !

2011年7月19日 星期二

The COSCUP 2011 iPhone program

緣由: 今年 COSCUP,由於智慧型手機的普遍化,增添了 App 競賽。所以就來共襄盛舉一番。

6 月 20 日:看到 COSCUP 的公告,開始熱血沸騰...可是,我不會 Java 、剛學會 Objective-C,只會寫 Hello World;如果要選比較可能做得到的平台,好像 iPhone 比較接近一些些。所以開始研讀  Cocoa 。

7 月 9 日,可以用 COSCUP API 抓到資料,用 json framework 來 parsing,感覺很幸福!

7 月 10, 11 ... 15 日,頭髮一直掉.... 媽!我錯了!但是為了自我實現的一個目標,繼續奮戰。感謝家人,同事的默默支持,也感謝 COSCUP 工作人員的協助。

這是現在完成的三個畫面。

以時間來看

以議程的類型來看

這兩種觀看的模式,可用右上角的按鈕群來互相切換。

另外,贊助廠商的導覽,可以由畫面下方的 Sponsors tab 來選擇。

因為這是一些資料的 parsing ,目的是使大家很快的找到需要的資訊,所以以極簡風格來完成使命。

第一次執行時,會從 COSCUP 網站下載資訊,之後就存在手機裡了,之後就從手機讀檔,需要 update 的話,左上角按鈕可以再從網站下載。

另外,有提供智慧型的語系選擇,例如,如果從 COSCUP 拿到了 Intel 廠商給的資訊,只有中文,那麼不論手機的語系設定如何,都會看到中文;那如果贊助廠商給的資訊有中、英文,那就會優先以手機的語系設定來顯示出贊助廠商的資訊。

 

程式碼放在 GitHub

git clone: git@github.com:tomjpsun/Coscup.git

就這樣啦!期待大家在8/20 見面啦!

 

2011年4月27日 星期三

2011年4月12日 星期二

greedy straegy abstract

為了解一個問題,把 [ Introduction to Algorithms ] 抓來亂翻了一下,
再配合交大 [ 譚老師的講義 ],把 greedy algorithm 部份研讀了一下,
大概領悟力不夠,還是不能融會貫通,只好把重點節錄起來,慢慢消化:

以下 Greedy Algorithm 以 Greedy 簡稱之
         Dynamic Algorithm 以 Dynamic 簡稱之
         Optimal Solution 以 Opt. 簡稱之

Greedy  簡單說就是:經由一連串的選擇,找出全局最佳解,每次
選擇時,是找出當時的最佳解,這種 heuristic 的方法,就稱為 Greedy.

Greedy 異於 Dynamic 的解法,不像 Dynamic 找出所有 subproblems 的解,再慢慢
用 table 記下,累積到全局:而是先把問題分成一個 greedy choice + subproblem ,
這個 greedy choice 是一個局部最佳解,並且用 recursive 方式繼續 下去解 subproblem。
最後的結果,使得 Greedy 不一定得到 Opt.,但是很快,而且結果可以接近 Opt.

很多時候,由於這種早期決定的性質,Greedy 無法找到 Opt.
當然,如果能證明,這個 greedy choice 是全局 Opt. 的一環,那麼就可以確保,一系列
的 greedy choice 可以找到全局 Opt.

下面是從 [Wiki] 節錄的,Greedy 的兩個重要成份:

Greedy choice property
    We can make whatever choice seems best at the moment and then solve
the subproblems that arise later. The choice made by a greedy algorithm
may
depend on choices made so far but not on future choices or all the
solutions to the subproblem.
It iteratively makes one greedy choice
after another, reducing each given problem into a smaller one.

In other words, a greedy algorithm never reconsiders its choices.
This is the main difference from dynamic programming, which is exhaustive
and is guaranteed to find the solution.
After every stage, dynamic programming makes decisions based on all
the decisions made in the previous stage
, and may reconsider the
previous stage's algorithmic path to solution.

Optimal substructure
    "A problem exhibits optimal substructure if an optimal solution
 to the problem contains optimal solutions to the sub-problems."

以下列出一些例子來討論:
例一   0-1 knapsack problem : 假設有 n 種礦石,以 1,2...n 代表這 n 種礦石,
第 i 種重量是 w[i] ,價值是 v[i],限定載重上限為 W 的情形下,
怎樣拿會最有價值?

例二   fractional knapsack problem : 假設有 n 種礦石粉末,以 1,2...n 代表這 n 種礦石,
第 i 種重量是 w[i] ,價值是 v[i],限定載重上限為 W 的情形下,
怎樣拿會最有價值?

這兩種問題,都有 Optimal substructure 的特性 ----- 假設最有價值的裝法 載重是 W,
則裝入礦石 j 後,對於剩下的 n-1 種礦石 ( 就是 j 已拿光後 ) 最有價值的載重
剩下 W-W[j]

fractional knapsack problem 可以用 Greedy 找到 Opt. :
因為當每次選擇 價值/重量 比最高的礦石粉 j 時,可以確定把 j 拿完,
是最好地選擇。若 j 拿完還有多餘的載重量,就選擇 價值/重量 比
次高的礦石粉,此時 所作的 greedy selection 就是符合 global Opt. 的選擇。

0-1 knapsack problem 無法用 Greedy 找到 Opt. :
反例 :考慮三種礦石,都只有一個:
 v[1]=60 ,  w[1]=10
 v[2]=100, w[2]=20
 v[3]=120, w[3]=30
 upper weight W= 50

1 的 價值/重量 比最高,選取 1 剩下可載重 40,但是選 1 不會得到 Opt.
Opt. 是選 2+3, total value =220
但是 0-1 knapsack problem 可以用 Dynamic 找到 Opt.
 
另外,有漂亮的數學證明, 符合 matroid 結構的問題,可以用 greedy 得到 Opt.
( matroid 是比較深的主題,有空再來研究吧!)
#

2011年3月28日 星期一

simple & clean daemon code

This blog is original from here: [ uCdot ]

Here the little trick is :
Use option '-D' as a 'differentiate mark' of daemon process
from the parent process. 
  
The second time it self exec(), means the daemon process
starting with -D option, which make it goes to the 'else' block :

It's a Clean and Simple example!
#