who := mark
act := $(who) say
who := alice
echo $(act)
將會是 mark say,:=這種assgn的operator,如同字面上所言簡單的擴展,他一遇到該行就直接擴展並不會去查他最後是什麼樣子,如果你想要結果是 alice say的話那麼就是要使用第二種方式。
第二種 recursive expand,是使用= 這樣的operator
who = mark
act = $(who) say
who = alice
echo $(act)
這樣一來結果就會是alice say
第三種是conditional variable assginment operator,是使用?=這樣的operator
who = mark
act = $(who) say
who ?= alice
echo $(act)
嘿嘿結果是 mark say喔~ 這個operator的作用是他會檢查該變數是否有值,有值的話就不會做assign的動作
如此這類的,但是呢! 當你要用來做這種事情的時候,請記得多加這一行 .phony: clean
會需要多加這行的原因是 make它是無法辨別target是要用來產生檔案或是純粹執行指令,所以要加.phony的宣告,讓make知道它是always out of date,舉個例子吧,如果今天你沒有加這行會發生什麼事呢?
當你同目錄下沒有檔案叫做clean的話那一切就會正常,always out of date,但~~~是~有的話呢!,此時你的target就會被認為是要產生檔案用的,由於clean的rule並沒有任何prerequisites所以always up to date,所以就不會被執行了。
def collision(self, obj):
'''
2d collision -- split in two part
first -- v parallel to the line connected the two circle center
second -- v vertical to the line connected the two circle center
inelastic case, both will has the same velocity....
v1' = (m1-m2)v1/(m1+m2) + 2 m2v2/(m1+m2)
v2' = (2m1)v1/(m1+m2) + (m2-m1)v2/(m1+m2)
'''
if self.boundCircle.isCollision(obj.boundCircle): #compare two circle
o1x, o1y = self.boundCircle.pos.point
o2x, o2y = obj.boundCircle.pos.point
p1 = Vector(o2x-o1x, o2y-o1y)
v1, v2 = self.velocity, obj.velocity
v1L, v2L = v1.length(), v2.length()
try:
rad1 = math.acos( v1.dot(p1)/ (p1.length()*v1L) )
except:
rad1 = 0
try:
rad2 = math.acos( v2.dot(-p1)/ (p1.length()*v2L) )
except:
rad2 = 0
v1 = p1.normalize()*v1L*math.cos(rad1)
v2 = -p1.normalize()*v2L*math.cos(rad2)
m1, m2 = self.mass, obj.mass
v1f = (m1-m2)*v1/(m1+m2) + 2*m2*v2/(m1+m2)
v2f = 2*m1*v1/(m1+m2) + (m2-m1)*v2/(m1+m2)
self.velocity = v1f + (self.velocity-v1)
obj.velocity = v2f + (obj.velocity-v2)
pyqt image displayer