锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 綰у埆錛?鍒濈駭 钄?鏋?/font>, IBM 涓浗杞歡寮鍙戜腑蹇冭蔣浠跺伐紼嬪笀 2006 騫?2 鏈?23 鏃?/p>
鏈枃浠嬬粛浜咺BM Rational Purify鐨勫熀鏈蹇靛拰鍦ㄤ笉鍚屾搷浣滅郴緇熶腑浣跨敤Purify瀵笴/C++婧愮▼搴忎腑瀛樺湪鐨勫唴瀛橀棶棰樿繘琛屽嫎瀵熷拰鍒嗘瀽錛屽茍涓旀彁渚涗簡鏈夊叧鐨勫疄渚嬩互渚胯鑰呭湪瀹為檯鎿嶄綔涓綔涓哄弬鑰冦?/p>
鍦–/C++紼嬪簭涓紝鏈夊叧鍐呭瓨浣跨敤鐨勯棶棰樻槸鏈闅懼彂鐜板拰瑙e喅鐨勩傝繖浜涢棶棰樺彲鑳藉鑷寸▼搴忚帿鍚嶅叾濡欏湴鍋滄銆佸穿婧冿紝鎴栬呬笉鏂秷鑰楀唴瀛樼洿鑷寵祫婧愯楀敖銆傜敱浜嶤/C++璇█鏈韓鐨勭壒璐ㄥ拰鍘嗗彶鍘熷洜錛岀▼搴忓憳浣跨敤鍐呭瓨闇瑕佹敞鎰忕殑浜嬮」杈冨錛岃屼笖璇█鏈韓涔熶笉鎻愪緵綾諱技Java鐨勫瀮鍦炬竻鐞嗘満鍒躲傜紪紼嬩漢鍛樹嬌鐢ㄤ竴瀹氱殑宸ュ叿鏉ユ煡鎵懼拰璋冭瘯鍐呭瓨鐩稿叧闂鏄崄鍒嗗繀瑕佺殑銆?/p>
鎬葷殑璇存潵錛屼笌鍐呭瓨鏈夊叧鐨勯棶棰樺彲浠ュ垎鎴愪袱綾伙細鍐呭瓨璁塊棶閿欒鍜屽唴瀛樹嬌鐢ㄩ敊璇傚唴瀛樿闂敊璇寘鎷敊璇湴璇誨彇鍐呭瓨鍜岄敊璇湴鍐欏唴瀛樸傞敊璇湴璇誨彇鍐呭瓨鍙兘璁╀綘鐨勬ā鍧楄繑鍥炴剰鎯充笉鍒扮殑緇撴灉錛屼粠鑰屽鑷村悗緇殑妯″潡榪愯寮傚父銆傞敊璇湴鍐欏唴瀛樺彲鑳藉鑷寸郴緇熷穿婧冦傚唴瀛樹嬌鐢ㄦ柟闈㈢殑閿欒涓昏鏄寚鐢寵鐨勫唴瀛樻病鏈夋紜噴鏀撅紝浠庤屼嬌紼嬪簭榪愯閫愭笎鍑忔參錛岀洿鑷沖仠姝€傝繖鏂歸潰鐨勯敊璇敱浜庤〃鐜版瘮杈冩參寰堥毦琚漢宸ュ療瑙夈傜▼搴忎篃璁歌繍琛屼簡寰堜箙鎵嶄細鑰楀噣璧勬簮錛屽彂鐢熼棶棰樸?/p>
涓涓吀鍨嬬殑C++鍐呭瓨甯冨眬濡備笅鍥炬墍紺猴細 鑷簳鍚戜笂錛屽唴瀛樹腑渚濇瀛樻斁鐫鍙鐨勭▼搴忎唬鐮佸拰鏁版嵁錛屽叏灞鍙橀噺鍜岄潤鎬佸彉閲忥紝鍫嗕腑鐨勫姩鎬佺敵璇峰彉閲忓拰鍫嗘爤涓殑鑷姩鍙橀噺銆傝嚜鍔ㄥ彉閲忓氨鏄湪鍑芥暟鍐呭0鏄庣殑灞閮ㄥ彉閲忋傚綋鍑芥暟琚皟鐢ㄦ椂錛屽畠浠鍘嬪叆鏍堬紱褰撳嚱鏁拌繑鍥炴椂錛屽畠浠氨瑕佽寮瑰嚭鍫嗘爤銆傚爢鏍堢殑浣跨敤鍩烘湰涓婄敱緋葷粺鎺у埗錛岀敤鎴蜂竴鑸笉浼氱洿鎺ュ鍏惰繘琛屾帶鍒訛紝鎵浠ュ爢鏍堢殑浣跨敤榪樻槸鐩稿瀹夊叏鐨勩傚姩鎬佸唴瀛樻槸涓鏌勫弻鍒冨墤錛氬畠鍙互鎻愪緵紼嬪簭鍛樻洿鐏墊椿鐨勫唴瀛樹嬌鐢ㄦ柟娉曪紝鑰屼笖鏈変簺綆楁硶娌℃湁鍔ㄦ佸唴瀛樹細寰堥毦瀹炵幇錛涗絾鏄姩鎬佸唴瀛樺線寰鏄唴瀛橀棶棰樺瓨鍦ㄧ殑娌冨湡銆?/p>
鐩稿鐢ㄦ埛浣跨敤鐨勮璦錛屽姩鎬佸唴瀛樼殑鐢寵涓鑸敱malloc/new鏉ュ畬鎴愶紝閲婃斁鐢眆ree/delete瀹屾垚銆傚熀鏈殑鍘熷垯鍙互鎬葷粨涓猴細涓瀵逛竴錛屼笉娣風(fēng)敤銆備篃灝辨槸璇翠竴涓猰alloc蹇呴』瀵瑰簲涓涓斿敮涓鐨刦ree錛沶ew瀵瑰簲涓涓斿敮涓鐨刣elete; malloc涓嶈兘鍜宒elete, new涓嶈兘鍜宖ree瀵瑰簲銆傚彟澶栧湪C++涓娉ㄦ剰delete鍜宒elete[]鐨勫尯鍒俤elete鐢ㄦ潵閲婃斁鍗曞厓鍙橀噺錛宒elete[]鐢ㄦ潵閲婃斁鏁扮粍絳夐泦鑱氬彉閲忋傛湁鍏寵繖鏂歸潰鐨勮緇嗕俊鎭彲浠ュ弬鑰僛C++Adv]銆?/p>
鎴戜滑鍙互灝嗗唴瀛樿闂敊璇ぇ鑷村垎鎴愪互涓嬪嚑綾伙細鏁扮粍瓚婄晫璇繪垨鍐欍佽闂湭鍒濆鍖栧唴瀛樸佽闂凡緇忛噴鏀劇殑鍐呭瓨鍜岄噸澶嶉噴鏀懼唴瀛樻垨閲婃斁闈炴硶鍐呭瓨銆?/p>
涓嬮潰鐨勪唬鐮侀泦涓樉紺轟簡涓婅堪闂鐨勫吀鍨嬩緥瀛愶細 鐢變互涓婄殑紼嬪簭錛屾垜浠彲浠ョ湅鍒幫細鍦ㄧ5琛屽垎閰嶅唴瀛樻椂錛屽拷鐣ヤ簡瀛楃涓茬粓姝㈢"\0"鎵鍗犵┖闂村鑷翠簡絎?琛岀殑鏁扮粍瓚婄晫鍐欙紙Array Bounds Write錛夊拰絎?琛岀殑鏁扮粍瓚婄晫璇伙紙Array Bounds Read錛? 鍦ㄧ7琛岋紝鎵撳嵃灝氭湭璧嬪肩殑str2灝嗕駭鐢熻闂湭鍒濆鍖栧唴瀛橀敊璇紙Uninitialized Memory Read錛?鍦ㄧ11琛屼嬌鐢ㄥ凡緇忛噴鏀劇殑鍙橀噺灝嗗鑷撮噴鏀懼唴瀛樿鍜屽啓閿欒(Freed Memory Read and Freed Memory Write)錛涙渶鍚庣敱浜巗tr3鍜宻tr2鎵鎸囩殑鏄悓涓鐗囧唴瀛橈紝絎?2琛屽張涓嬈¢噴鏀句簡宸茬粡琚噴鏀劇殑絀洪棿 (Free Freed Memory)銆?/p>
榪欎釜鍖呭惈璁稿閿欒鐨勭▼搴忓彲浠ョ紪璇戣繛鎺ワ紝鑰屼笖鍙互鍦ㄥ緢澶氬鉤鍙頒笂榪愯銆備絾鏄繖浜涢敊璇氨鍍忓畾鏃剁偢寮癸紝浼氬湪鐗規(guī)畩閰嶇疆涓嬭Е鍙戯紝閫犳垚涓嶅彲棰勮鐨勯敊璇傝繖灝辨槸鍐呭瓨閿欒闅句互鍙戠幇鐨勪竴涓富瑕佸師鍥犮?/p>
鍐呭瓨浣跨敤閿欒涓昏鏄寚鍐呭瓨娉勬紡錛屼篃灝辨槸鎸囩敵璇風(fēng)殑鍔ㄦ佸唴瀛樻病鏈夎姝g‘鍦伴噴鏀撅紝鎴栬呮槸娌℃湁鎸囬拡鍙互璁塊棶榪欎簺鍐呭瓨銆傝繖浜涘皬鐨勮浜洪仐蹇樼殑鍐呭瓨鍧楀崰鎹簡涓瀹氱殑鍦板潃絀洪棿銆傚綋緋葷粺鍘嬪姏澧炲ぇ鏃訛紝榪欎簺瓚婃潵瓚婂鐨勫皬鍧楀皢鏈緇堝鑷寸郴緇熷唴瀛樿楀敖銆傚唴瀛樹嬌鐢ㄩ敊璇瘮鍐呭瓨璁塊棶閿欒鏇村姞闅句互鍙戠幇銆傝繖涓昏鏈変袱鐐瑰師鍥狅細絎竴錛屽唴瀛樹嬌鐢ㄩ敊璇槸"鎱㈡х梾"錛屽畠鐨勭棁鐘跺彲鑳戒笉浼氬湪灝戞暟銆佺煭鏃墮棿鐨勮繍琛屼腑浣撶幇錛涚浜岋紝鍐呭瓨浣跨敤閿欒鏄洜涓?涓嶅仛涓?錛堝繕璁伴噴鏀懼唴瀛橈級鑰屼笉鏄?鍋氶敊"閫犳垚鐨勩傝繖鏍風(fēng)敱浜庡拷鐣ラ犳垚鐨勯敊璇湪媯鏌ュ眬閮ㄤ唬鐮佹椂寰堥毦鍙戠幇錛屽挨鍏舵槸褰撶郴緇熺浉褰撳鏉傜殑鏃跺欍?/p>
IBM Rational PurifyPlus鏄竴緇勭▼搴忚繍琛屾椂鐨勫垎鏋愯蔣浠躲傚ス鍖呮嫭浜嗙▼搴忔ц兘鐡墮鍒嗘瀽杞歡Quantify錛?紼嬪簭瑕嗙洊闈㈠垎鏋愯蔣浠禤ureCoverage錛屽拰鏈枃鐨勪富瑙掞細紼嬪簭榪愯閿欒鍒嗘瀽杞歡Purify銆侾urify鍙互鍙戠幇紼嬪簭榪愯鏃剁殑鍐呭瓨璁塊棶錛屽唴瀛樻硠婕忓拰鍏朵粬闅句互鍙戠幇鐨勯棶棰樸?/p>
鍚屾椂濂逛篃鏄競鍦轟笂鍞竴鏀寔澶氱騫沖彴鐨勭被浼煎伐鍏鳳紝騫朵笖鍙互鍜屽緢澶氫富嫻佸紑鍙戝伐鍏烽泦鎴愩侾urify鍙互媯鏌ュ簲鐢ㄧ殑姣忎竴涓ā鍧楋紝鐢氳嚦鍙互鏌ュ嚭澶嶆潅鐨勫綰跨▼鎴栬繘紼嬪簲鐢ㄤ腑鐨勯敊璇傚彟澶栧ス涓嶄粎鍙互媯鏌/C++錛岃繕鍙互瀵笿ava鎴?NET涓殑鍐呭瓨娉勬紡闂緇欏嚭鎶ュ憡銆?/p>
紼嬪簭榪愯鏃剁殑鍒嗘瀽鍙互閲囩敤澶氱鏂規(guī)硶銆侾urify浣跨敤浜嗗叿鏈変笓鍒╃殑鐩爣浠g爜鎻掑叆鎶鏈紙OCI錛歄bject Code Insertion錛夈傚ス鍦ㄧ▼搴忕殑鐩爣浠g爜涓彃鍏ヤ簡鐗規(guī)畩鐨勬寚浠ょ敤鏉ユ鏌ュ唴瀛樼殑鐘舵佸拰浣跨敤鎯呭喌銆傝繖鏍峰仛鐨勫ソ澶勬槸涓嶉渶瑕佷慨鏀規(guī)簮浠g爜錛屽彧闇瑕侀噸鏂扮紪璇戝氨鍙互瀵圭▼搴忚繘琛屽垎鏋愩?/p>
瀵逛簬鎵鏈夌▼搴忎腑浣跨敤鐨勫姩鎬佸唴瀛橈紝Purify灝嗗畠浠寜鐓х姸鎬佽繘琛屽綊綾匯傝繖鍙互鐢變笅鍥炬潵璇存槑錛堟潵鑷猍DEV205]錛夛細 鍙傝鏈枃涓互涓婄粰鍑虹殑浠g爜錛屽湪紼嬪簭絎?琛屾墽琛屽悗錛宻tr2澶勪簬榛勮壊鐘舵併傚綋鍦ㄧ7琛岃繘琛岃鐨勬椂鍊欙紝緋葷粺灝變細鎶ュ憡涓涓闂湭鍒濆鍖栧唴瀛橀敊璇紙Uninitialized Memory Read錛夈傚洜涓哄彧鏈夊湪緇胯壊鐘舵佷笅錛屽唴瀛樻墠鍙互琚悎娉曡闂?/p>
涓轟簡媯鏌ユ暟鎹秺鐣岄敊璇紙ABR錛孉BW錛夛紝Purify榪樺湪姣忎釜鍒嗛厤鐨勫唴瀛樺墠鍚庢彃鍏ヤ簡綰㈣壊鍖哄煙銆傝繖鏍蜂竴鏉ワ紝瓚呰繃杈圭晫鐨勮闂寚浠ゅ繀瀹氳惤鍦ㄩ潪娉曞尯鍩燂紝浠庤岃Е鍙慉BR鎴栬匒BW閿欒鎶ュ憡銆傝繖閲岄渶瑕佹寚鍑轟竴鐐廣傝闂湭鍒濆鍖栧唴瀛橀敊璇疷MR鍦ㄦ煇浜涙儏鍐典笅鍏跺疄鏄悎娉曠殑鎿嶄綔錛屼緥濡傚唴瀛樻嫹璐濄傛墍浠ュ湪鍒嗘瀽鎶ュ憡鏃跺彲浠ユ妸UMR鏀懼埌鏈鍚庯紝鎴栬呭共鑴嗕粠緇撴灉涓護闄ゃ?/p>
榪欓噷綆鍗曚粙緇嶄竴涓婸urify鍦╓indows鍜孶NIX鐜涓嬬殑浣跨敤銆?/p>
鍦╓indows涓紝鍙榪愯Purify錛屽~鍏ラ渶瑕佸垎鏋愮殑紼嬪簭鍙婂弬鏁板氨鍙侾urify浼氳嚜鍔ㄦ彃鍏ユ嫻嬩唬鐮佸茍鏄劇ず鎶ュ憡銆傛姤鍛婄殑鏍煎紡濡備笅錛堟潵鑷猍DEV205]錛夛細 钃濊壊鐨勫浘鏍囦唬琛ㄤ竴浜涜繍琛岀殑淇℃伅錛屾瘮濡傚紑濮嬪拰緇撴潫絳夈傞粍鑹叉槸Purify緇欏嚭鐨勮鍛娿傞氬父UMR浼氫綔涓鴻鍛婂垪鍑恒傜孩鑹插垯浠h〃涓ラ噸鐨勯敊璇傛瘡涓縐嶇浉鍚岀殑閿欒錛屽挨鍏舵槸鍦ㄥ驚鐜腑鐨勶紝浼氳闆嗕腑鍦ㄤ竴璧鋒樉紺猴紝騫朵笖鏍囨槑鍙戠敓鐨勬鏁般傜敱姣忎釜閿欒鐨勮緇嗕俊鎭紝鐢ㄦ埛鍙互鐭ラ亾鐩稿簲鐨勫唴瀛樺湴鍧鍜屾簮浠g爜鐨勪綅緗紝騫剁洿鎺ヤ慨鏀廣傚彟澶栫敤鎴瘋繕鍙互璁劇疆涓嶅悓鐨勬護榪囧櫒錛岀敤鏉ラ殣钘忔殏鏃朵笉鍏沖績鐨勬秷鎭?/p>
鍦║NIX緋葷粺涓紝浣跨敤Purify闇瑕侀噸鏂扮紪璇戠▼搴忋傞氬父鐨勫仛娉曟槸淇敼Makefile涓殑緙栬瘧鍣ㄥ彉閲忋備笅闈㈡槸鐢ㄦ潵緙栬瘧鏈枃涓▼搴忕殑Makefile錛?/p>
棣栧厛榪愯Purify瀹夎鐩綍涓嬬殑purifyplus_setup.sh鏉ヨ緗幆澧冨彉閲忥紝鐒跺悗榪愯make閲嶆柊緙栬瘧紼嬪簭銆傞渶瑕佹寚鍑虹殑鏄紝紼嬪簭蹇呴』緙栬瘧鎴愯皟璇曠増鏈傚湪gcc涓紝涔熷氨鏄繀欏諱嬌鐢?-g"閫夐」銆傚湪閲嶆柊緙栬瘧鐨勭▼搴忚繍琛岀粨鏉熷悗錛孭urify浼氭墦鍗板嚭涓涓垎鏋愭姤鍛娿傚畠鐨勬牸寮忓拰鍚箟涓嶹indows騫沖彴澶у悓灝忓紓銆?/p>
涓嬮潰鏄湰鏂囦腑鐨勭▼搴忓湪Linux涓奝urify榪愯鐨勭粨鏋滐細 鎴戜滑瀵圭収紼嬪簭鍙互鍙戠幇Purify鏌ュ嚭浜嗙▼搴忎腑鎵鏈夌殑閿欒銆傚浜庢瘡涓敊璇紝濂逛笉浣嗙粰鍑轟簡婧愪唬鐮佺殑浣嶇疆榪樻寚鍑鴻繖浜涘唴瀛樻渶鍒濆垎閰嶇殑婧愪唬鐮佷綅緗傝繖瀵逛簬鏌ユ壘闂鎻愪緵浜嗗緢澶у府鍔┿傚浜庣▼搴?2琛岀殑瑙i噴錛孭urify灝嗗叾璁や負鏄笉鍖歸厤鐨勫唴瀛橀噴鏀撅紙FMM: Freeing mismatched memory錛夛紝鍥犱負濂硅涓鴻繖鏍風(fēng)殑閲婃斁鏂瑰紡涓嶇鍚堜弗鏍肩殑瑙勫畾銆?/p>
Purify鍦ㄥ叾鎶ュ憡鍜屾枃妗d腑浣跨敤浜嗗緢澶氱殑緙╁啓錛屽湪姝や竴騫跺垪鍑猴紝浠ヤ究璇昏呭湪浣跨敤鏃跺弬鑰冿紙鏉ヨ嚜[Purify]錛夛細 榪欓噷綆鍗曚粙緇嶄竴涓婸urify鎻愪緵鐨勫嚑涓壒鎬с傛湁鍏寵繖浜涚壒鎬х殑璇︾粏淇℃伅錛岃鏌ラ槄鏂囨。[Purify]銆?/p>
褰撲嬌鐢–/C++榪涜寮鍙戞椂錛岄噰鐢ㄨ壇濂界殑涓鑷寸殑緙栫▼瑙勮寖鏄槻姝㈠唴瀛橀棶棰樼涓閬撲篃鏄渶閲嶈鐨勬帾鏂姐傚湪姝ゅ墠鎻愪笅錛孖BM Rational Purify浣滀負涓縐嶈繍琛屾椂鍒嗘瀽杞歡鍙互寰堝ソ鍦板府鍔╂?zhèn)ㄥ彂鐜板拷鐣ョ殑鍐呭瓨闂锛屾垨鎴愪给櫴Y浠惰嚜鍔ㄦ祴璇曚腑鐨勪竴涓噸瑕佺粍鎴愰儴鍒嗐?/p>
[C++Adv] 钄℃灄錛孖BM 涓浗杞歡寮鍙戜腑蹇冭蔣浠跺伐紼嬪笀錛?004騫磋幏寰楃編鍥紹aylor University璁$畻鏈虹郴紜曞+瀛︿綅錛屽悓騫村姞鍏BM 涓浗杞歡寮鍙戜腑蹇冿紝浠庝簨Rational ClearQuest G11N鐨勫紑鍙戝伐浣溿?/strong>
鍙﹀鍒嗕韓涓灝忔娌′粈涔堢敤澶勭殑嫻嬭瘯浠g爜錛?br>
#include <string>
#include <list>
#include <algorithm>
#include <vcclr.h>
using namespace System;
int main()
{
std::list<int> lstTest;
std::copy(
std::istream_iterator<int>(std::cin),
std::istream_iterator<int>(),
std::back_insert_iterator< std::list<int> >( lstTest )
);
System::Collections::Generic::List<int>^ lstCLR = gcnew Collections::Generic::List<int>();
for( std::list<int>::const_iterator it = lstTest.begin();
it != lstTest.end();
++it )
{
lstCLR->Add( *it );
}
printf_s( "-----------------------------------------\n" );
lstCLR->Sort();
for each( int i in lstCLR )
{
Console::WriteLine( i );
}
System::Collections::Generic::List< String^ >^ lstString = gcnew Collections::Generic::List<String^>();
for( int i =0; i < 10; ++i )
{
wchar_t sz[12];
swprintf_s( sz, L"%d", i );
lstString->Add( gcnew String( sz ) );
}
std::list<std::wstring> lstStdString;
for each( String^ Str in lstString )
{
pin_ptr< const wchar_t > pStr = PtrToStringChars( Str );
lstStdString.push_back( std::wstring( pStr ) );
}
std::copy( lstStdString.begin(),
lstStdString.end(),
std::ostream_iterator< std::wstring, wchar_t >( std::wcout, L"\n" )
);
return 0;
}
榪欐墠鏄垜緇忓父媧誨姩鐨勫銆?br>
]]>
鏌忔灄鍣0(Perlin Noise)(璇?
鍘熸枃閾炬帴:http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
緲昏瘧:azure
Many people have used random number generators in their programs to create unpredictability, make the motion and behavior of objects appear more natural, or generate textures. Random number generators certainly have their uses, but at times their output can be too harsh to appear natural. This article will present a function which has a very wide range of uses, more than I can think of, but basically anywhere where you need something to look natural in origin. What's more it's output can easily be tailored to suit your needs.
寰堝浜哄湪浠栦滑鐨勭▼搴忎腑浣跨敤闅忔満鏁扮敓鎴愬櫒鍘誨垱閫犱笉鍙嫻嬶紝浣跨墿浣撶殑琛屼負鍜岃繍鍔ㄨ〃鐜扮殑鏇村姞鑷劧錛屾垨鑰呯敓鎴愮汗鐞嗐傞殢鏈烘暟鐢熸垚鍣ㄥ綋鐒舵槸鏈変粬浠殑鐢ㄩ旂殑錛屼絾鏄畠浠技涔庤繃浜庤嫑鍒匯傝繖綃囨枃绔犲皢浼氬睍紺轟竴涓敤閫斿崄鍒嗗箍娉涚殑鍔熻兘錛岀敋鑷沖叾鐢ㄩ旀瘮鎴戞兂鍒扮殑榪樿騫挎硾錛屽叾緇撴灉鍙互杞繪槗鐨勯傚悎浣犵殑闇姹傘?br>
If you look at many things in nature, you will notice that they are fractal. They have various levels of detail. A common example is the outline of a mountain range. It contains large variations in height (the mountains), medium variations (hills), small variations (boulders), tiny variations (stones) . . . you could go on. Look at almost anything: the distribution of patchy grass on a field, waves in the sea, the movements of an ant, the movement of branches of a tree, patterns in marble, winds. All these phenomena exhibit the same pattern of large and small variations. The Perlin Noise function recreates this by simply adding up noisy functions at a range of different scales.
濡傛灉浣犺瀵熻嚜鐒剁晫涓緢澶氫簨鐗╋紝浣犱細娉ㄦ剰鍒板畠浠槸鍒嗗艦鐨勩傚畠浠湁鐫寰堝灞傛緇嗚妭銆傛渶騫沖父鐨勪緥瀛愭槸灞卞嘲杞粨銆傚畠鍖呭惈鐫楂樺害涓婄殑寰堝ぇ鍙樺寲錛堝北宄幫級錛屼腑絳夊彉鍖栵紙涓橀櫟錛夛紝灝忕殑鍙樺寲錛堢牼鐭籌級錛屽井灝忓彉鍖栵紙鐭沖ご錛?..浣犲彲浠ョ戶緇兂璞°傝瀵熷嚑涔庢墍鏈変簨鐗╋細鐗囩姸鍒嗗竷浜庣敯闂磋崏錛屾搗涓殑娉㈡氮錛岃殏铓佺殑榪愬姩鏂瑰紡錛屾爲(wèi)鏋濈殑榪愬姩錛屽ぇ鐞嗙煶鐨勮姳綰癸紝椋庛傛墍鏈夎繖浜涚幇璞¤〃鐜板嚭浜嗗悓涓縐嶇殑澶у皬鐨勫彉鍖栧艦寮忋傛煆鏋楀櫔澹板嚱鏁伴氳繃鐩存帴娣誨姞涓瀹氳寖鍥村唴錛屼笉鍚屾瘮渚嬬殑鍣0鍑芥暟鏉ラ噸鐜拌繖縐嶇幇璞°?br>
To create a Perlin noise function, you will need two things, a Noise Function, and an Interpolation Function.
涓轟簡鍒涘緩涓涓煆鏋楀櫔澹板嚱鏁幫紝鎴戜滑闇瑕佷袱涓笢瑗匡紝涓涓櫔澹板嚱鏁板拰涓涓彃鍊煎嚱鏁般?br>
Introduction To Noise Functions
鍣0鍑芥暟浠嬬粛
A noise function is essentially a seeded random number generator. It takes an integer as a parameter, and returns a random number based on that parameter. If you pass it the same parameter twice, it produces the same number twice. It is very important that it behaves in this way, otherwise the Perlin function will simply produce nonsense.
涓涓櫔澹板嚱鏁板熀鏈笂鏄竴涓瀛愰殢鏈哄彂鐢熷櫒銆傚畠闇瑕佷竴涓暣鏁頒綔涓哄弬鏁幫紝鐒跺悗榪斿洖鏍規(guī)嵁榪欎釜鍙傛暟榪斿洖涓涓殢鏈烘暟銆傚鏋滀綘涓ゆ閮戒紶鍚屼竴涓弬鏁拌繘鏉ワ紝瀹冨氨浼氫駭鐢熶袱嬈$浉鍚岀殑鏁般傝繖鏉¤寰嬮潪甯擱噸瑕侊紝鍚﹀垯鏌忔灄鍑芥暟鍙槸鐢熸垚涓鍫嗗瀮鍦俱?br>
Here is a graph showing an example noise function. A random value between 0 and1 is assigned to every
point on the X axis.
榪欓噷鐨勪竴寮犲浘灞曠幇浜嗗櫔澹板嚱鏁扮殑涓涓緥瀛愩俋杞翠笂姣忎釜鐐硅璧嬩簣涓涓?鍒?涔嬮棿鐨勯殢鏈烘暟銆?br>
By smoothly interpolating between the values, we can define a continuous function that takes a non-integer as a parameter. I will discuss various ways of interpolating the values later in this article.
閫氳繃鍦ㄥ間箣闂村鉤婊戠殑鎻掑鹼紝鎴戜滑瀹氫箟浜嗕竴涓甫鏈変竴涓潪鏁村弬鏁扮殑榪炵畫鍑芥暟銆傛垜浠皢浼氬湪鍚庨潰鐨勫唴瀹逛腑璁ㄨ澶氱鎻掑兼柟寮?br>
Definitions
瀹氫箟
Before I go any further, let me define what I mean by amplitude and frequency. If you have studied physics, you may well have come across the concept of amplitude and frequency applied to a sin wave.
褰撴垜浠噯澶囨繁鍏ヤ箣鍓嶏紝璁╂垜瀹氫箟涓嬩粈涔堟槸鎸箙錛坅mplitude)鍜岄鐜囷紙frequency)銆傚鏋滀綘瀛﹁繃鐗╃悊錛屼綘鍙兘閬囧埌榪囧湪姝g巹娉腑鎸箙(amlitude)鍜岄鐜?frequency)鐨勬蹇點?br>
Sin Wave
The wavelength of a sin wave is the distance from one peak to another. The amplitude is the height of the wave. The frequency is defined to be 1/wavelength.
姝g巹娉?br>姝g巹娉㈢殑娉㈤暱(wavelength)鏄袱涓嘗宄板彧闂寸殑璺濈銆傛尟騫呮槸姝ゆ嘗鐨勯珮搴︺傞鐜囨垜浠畾涔変負 1/娉㈤暱(wavelength)銆?br>
Noise Wave
In the graph of this example noise function, the red spots indicate the random values defined along the dimension of the function. In this case, the amplitude is the difference between the minimum and maximum values the function could have. The wavelength is the distance from one red spot to the next. Again frequency is defined to be 1/wavelength.
鍣0娉?br>鍥句腑榪欎釜鍣0娉㈢殑渚嬪瓙涓紝綰㈢偣琛ㄧず瀹氫箟娌跨潃鍦ㄥ嚱鏁扮淮涓婄殑闅忔満鍊箋傚湪榪欑鎯呭喌涓嬶紝鎸箙鏄繖涓嚱鏁扮殑鏈澶у間笌鏈灝忓肩殑宸箋傛嘗闀?wavelength)鏄袱涓孩鐐逛箣闂寸殑璺濈銆傚悓鏍風(fēng)殑棰戠巼(frequency)瀹氫箟涓?/娉㈤暱(wavelength).
Creating the Perlin Noise Function
鍒涘緩鏌忔灄鍣0鍑芥暟
Now, if you take lots of such smooth functions, with various frequencies and amplitudes, you can add them all together to create a nice noisy function. This is the Perlin Noise Function.
鐜板湪錛屽鏋滀綘浣跨敤寰堝騫蟲粦鍑芥暟錛屽垎鍒嫢鏈夊悇縐嶅悇鏍風(fēng)殑棰戠巼鍜屾尟騫咃紝浣犲彲浠ユ妸浠栦滑鍙犲姞鍦ㄤ竴璧鋒潵鍒涘緩涓涓紓浜殑鍣0鍑芥暟銆傝繖涓氨鏄煆鏋楀櫔澹板嚱鏁般?br>
Take the following Noise Functions
浣跨敤浠ヤ笅鐨勫櫔澹板嚱鏁?br>
Add them together, and this is what you get.
灝嗕粬浠彔鍔犺搗鏉ワ紝浣犲皢浼氬緱鍒?-)
You can see that this function has large, medium and small variations. You may even imagine that it looks a little like a mountain range. In fact many computer generated landscapes are made using this method. Of course they use 2D noise, which I shall get onto in a moment.
浣犺兘鍙戠幇榪欎釜鍑芥暟鎷ユ湁澶х殑錛屼腑鐨勫拰灝忕殑鍙樺寲銆備綘鐢氳嚦鍙互瀹冨凡緇忔湁鐐瑰儚灞辯殑杞粨浜嗐備簨瀹炰笂寰堝鐢?shù)鑴戠敓鎴愬湴迮炴櫙瑙備篃鏄娇鐢ㄤ簡杩櫩U嶆柟娉曪紝褰撶劧閭d嬌鐢ㄧ殑鏄?D鐨勫櫔澹幫紝鎴戜滑灝嗚繃涓涓嬫潵鐮旂┒榪欎釜銆?br>
You can, of course, do the same in 2 dimensions.
浣犲綋鐒跺悓鏍風(fēng)殑鍙互鍦ㄤ簩緇翠笅涔熻繖涔堝仛銆?br>
Some noise functions are created in 2D
涓浜?D鐨勫櫔澹板嚱鏁?br>
Adding all these functions together produces a noisy pattern.
鎶婅繖浜涘嚱鏁板彔鍔犺搗鏉ヤ駭鐢熺殑鍣0鏍峰紡銆?br>
Persistence
鎸佺畫搴?br>
When you're adding together these noise functions, you may wonder exactly what amplitude and frequency to use for each one. The one dimensional example above used twice the frequency and half the amplitude for each successive noise function added. This is quite common. So common in fact, that many people don't even consider using anything else. However, you can create Perlin Noise functions with different characteristics by using other frequencies and amplitudes at each step. For example, to create smooth rolling hills, you could use Perlin noise function with large amplitudes for the low frequencies , and very small amplitudes for the higher frequencies. Or you could make a flat, but very rocky plane choosing low amplitudes for low frequencies.
褰撲綘鎶婂櫔澹板嚱鏁板彔鍔犵殑鏃跺欙紝浣犲彲鑳芥兂浜嗚В姣忔鍏蜂綋浣跨敤浜嗕粈涔堟尟騫呭拰棰戠巼銆備笂闈竴緇寸殑渚嬪瓙瀵逛簬姣忎釜榪炵畫鍙犲姞鐨勫櫔澹板嚱鏁頒嬌鐢ㄤ簡涓ゅ嶇殑棰戠巼鍜屼簩鍒嗕箣涓鍊嶇殑鎸箙銆傝繖涓お鏅氫簡錛屼簨瀹炰笂澶櫘閫氾紝浠ヨ嚦浜庡緢澶氫漢鐢氳嚦浠庢潵閮芥病鏈夎冭檻榪囦嬌鐢ㄥ叾浠栦粈涔堛傚敖綆″姝わ紝浣犲彲浠ラ氳繃鍦ㄦ瘡姝ヤ嬌鐢ㄥ叾浠栫殑棰戠巼鍜屾尟騫呮潵鍒涘緩涓嶅悓鐗瑰緛鐨勬煆鏋楀櫔澹板嚱鏁般備緥濡傦紝涓轟簡鍒涘緩涓涓鉤婊戞粴鍔ㄧ殑涓橀櫟錛屼綘鍙互浣跨敤澶х殑鎸箙鍜屽皬鐨勯鐜囩殑鏌忔灄鍣0鍑芥暟錛屽悓鏃跺皬鐨勬尟騫呭拰楂樼殑棰戠巼錛屼綘鍙互鍒涘緩涓涓鉤鍦幫紝鍙﹀瑕佸垱寤洪潪甯擱綈哥殑騫抽潰錛屽簲璇ラ夋嫨灝忕殑鎸箙鍜屼綆鐨勯鐜囥?br>
To make it simpler, and to avoid repeating the words Amplitude and Frequency all the time, a single number is used to specify the amplitude of each frequency. This value is known as Persistence. There is some ambiguity as to it's exact meaning. The term was originally coined by Mandelbrot, one of the people behind the discovery of fractals. He defined noise with a lot of high frequency as having a low persistence. My friend Matt also came up with the concept of persistence, but defined it the other way round. To be honest, I prefer Matt's definition. Sorry Mandelbrot. So our definition of persistence is this:
涓轟簡璁╄繖浜涙洿綆鍗曟槗鎳傦紝鍚屾椂涓轟簡閬垮厤閲嶅鎸箙鍜岄鐜囪繖涓や釜璇嶏紝鎴戜滑鐢ㄤ竴涓暟鏉ヨ〃紺烘瘡涓鐜囦笅鐨勬尟騫咃紝榪欎釜鏁板氨鏄寔緇害(Persistence)銆傝繖閲岀殑璇嶅拰瀹冪殑鐪熷疄鎰忎箟鏈変簺姝у紓銆傝繖涓湳璇師鏈槸Mandelbrot鎻愬嚭鐨勶紝浠栨槸鍙戠幇鍒嗗艦鐜拌薄鐨勪漢涓殑涓涓備粬瀹氫箟鍣0鎷ユ湁澶ч噺鐨勯珮棰戠巼灝嗕綋鐜板嚭浣庣殑鎸佺畫搴︺傛垜鐨勬湅鍙婱att涔熸兂鍑轟簡鎸佺畫搴︾殑姒傚康錛屼絾鏄槸閫氳繃鍙﹀涓縐嶆柟寮忓畾涔夊畠鐨勩傝瘹鐒訛紝鎴戞洿鍠滄Matt鐨勫畾涔夋柟寮忋傚涓嶈搗浜嗭紝Mandelbrot. 鎵浠ユ垜浠繖鏍峰畾涔夋寔緇害(persistence):
frequency = 2i
amplitude = persistencei
Where i is the ith noise function being added. To illustrate the effect of persistence on the output of the Perlin Noise, take a look at the diagrams below. They show the component noise functions that are added, the effect of the persistence value, and the resultant Perlin noise function.
i 鏄〃紺虹i涓鍙犲姞鐨勫櫔澹板嚱鏁般備負浜嗗睍紺烘煆鏋楀嚱鏁板湪杈撳嚭涓婃寔緇害鐨勮〃鐜版晥鏋滐紝璇風(fēng)湅涓嬩笅闈㈢殑鍥捐〃銆備粬浠睍紺轟簡鍙犲姞鐨勬瘡涓粍鎴愰儴鍒嗭紝鎸佺畫搴︾殑鏁堟灉鍜屾渶緇堢殑鏌忔灄鍑芥暟銆?br>
Octaves
鍊嶉
Each successive noise function you add is known as an octave. The reason for this is that each noise function is twice the frequency of the previous one. In music, octaves also have this property.
姣忎釜浣犳墍鍙犲姞鐨勫櫔澹板嚱鏁板氨鏄竴涓嶉銆傚洜涓烘瘡涓涓櫔澹板嚱鏁版槸涓婁竴涓殑涓ゅ嶉鐜囥傚湪闊充箰涓婏紝鍊嶉涔熸湁鐫榪欓」灞炴с?br>
Exactly how many octaves you add together is entirely up to you. You may add as many or as few as you want. However, let me give you some suggestions. If you are using the perlin noise function to render an image to the screen, there will come a point when an octave has too high a frequency to be displayable. There simply may not be enough pixels on the screen to reproduce all the little details of a very high frequency noise function. Some implementations of Perlin Noise automatically add up as many noise functions they can until the limits of the screen (or other medium) are reached.
鍏蜂綋澶氬皯鍊嶉浣犲彔鍔犲湪涓璧鳳紝榪欏畬鍏ㄥ彇鍐充簬浣犮備綘鍙互鍙犲姞寰堝涔熷彲浠ュ緢灝戙傚敖綆″姝わ紝榪樻槸璁╂垜緇欎綘涓浜涘緩璁惂銆傚鏋滀綘姝d嬌鐢ㄦ煆鏋楀櫔澹板嚱鏁板湪灞忓箷涓婃覆鏌撳浘璞$殑璇濓紝濡傛灉鍊嶉棰戠巼澶珮灝嗕細浣跨緝鎴愪竴涓偣浠ヨ嚦浜庝笉鑳芥樉紺猴紝榪欏氨鏄洜涓轟綘灞忓箷鐨勫垎杈ㄧ巼涓嶅銆備竴浜涙煆鏋楀櫔澹板嚱鏁扮殑瀹炵幇浼氳嚜鍔ㄥ彔鍔犲櫔澹板嚱鏁扮洿鍒拌揪鍒板睆騫曞垎杈ㄧ巼鐨勬瀬闄愩?br>
It is also wise to stop adding noise functions when their amplitude becomes too small to reproduce. Exactly when that happens depends on the level of persistence, the overall amplitude of the Perlin function and the bit resolution of your screen (or whatever).
褰撴尟騫呭彉鐨勫緢灝忕殑鏃跺欙紝涔熷簲璇ユ槑鏅虹殑鍋滄鍐嶅彔鍔犲櫔澹板嚱鏁般傚眾鏃跺綋鍙戠敓渚濋潬鎸佺畫搴︾殑絳夌駭錛屾煆鏋楀嚱鏁版暣浣撶殑鎸箙鍜屽睆騫曠殑鍒嗚鯨鐜囷紙緲昏瘧鐨勭儌)銆?br>
Making your noise functions
鍒涢犱綘鐨勫櫔澹板嚱鏁?
What do we look for in a noise function? Well, it's essentially a random number generator. However, unlike other random number generators you may have come across in your programs which give you a different random number every time you call them, these noise functions supply a random number calculated from one or more parameters. I.e. every time you pass the same number to the noise function, it will respond with the same number. But pass it a different number, and it will return a different number.
鎴戜滑闇瑕佷粈涔堟牱鐨勫櫔澹板嚱鏁幫紵濂斤紝鍩烘湰涓婂氨鏄竴涓殢鏈烘暟鍙戠敓鍣ㄣ傚敖綆″姝わ紝瀹冧笉鍍忎綘鍦ㄧ▼搴忎腑閬囧埌鐨勯偅涓瘡嬈¤皟鐢ㄥ畠閮借繑鍥炰笉鍚岀殑闅忔満鏁扮殑闅忔満鍑芥暟錛岃繖浜涘櫔澹板嚱鏁扮敓鎴愪竴涓殢鏈烘暟鏄氳繃涓涓垨鑰呭涓弬鏁拌綆楄屾潵銆備緥濡傦紝姣忔浣犱紶鍏ヤ竴涓浉鍚岀殑鏁板埌鍣0鍑芥暟閲岋紝瀹冨皢姣忔涔熻繑鍥炵浉鍚岀殑闅忔満鏁般備絾鏄鏋滀紶鍏ヤ竴涓笉鍚岀殑鏁幫紝閭d箞瀹冨張灝嗚繑鍥炰竴涓笉鍚岀殑鏁幫紝
Well, I don't know a lot about random number generators, so I went looking for some, and here's one I found. It seems to be pretty good. It returns floating point numbers between -1.0 and1.0.
濂斤紝鎴戝闅忔満鏁扮敓鎴愬櫒騫朵笉鎳傚お澶氾紝鎵浠ユ垜鍘繪壘浜嗕竴浜涳紝榪欓噷鎴戞壘鍒頒簡涓涓紝濂借薄寰堝ソ鐢ㄣ傚畠榪斿洖涓涓誕鐐規(guī)暟錛岃寖鍥存槸-1.0鍒?.0
function IntNoise(32-bit integer: x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end IntNoise function
Now, you'll want several different random number generators, so I suggest making several copies of the above code, but use slightly different numbers. Those big scarey looking numbers are all prime numbers, so you could just use some other prime numbers of a similar size. So, to make it easy for you to find random numbers, I have written a little program to list prime numbers for you. You can give it a start number and an end number, and it will find all the primes between the two. Source code is also included, so you can easily include it into your own programs to produce a random prime number. Primes.zip
鐜板湪錛屼綘灝嗚闇瑕佸嚑涓笉鍚岀殑闅忔満鏁扮敓鎴愬櫒錛屾墍浠ユ垜寤鴻鎶婁笂闈㈢殑浠g爜澶嶅埗鍑犱釜鎷瘋礉錛岀劧鍚庣◢寰慨鏀逛笅閲岄潰鐨勫弬鏁般傞偅浜涘彲鎬曠殑鏁板瓧閮芥槸璐ㄦ暟錛屾墍浠ヤ綘鍙互鏀規(guī)垚鍏朵粬宸笉澶氬ぇ灝忕殑璐ㄦ暟錛堣鎴戞兂璧蜂簡 hash key鐢熸垚錛夛紝涓轟簡璁╀綘杞繪澗鐨勬壘鐨勯殢鏈烘暟錛屾垜宸茬粡鍐欎簡涓涓皬紼嬪簭鏉ヤ負浣犲垪鍑鴻川鏁般備綘鍙敤杈撳叆涓涓搗濮嬪煎拰涓涓粨鏉熷鹼紝瀹冩壘鍒版墍鏈夊湪涓ゅ間箣闂寸殑璐ㄦ暟銆傛簮浠g爜涔熸彁渚涳紝鎵浠ヤ綘鍙互杞繪澗鐨勫寘鍚埌浣犺嚜宸辯殑紼嬪簭涓潵鐢熸垚闅忔満鐨勮川鏁?Primes.zip
Interpolation
鎻掑?
Having created your noise function, you will need to smooth out the values it returns. Again, you can choose any method you like, but some look better than others. A standard interpolation function takes three inputs, a and b, the values to be interpolated between, and x which takes a value between 0 and1. The Interpolation function returns a value between a and b based on the value x. When x equals 0, it returns a, and when x is 1, it returns b. When x is between 0 and1, it returns some value between a and b.
褰撳垱寤轟簡浣犵殑鍣0鍑芥暟錛屼綘灝嗛渶瑕佸鉤婊戜笅浠栫殑榪斿洖鍊箋傚啀嬈★紝浣犲彲浠ラ夋嫨浠諱綍浣犲枩嬈㈢殑鏂瑰紡錛屼絾鏄湁涓浜涙晥鏋滄洿濂姐備竴涓爣鍑嗙殑鎻掑煎嚱鏁伴渶瑕佷笁涓緭鍏ワ紝a 鍜?b, 闇瑕佸湪a鍜宐涔嬮棿榪涜鎻掑鹼紝榪樻湁x,瀹冨彇鍊艱寖鍥存槸0鍒?銆傛彃鍊煎嚱鏁拌繑鍥瀉鍒癰涔嬮棿鍙栧喅涓巟鐨勪竴涓箋傚綋x絳変簬0,瀹冭繑鍥瀉,褰搙絳変簬1鏃訛紝瀹冭繑鍥瀊銆傚綋x 鏄?鍒?涔嬮棿鏃訛紝瀹冨皢榪斿洖a鍒癰涔嬮棿鐨勬煇鍊箋?br>
Linear Interpolation:
綰挎ф彃鍊?br>
Looks awful, like those cheap 'plasmas' that everyone uses to generate landscapes. It's a simple algorithm though, and I suppose would be excusable if you were trying to do perlin noise in realtime.
鐪嬭搗鏉ュ緢榫岄緤鐨勶紝鍍忛偅浜涙瘡涓漢鐢ㄦ潵鐢熸垚鍦板艦鐨勫粔浠?plasmas'涓鏍鳳紝瀹冩槸涓涓畝鍗曠殑綆楁硶錛屽鏋滀綘鎯沖疄鏃剁殑浣跨敤鏌忔灄鍣0鍑芥暟錛岃繖縐嶆彃鍊兼柟寮忔槸涓涓夋嫨銆?br>
function Linear_Interpolate(a, b, x)
return a*(1-x) + b*x
end of function
Cosine Interpolation:
浣欑巹鎻掑?br>
This method gives a much smother curve than Linear Interpolation. It's clearly better and worth the effort if you can afford the very slight loss in speed.
榪欎釜鏂規(guī)硶綰挎ф彃鍊肩敓鎴愪簡鏇村鉤婊戠殑鏇茬嚎銆傚畠褰撶劧鏈夌潃鏇村ソ鐨勬晥鏋滐紝濡傛灉浣犳効鎰忕◢寰崯澶辯偣閫熷害鐨勮瘽銆?br>
function Cosine_Interpolate(a, b, x)
ft = x * 3.1415927
f = (1 - cos(ft)) * .5
return a*(1-f) + b*f
end of function
Cubic Interpolation:
绔嬫柟鎻掑鹼細
This method gives very smooth results indeed, but you pay for it in speed. To be quite honest, I'm not sure if it would give noticeably better results than Cosine Interpolation, but here it is anyway if you want it. It's a little more complicated, so pay attention. Whereas before, the interpolation functions took three inputs, the cubic interpolation takes five. Instead of just a and b, you now need v0, v1, v2 and v3, along with x as before.
榪欎釜鏂規(guī)硶鐨勭‘鏄敓鎴愪簡闈炲父騫蟲粦鐨勭粨鏋滐紝浣嗘槸浣犱粯鍑虹殑浠d環(huán)灝辨槸閫熷害銆傝佸疄璇達紝鎴戜笉閭d箞紜畾瀹冭兘緇欎綘姣斾綑鐜勬彃鍊煎ソ寰堝鐨勬晥鏋滐紝浣嗘槸濡傛灉浣犳棤璁哄浣曡浣跨敤瀹冪殑璇濓紝瀹冩湁涓鐐圭偣鐨勫鏉傦紝鎵浠ヨ繖閲岃娉ㄦ剰錛屼箣鍓嶏紝鎻掑煎嚱鏁板彧闇瑕佷笁涓弬鏁幫紝浣嗘槸绔嬫柟鎻掑奸渶瑕佷簲涓紝鍙栦唬浜哸鍜宐錛岀幇鍦ㄤ綘闇瑕乿0,v1,v2,v3,x鍜屼互鍓嶄竴鏍蜂篃闇瑕併?br>
榪欎簺鏄細
v0 = a 鍓嶉潰涓鐐?br>v1 = a 鐐?
v2 = b 鐐?
v3 = b 鍚庨潰涓鐐?br>
function Cubic_Interpolate(v0, v1, v2, v3,x)
P = (v3 - v2) - (v0 - v1)
Q = (v0 - v1) - P
R = v2 - v0
S = v1
return Px3 + Qx2 + Rx + S
end of function
Smoothed Noise
騫蟲粦鐨勫櫔澹?br>
Aside from Interplolation, you can also smooth the output of the noise function to make it less random looking, and also less square in the 2D and 3D versions. Smoothing is done much as you would expect, and anyone who has written an image smoothing filter, or fire algorithm should already be familiar with the process.
Rather than simply taking the value of the noise function at a single coordinate, you can take the average of that value, and it's neighbouring values. If this is unclear, take a look at the pseudo code below.
闄や簡鎻掑鹼紝浣犱篃鍙互騫蟲粦鍣0鍑芥暟鐨勮緭鍑烘潵浣垮畠鐪嬭搗鏉ヤ笉閭d箞闅忔満錛屽拰璁?D鍜?D鐨勭増鏈皯涓鐐規(guī)柟鍧椼傚鉤婊戠殑緇撴灉鍜屼綘鎵鎯崇殑宸笉澶氾紝鍙鏄啓榪囧鉤婊戣繃婊ゆ垨鑰呯伀鐒扮畻娉曠殑浜洪兘搴旇鐩稿綋鐔熸?zhèn)夋杩嚱E嬨傜浉姣斿湪涓涓崟鐙殑鍧愭爣涓婂彇寰楀櫔澹板鹼紝浣犲彲浠ュ彇騫沖潎鐨勫櫔澹板鹼紝鍜屽畠涓磋繎鐨勫箋傚鏋滀綘涓嶆竻妤氳繖涓紝鍙互鐪嬬湅涓嬮潰鐨勪吉浠g爜銆?br>
On the right, you can see a little diagram illustrating the difference between smoothed noise, and the same noise function without smoothing. You can see that the smooth noise is flatter, never reaching the extremes of unsmoothed noise, and the frequency appears to be roughly half. There is little point smoothing 1 dimensional noise, since these are really the only effects. Smoothing becomes more useful in 2 or three dimensions, where the effect is to reduce the squareness of the noise. Unfortunately it also reduces the contrast a little. The smoother you make it, obviously, the flatterthe noise will be.
鍦ㄥ彸闈紙榪欓噷鐪嬩笅闈級錛屼綘鍙互鐪嬭涓涓皬鐨勫浘灞曠ず浜嗕笉鍚屽鉤婊戝嚱鏁扮殑鍖哄埆錛屽拰鍚屾牱鐨勪竴涓櫔澹頒絾鏈繘琛屽鉤婊戝鐞嗐備綘鍙互鐪嬭騫蟲粦鍑芥暟錛屼粠鏉ラ兘娌℃湁鍒板簳閭d釜鏈鉤婊戝嚱鏁扮殑鏋侀檺鍊鹼紝騫朵笖棰戠巼鏄懼緱鍙湁澶х害涓鍗娿傞偅閲屾湁灝忕偣騫蟲粦涓緇寸殑鍣0錛屽彧鏈夎繖涓涓晥鏋溿傚鉤婊戣繃紼嬪湪浜岀淮鍜屼笁緇翠腑錛屾樉寰楁洿鏈夌敤澶勶紝閭e氨鏄畠鍑忓皯浜嗗櫔澹板ぇ鏂瑰潡銆備笉騫哥殑鏄畠涔熼檷浣庝簡涓鐐瑰姣斿害銆備綘璁╁畠瓚婂鉤婊戯紝榪欎釜鍣0灝變細瓚婂鉤鍧︺?br>
1-dimensional Smooth Noise
涓緇村櫔澹板嚱鏁?
function Noise(x)
.
.
end function
function SmoothNoise_1D(x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function
2-dimensional Smooth Noise
浜岀淮鍣0鍑芥暟
function Noise(x, y)
.
.
end function
function SmoothNoise_2D(x>, y)
corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4
return corners + sides + center
end function
Putting it all together
鎶婂畠浠粍鍚堝湪涓璧?br>
Now that you know all that, it's time to put together all you've learned and create a Perlin Noise function. Remember that it's just several Interpolated Noise functions added together. So Perlin Noise it just a function. You pass it one or more parameters, and it responds with a number. So, here's a simple 1 dimensional Perlin function.
鏃㈢劧浣犵煡閬撲簡鍏ㄩ儴榪欎簺錛岀幇鍦ㄦ槸鏃跺欐妸浠栦滑緇勫悎鍦ㄤ竴璧蜂簡錛屼綘灝嗗浼氬茍鍒涘緩涓涓煆鏋楀嚱鏁般傝浣忚繖鐭ヨ瘑鍑犱釜鎻掑肩殑鍣0鍑芥暟鍙犲姞鍦ㄤ竴璧楓傛墍浠ユ煆鏋楀嚱鏁板彧鏄竴涓嚱鏁般備綘浼犲叆涓涓垨澶氫釜鍙傛暟錛岀劧鍚庡畠榪斿洖涓涓暟緇欎綘銆傛墍浠ュ緢綆鍗曪紝涓緇寸殑鏌忔灄鍑芥暟鏄繖鏍楓?br>
The main part of the Perlin function is the loop. Each iteration of the loop adds another octave of twice the frequency. Each iteration calls a different noise function, denoted by Noisei. Now, you needn't actually write lots of noise functions, one for each octave, as the pseudo code seems to suggest. Since all the noise functions are essentially the same, except for the values of those three big prime numbers, you can keep the same code, but simply use a different set of prime numbers for each.
鏌忔灄鍑芥暟閲嶈鐨勯儴鍒嗘槸閭d釜寰幆銆傛瘡嬈″驚鐜穼浠e彔鍔犲彟涓涓袱鍊嶉鐜囩殑鍊嶉銆傛瘡嬈¤穼浠h皟鐢ㄤ竴涓笉鍚岀殑鍣0鍑芥暟錛岀О鍋歂oisei銆傚綋鐒訛紝浣犲茍涓嶉渶瑕佺湡鐨勫啓涓烘瘡涓嶉寰堝鍣0鍑芥暟錛屼吉浠g爜涓ソ璞″彧鏄緩璁繖涔堝仛銆傛棦鐒舵墍鏈夌殑鍣0鍑芥暟瀹為檯涓婇兘鏄浉鍚岀殑錛岄櫎浜嗛偅涓変釜澶ц川鏁頒笉鍚岄櫎澶栵紝浣犲彲浠ヤ嬌鐢ㄥ悓鏍風(fēng)殑浠g爜錛屽彧鏄瘡涓唬鐮佹敼鐢ㄤ笉鍚岀殑璐ㄦ暟銆?br>
1-dimensional Perlin Noise Pseudo code
涓緇存煆鏋楀櫔澹板嚱鏁頒吉浠g爜
function Noise1(integer x)
x = (x<<13) ^ x;
return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function
function SmoothedNoise_1(float x)
return Noise(x)/2 + Noise(x-1)/4 + Noise(x+1)/4
end function
function InterpolatedNoise_1(float x)
integer_X = int(x)
fractional_X = x - integer_X
v1 = SmoothedNoise1(integer_X)
v2 = SmoothedNoise1(integer_X + 1)
return Interpolate(v1 , v2 , fractional_X)
end function
function PerlinNoise_1D(float x)
total = 0
p = persistence
n = Number_Of_Octaves - 1
loop i from 0 to n
frequency = 2i
amplitude = pi
total = total + InterpolatedNoisei(x * frequency) * amplitude
end of i loop
return total
end function
Now it's easy to apply the same code to create a 2 or more dimensional Perlin Noise function:
鐜板湪鍙互杞繪澗鐨勪嬌鐢ㄥ悓鏍風(fēng)殑浠g爜鍒涘緩浜岀淮鎴栬呭緇寸殑鏌忔灄鍣0鍑芥暟浜嗭細
2-dimensional Perlin Noise Pseudocode
浜岀淮鏌忔灄鍣0鍑芥暟浼唬鐮?
function Noise1(integer x, integer y)
n = x + y * 57
n = (n<<13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 7fffffff) / 1073741824.0);
end function
function SmoothNoise_1(float x, float y)
corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16
sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8
center = Noise(x, y) / 4
return corners + sides + center
end function
function InterpolatedNoise_1(float x, float y)
integer_X = int(x)
fractional_X = x - integer_X
integer_Y = int(y)
fractional_Y = y - integer_Y
v1 = SmoothedNoise1(integer_X, integer_Y)
v2 = SmoothedNoise1(integer_X + 1, integer_Y)
v3 = SmoothedNoise1(integer_X, integer_Y + 1)
v4 = SmoothedNoise1(integer_X + 1, integer_Y + 1)
i1 = Interpolate(v1 , v2 , fractional_X)
i2 = Interpolate(v3 , v4 , fractional_X)
return Interpolate(i1 , i2 , fractional_Y)
end function
function PerlinNoise_2D(float x, float y)
total = 0
p = persistence
n = Number_Of_Octaves - 1
loop i from 0 to n
frequency = 2i
amplitude = pi
total = total + InterpolatedNoisei(x * frequency, y * frequency) * amplitude
end of i loop
return total
end function
鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛歨ttp://blog.csdn.net/anywn1314/archive/2007/10/15/1825765.aspx
]]>
鍦ㄦ闈笂鏂板緩涓涓枃鏈枃浠訛紝鍐欏叆abcd鍥涗釜瀛楁瘝錛屽彸鍑誨畠錛屽睘鎬э紝澶у皬錛?瀛楄妭錛屽崰鐢ㄧ┖闂達細4.00KB銆?br>榪欏氨鏄負浠涔堣鎵撳寘鐨勫師鍥犱箣涓銆?br>
鍙﹀浣犲彲浠ュ悓鏃跺鐞嗗ぇ鐨勬墦鍖呰繃鐨勬枃浠跺拰涓澶у爢鍑犱竾鐢氳嚦鍑犲崄涓囦釜鏂囦歡錛岄熷害浼氫笉鍚岀殑銆傚墠鑰呰蹇簺銆傚悓鏃舵墦鍖呰繕鍙互瀵規(guī)枃浠惰繘琛屽姞瀵嗐佸帇緙╃瓑絳夈?br>
鍙鎵撳寘緹庢湳璧勬簮榪樻槸寰堟湁鎰忎箟鐨勶紝鑰屼笖榪樻湁涓涓ソ澶勶紝鐪嬭搗鏉ool!涓浜涖?
]]>
]]>
Rational Purify 浣跨敤鍙婂垎鏋愬疄渚?/h1>
![]()
![]()
![]()
![]()
鏈枃浠嬬粛浜?IBM Rational Purify鐨勫熀鏈蹇靛拰鍦ㄤ笉鍚屾搷浣滅郴緇熶腑浣跨敤Purify瀵笴/C++婧愮▼搴忎腑瀛樺湪鐨勫唴瀛橀棶棰樿繘琛屽嫎瀵熷拰鍒嗘瀽錛屽茍涓旀彁渚涗簡鏈夊叧鐨勫疄渚嬩互渚胯鑰呭湪瀹為檯鎿嶄綔涓綔涓哄弬鑰冦?/blockquote>
![]()
![]()
![]()
1 #include <iostream>
2 using namespace std;
3 int main(){
4 char* str1="four";
5 char* str2=new char[4]; //not enough space
6 char* str3=str2;
7 cout<<str2<<endl; //UMR
8 strcpy(str2,str1); //ABW
9 cout<<str2<<endl; //ABR
10 delete str2;
11 str2[0]+=2; //FMR and FMW
12 delete str3; //FFM
13 }
![]()
![]()
CC=purify gcc
all: pplusdemo
pplusdemo: pplusdemo.o
$(CC) -o pplusdemo pplusdemo.o -lstdc++
pplusdemo.o: pplusdemo.cpp
$(CC) -g -c -w pplusdemo.cpp
clean:
-rm pplusdemo pplusdemo.o
**** Purify instrumented ./pplusdemo (pid 30669) ****
UMR: Uninitialized memory read:
* This is occurring while in:
strlen [rtlib.o]
std::basic_ostream< char,std::char_traits< char>> & std::operator
<<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits<
char>> &, char const *) [libstdc++.so.5]
main [pplusdemo.cpp:7]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Reading 1 byte from 0x80b45e0 in the heap.
* Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
ABW: Array bounds write:
* This is occurring while in:
strcpy [rtlib.o]
main [pplusdemo.cpp:8]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 5 bytes to 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal).
* Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
ABR: Array bounds read:
* This is occurring while in:
strlen [rtlib.o]
std::basic_ostream< char,std::char_traits< char>> & std::operator
<<<std::char_traits< char>>(std::basic_ostream< char,std::char_traits<
char>> &, char const *) [libstdc++.so.5]
main [pplusdemo.cpp:9]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Reading 5 bytes from 0x80b45e0 in the heap (1 byte at 0x80b45e4 illegal).
* Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
FMM: Freeing mismatched memory:
* This is occurring while in:
operator delete( void *) [rtlib.o]
main [pplusdemo.cpp:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Attempting to free block at 0x80b45e0 in the heap.
* Address 0x80b45e0 is at the beginning of a malloc'd block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* This block of memory was obtained using an allocation routine which is
not compatible with the routine by which it is being freed.
**** Purify instrumented ./pplusdemo (pid 30669) ****
FMR: Free memory read:
* This is occurring while in:
main [pplusdemo.cpp:11]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Reading 1 byte from 0x80b45e0 in the heap.
* Address 0x80b45e0 is at the beginning of a freed block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* There have been 0 frees since this block was freed from:
free [rtlib.o]
_ZdLpV [libstdc++.so.5]
main [pplusdemo.cpp:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
FMW: Free memory write:
* This is occurring while in:
main [pplusdemo.cpp:11]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Writing 1 byte to 0x80b45e0 in the heap.
* Address 0x80b45e0 is at the beginning of a freed block of 4 bytes.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* There have been 0 frees since this block was freed from:
free [rtlib.o]
_ZdLpV [libstdc++.so.5]
main [pplusdemo.cpp:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
FUM: Freeing unallocated memory:
* This is occurring while in:
free [rtlib.o]
_ZdLpV [libstdc++.so.5]
main [pplusdemo.cpp:12]
__libc_start_main [libc.so.6]
_start [crt1.o]
* Attempting to free block at 0x80b45e0 already freed.
* This block was allocated from:
malloc [rtlib.o]
operator new( unsigned) [libstdc++.so.5]
operator new []( unsigned) [libstdc++.so.5]
main [pplusdemo.cpp:5]
__libc_start_main [libc.so.6]
_start [crt1.o]
* There have been 1 frees since this block was freed from:
free [rtlib.o]
_ZdLpV [libstdc++.so.5]
main [pplusdemo.cpp:10]
__libc_start_main [libc.so.6]
_start [crt1.o]
**** Purify instrumented ./pplusdemo (pid 30669) ****
Current file descriptors in use: 5
FIU: file descriptor 0: <stdin>
FIU: file descriptor 1: <stdout>
FIU: file descriptor 2: <stderr>
FIU: file descriptor 26: <reserved for Purify internal use>
FIU: file descriptor 27: <reserved for Purify internal use>
**** Purify instrumented ./pplusdemo (pid 30669) ****
Purify: Searching for all memory leaks...
Memory leaked: 0 bytes (0%); potentially leaked: 0 bytes (0%)
Purify Heap Analysis (combining suppressed and unsuppressed blocks)
Blocks Bytes
Leaked 0 0
Potentially Leaked 0 0
In-Use 0 0
----------------------------------------
Total Allocated 0 0
**** Purify instrumented ./pplusdemo (pid 30669) ****
* Program exited with status code 0.
* 7 access errors, 7 total occurrences.
* 0 bytes leaked.
* 0 bytes potentially leaked.
* Basic memory usage (including Purify overhead):
290012 code
152928 data/bss
6816 heap (peak use)
7800 stack
![]()
![]()
![]()
![]()
![]()
![]()
[DEV205] Essentials of Rational PurifyPlus
[Purify] IBM Rational PurifyPlus for Linux and UNIX Documentation
![]()
![]()
]]>
]]>
銆銆鎺т歡鍦╒isual C++緙栫▼瀛︿範(fàn)涓崰鎹緢閲嶈鐨勪綅緗傜瑪鑰呭湪鍥藉鑻辨枃緗戠珯涓婄湅鍒頒簡榪欑瘒鍏充簬鏃ュ巻鎺т歡瀛︿範(fàn)鐨勬枃绔狅紝铏界劧鍐呭鐪嬩技綆鍗曪紝浣嗚瀹屽悗鎰熻鍒拌繕鏄鍒頒簡涓浜涗笢瑗褲傛劅瑙夊埌鍘熻憲浣滆呭涓浜涗笉甯哥敤鐨勬棩鍘嗘帶鍒剁殑浣跨敤鏂規(guī)硶鍐欑殑浠嬬粛鐨勫緢璇︾粏錛岄氫織鏄撴噦錛屼簬騫蟲貳涔嬩腑鏄劇濂囷紝鏄鏃ュ巻鎺т歡鐨?娣卞害鎸栨帢"錛屽VC鐨勫垵瀛﹁呭簲璇ユ槸寰堟湁甯姪鐨勶紝鎵浠ュ氨灝嗗叾緲昏瘧榪囨潵浠嬬粛緇欏浗鍐呰鑰呮湅鍙嬨?br>
銆銆涓銆佹湁鍏蟲棩鍘嗘帶浠剁殑浠嬬粛
銆銆Win32 API鎻愪緵浜嗕竴涓樉紺烘棩鏈熷緱褰撳僵鑹叉棩鍘嗘帶浠訛紝鏃ユ湡鐨勬樉紺烘ā寮忔槸鍩轟簬鎺у埗闈㈡澘涓殑鍖哄煙鎬ц緗垨鑰呰鏄緷璧栦簬鐢ㄦ埛鐨?a class=akey target=_blank>鎿嶄綔緋葷粺銆傚叿浣撶殑鏃ュ巻鎺т歡濡備笅鍥句竴鎵紺猴細

鍥句竴銆佹棩鍘嗘帶浠舵樉紺烘晥鏋?/div>
銆銆榪欎釜甯哥敤鐨勬棩鍘嗘帶浠剁殑鏍囬鏉″寘鍚袱涓寜閽拰涓や釜鏍囩錛屽乏杈圭殑鎸夐挳鍑嗚鐢ㄦ埛鍗曞嚮閫夋嫨鍓嶄竴涓湀浠斤紝宸﹁竟鐨勬爣絳炬樉紺哄綋鍓嶉夋嫨鐨勬湀浠斤紝鍙寵竟鐨勬爣絳炬樉紺哄綋鍓嶆棩鏈熶腑鐨勫勾浠姐傚彸杈圭殑鎸夐挳鏄鐢ㄦ埛閫夋嫨涓嬩竴涓湀浠姐傛棩鍘嗘帶浠跺彲浠ラ厤緗垚鏄劇ず澶氫釜鏈堜喚錛屼笅鍥炬槸涓鍏蜂綋鐨勫疄渚嬶細

鍥句簩銆佹樉紺哄涓湀浠界殑鏃ュ巻鎺т歡
銆銆濡傛灉瑕佽鏃ュ巻鎺т歡鏄劇ず澶氫釜鏈堜喚錛屾寜閽殑涓暟灝嗛氳繃鍓嶆湀鎴栧悗鏈堝垪琛ㄦ潵澧炲姞鎴栧噺灝戙備緥濡傦紝濡傛灉鎺т歡姝e湪鏄劇ず4鏈堟垨5鏈堬紝榪欐椂鐢ㄦ埛鐐瑰嚮浜嗗乏杈圭殑鎸夐挳錛屾帶浠跺皢鏄劇ず3鏈堟垨4鏈堬紱濡傛灉鐢ㄦ埛鐐瑰嚮浜嗗彸杈圭殑鎸夐挳錛屾帶浠跺皢鏄劇ず5鏈堝拰6鏈堛傛澶栵紝閫夋嫨褰撳墠騫翠喚涓殑浠繪剰涓涓湀浠斤紝鐢ㄦ埛鍙互鐐瑰嚮鏍囬妗嗕腑鐨勬湀浠藉悕錛岃繖鏃跺欏皢鏄劇ず涓涓湀浠藉垪琛ㄤ緵鐢ㄦ埛鏉ラ夋嫨銆傚叿浣撳鍥炬墍紺猴細

鍥句笁銆佹樉紺烘湀浠藉垪琛?/div>
銆銆濡傛灉瑕佹洿鏀瑰勾浠斤紝鐢ㄦ埛鍙互鐐瑰嚮騫翠喚鏍囩錛岃繖鏃跺欏皢鏄劇ず鏃嬭漿鎸夐挳錛岀敤鎴峰彲浠ラ氳繃鐐瑰嚮鏃嬭漿鎸夐挳鐨勪笂涓嬮敭鏉ユ洿鏀瑰勾浠斤紝涔熷彲浠ヤ嬌鐢?a class=akey target=_blank>閿洏涓婄殑涓婁笅綆ご鏉ユ洿鏀瑰勾浠姐?br>

鍥懼洓銆佹洿鏀規(guī)棩鍘嗘帶浠剁殑騫翠喚
鍦ㄦ爣棰樻潯鐨勪笅闈紝鏍規(guī)嵁鎺у埗闈㈡澘鐨勬牸寮忔樉紺虹潃鏄熸湡鐨勭畝鍐欙紝鍦ㄨ嫳璇湴鍖猴紝姣忎釜鏄熸湡鐨勭涓澶╅氬父鏄槦鏈熷ぉ銆傚紑鍙戜漢鍛樺彲浠ユ敼鍙樻帶浠朵腑鐨勭涓澶╄緗?br>
銆銆鎺т歡涓婏紝褰撳墠閫夋嫨鐨勬棩鏈熸湁涓鍦嗗湀銆傜敤鎴峰彲浠ョ偣鍑?yán)L閫夋嫨鐨勬棩鏈熸潵鍦ㄦ帶浠朵笂閫夋嫨涓涓棩鏈熴傚湪澶ч儴鍒嗗湴鍖猴紝鏃ユ湡浠ユ暟瀛楃殑褰㈠紡鏄劇幇鍦ㄤ竴涓櫧鑹茶儗鏅笂錛堣繖涓儗鏅鑹蹭箖鑷蟲帶浠朵笂鐨勪換浣曢鑹插彲浠ラ氳繃紼嬪簭鏉ユ敼鍙橈級銆傞粯璁ょ殑鎯呭喌涓嬶紝鎺т歡鏄劇ず涓涓き鍦嗗洿緇曠殑褰撳墠鏃ユ湡銆備嬌鐢ㄦ爣棰樻潯鎸夐挳銆佹湀浠藉拰騫翠喚鏍囩錛岀敤鎴峰彲浠ユ洿鏀規(guī)棩鏈熴傚鏋滄帶浠舵樉紺虹殑涓嶆槸褰撳墠鏃ユ湡錛岀敤鎴峰彲浠ラ氳繃鐐瑰嚮鎺т歡搴曢儴鏄劇ず浠婂ぉ鏃ユ湡鐨勬爣絳炬潵浣挎帶浠舵樉紺轟粖澶╃殑鏃ユ湡銆傦紙濡傛灉浣犳槸涓涓▼搴忓憳錛屽彲浠ラ殣钘忔帶浠跺簳閮ㄨ繖涓樉紺轟粖鏃ユ棩鏈熺殑鏍囩錛夈?
銆銆浜屻佸垱寤烘棩鍘嗘帶浠?/strong>
銆銆鎴戜滑鍙互鍦ㄧ獥鍙c佸璇濇鏋躲佸伐鍏鋒潯鍙婂叾浠栦換浣曞鍣ㄧ獥鍙d腑鍒涘緩鏃ュ巻鎺т歡銆傛棩鍘嗘帶浠跺搴旂潃CmonthCalCtrl綾伙紝鎵浠ヨ鍔ㄦ佸垱寤轟竴涓棩鍘嗘帶浠訛紝闇瑕佸0鏄庝竴涓狢monthCalCtrl鍙橀噺鎴栨寚鍚慍monthCalCtrl鐨勬寚閽堬紝浠g爜濡備笅錛?br>
// Exercise1Dlg.h : header file
class CExercise1Dlg : public CDialog
{
銆// Construction
銆public:
銆銆CExercise1Dlg(CWnd* pParent = NULL); // standard constructor
銆private:
銆銆CMonthCalCtrl *ctlCalendar;
};
銆銆CmonthCalCtrl綾昏薄MFC涓叾浠栨帶浠跺搴旂殑綾諱竴鏍鳳紝鎻愪緵浜嗕竴涓狢reate()鏂規(guī)硶鐢ㄦ潵鍦ㄥ鍣ㄧ獥鍙d腑鍔ㄦ佸垱寤烘棩鍘嗘帶浠訛紝浠g爜濡備笅錛?br>
CExercise1Dlg::CExercise1Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CExercise1Dlg::IDD, pParent)
{
銆//{{AFX_DATA_INIT(CExercise1Dlg)
銆//}}AFX_DATA_INIT
銆// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
銆m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
銆ctlCalendar = new CMonthCalCtrl;
}
/////////////////////////////////////////////////////////////////////////////
// CExercise1Dlg message handlers
BOOL CExercise1Dlg::OnInitDialog()
{
銆CDialog::OnInitDialog();
銆// Set the icon for this dialog. The framework does this automatically
銆// when the application's main window is not a dialog
銆SetIcon(m_hIcon, TRUE); // Set big icon
銆SetIcon(m_hIcon, FALSE); // Set small icon
銆// TODO: Add extra initialization here
銆ctlCalendar->Create(WS_TABSTOP | WS_CHILD | WS_VISIBLE | WS_BORDER,CPoint(20, 20), this, 0x224);
銆return TRUE; // return TRUE unless you set the focus to a control
}
涓夈佹棩鍘嗘帶浠跺睘鎬ф搷浣?br>
銆銆鍦ㄥ璇濇鎴栫獥鍙d腑鍒涘緩涓涓棩鍘嗘帶浠跺悗錛屽畠浠呮樉紺哄綋鍓嶇殑鏈堜喚騫朵粎浠呭彧鑳芥樉紺轟竴涓湀浠斤紝榪欐槸鍥犱負錛屾寜鐓ч粯璁ょ殑璁捐錛屾帶浠剁殑闀褲佸銆侀珮鍙兘瀹圭撼涓涓湀鐨勬棩鏈燂紝濡傛灉瑕佹樉紺轟袱涓湀錛屽氨瑕佸鍔犳帶浠剁殑瀹藉害錛堝悓鏍風(fēng)殑閬撶悊錛屼篃鍙互閫氳繃澧炲姞楂樺害鏉ユ樉紺轟袱涓湀浠斤級銆?
銆銆浣滀負涓涓彲瑙嗗寲瀵硅薄錛屾棩鍘嗘帶浠跺彲浠ョ敤涓嶅悓鐨勯鑹叉潵琛ㄧ幇鑳屾櫙銆佹槦鏈熸棩銆佹爣棰樻潯鏂囨湰銆佹爣棰樻潯鑳屾櫙絳夈備綔涓哄紑鍙戜漢鍛樼悊鎵褰撶劧鍦板彲浠ラ氳繃紼嬪簭鏉ユ洿鎹㈣繖浜涢鑹詫紝褰撶劧鏄鍦ㄤ笉褰卞搷鎺т歡浜插悎鍔涚殑鎯呭喌涓嬨傛敼鍙樻棩鍘嗘帶浠剁殑棰滆壊錛岄渶瑕佽皟鐢–MonthCalCtrl::SetColor() 鏂規(guī)硶錛岃鏂規(guī)硶鐨勮娉曟槸錛?br>
COLORREF SetColor(int nRegion, COLORREF ref);
銆銆榛樿鎯呭喌涓嬶紝鎺т歡鐨勬爣棰樻潯鏄劇ず钃濊壊鑳屾櫙錛屽鏋滆鏀瑰彉瀹冿紝闇瑕佸悜nRegion鍙傛暟浼犻扢CSC_TITLEBK鍊鹼紝鍚憆ef鍙傛暟浼犻掍綘鎵瑕佹樉紺虹殑棰滆壊銆傚鏋滄洿鏀規(guī)爣棰樻潯涓婃枃鏈殑棰滆壊錛岄渶瑕佸悜nRegion鍙傛暟浼犻扢CSC_TITLETEXT鍊箋?br>
![]() ![]() 鍥句簲銆佹洿鏀規(guī)帶浠剁殑鏍囬鏉¢鑹?/div> |
銆銆涓婃枃璇磋繃錛屽湪鏍囬鏉$殑涓嬫柟鏄劇ず鐫鏄熸湡鏃ワ紝鍦ㄨ嫳璇浗瀹訛紝涓涓槦鏈熺殑絎竴澶╂槸鏄熸湡澶╋紝濡傛灉浣犳兂鏇存敼涓涓槦鏈熺殑絎竴澶╋紝鍙互璋冪敤鍑芥暟SetFirstDayOfWeek()錛屽畠鐨勮娉曟槸錛?br>
| BOOL SetFirstDayOfWeek(int iDay, int* lpnOld = NULL); |
銆銆絎竴涓弬鏁板繀欏繪槸瀵瑰簲鐨勪笅鍒楁暣鏁板鹼細
| Value | Weekday |
| 0 | Monday |
| 1 | Tuesday |
| 2 | Wednesday |
| 3 | Thursday |
| 4 | Friday |
| 5 | Saturday |
| 6 | Sunday |
銆銆濡傛灉鎯寵鑾風(fēng)煡鏃ュ巻鎺т歡鐨勬槦鏈熷ぉ涓叿浣撳摢涓澶╄緗負絎竴澶╋紝鍙互璋冪敤鍑芥暟錛欸etFirstDayOfWeek()錛屽畠鐨勮娉曟槸錛?br>
| int GetFirstDayOfWeek(BOOL* pbLocal = NULL) const; |
銆銆璇ュ嚱鏁拌繑鍥炰竴涓暣鏁板鹼紝瀹冨搴旂殑鍚箟涓庝笂涓〃鏍間竴鑷淬?br>
銆銆鏄熸湡鏃ョ殑鍚嶅瓧浣跨敤鐨勯鑹蹭笌浣跨敤SetColor()鍑芥暟浼犻扢CSC_TITLETEXT鏃朵嬌鐢ㄧ殑棰滆壊涓鑷達紝鍦ㄦ槦鏈熸棩鐨勪笅闈㈡槸涓涓按騫沖垎鍓茬嚎錛岄粯璁ゆ儏鍐典笅瀹冭鏄粦鑹茬殑錛屼絾榪欓噷瀹冨嵈涓庨夋嫨鐨勬棩鏈熶竴涓鑹層傚湪鍒嗗壊綰夸笅鏄棩鏈熷垪琛紝榛樿鎯呭喌涓嬭儗鏅槸Windows榛樿鐨勭櫧鑹詫紝濡傛灉瑕佹敼鍙樺畠錛岄渶瑕佸悜nRegion鍙傛暟浼犻扢CSC_MONTHBK鍊鹼紝鍚憆ef鍙傛暟浼犻掍綘鎵瑕佹樉紺虹殑棰滆壊銆?br>
銆銆琛ㄧず鏃ユ湡鐨勬暟瀛楁樉紺烘湁涓ょ棰滆壊錛屽綋鍓嶉夋嫨鐨勬湀浠戒腑鐨勬棩鏈熶互榛戣壊琛ㄧず錛屽鏋滆鏀瑰彉榪欑棰滆壊錛屽彲浠ュ悜闇瑕佸悜nRegion鍙傛暟浼犻扢CSC_TRAILINGTEXT鍊鹼紝鍚憆ef鍙傛暟浼犻掍綘鎵瑕佹樉紺虹殑棰滆壊銆?br>
![]() ![]() 鍥懼叚銆佹洿鏀規(guī)棩鍘嗘帶浠剁殑鏃ユ湡鏄劇ず棰滆壊 |
鍒嗗壊綰夸笅鐨勬棩鏈熷垪琛ㄤ互涓ょ棰滆壊鏄劇ず錛屼負浜嗚瀹氬綋鍓嶆湀浠戒腑鏃ユ湡鐨勯鑹詫紝鍙互鍚戦渶瑕佸悜nRegion鍙傛暟浼犻扢CSC_TEXT鍊鹼紝鍚憆ef鍙傛暟浼犻掍綘鎵瑕佹樉紺虹殑棰滆壊銆?br>
![]() 鍥句竷銆佷笉鏄劇ず"浠婃棩"鏍囩鐨勬棩鍘嗘帶浠?/div> |
銆銆濡備笂鎵榪幫紝榛樿鎯呭喌涓嬫帶浠舵樉紺轟粖澶╂棩鏈燂紝鍙互閫氳繃緙栫▼浣跨敤MCS_NOTODAY鏉ラ殣钘忚繖涓爣絳撅紝浠g爜濡備笅錛?br>
| BOOL CExercise1Dlg::OnInitDialog() { 銆CDialog::OnInitDialog(); 銆// Set the icon for this dialog. The framework does this automatically 銆// when the application's main window is not a dialog 銆SetIcon(m_hIcon, TRUE); // Set big icon 銆SetIcon(m_hIcon, FALSE); // Set small icon 銆// TODO: Add extra initialization here 銆ctlCalendar->Create(WS_TABSTOP | WS_CHILD | 銆銆銆WS_VISIBLE | WS_BORDER | MCS_NOTODAY, 銆CPoint(20, 20), this, 0x224); 銆return TRUE; // return TRUE unless you set the focus to a control } |
銆銆鎴戜滑娉ㄦ剰鍒幫紝 褰撳墠鏃ユ湡榪樿涓涓き鍦嗗湀浜嗚搗鏉ワ紝濡傛灉瑕佸皢瀹冮殣钘忚搗鏉ワ紝搴旇浣跨敤MCS_NOTODAYCIRCLE綾誨瀷錛屼唬鐮佸涓嬶細
| BOOL CExercise1Dlg::OnInitDialog() { 銆CDialog::OnInitDialog(); 銆// Set the icon for this dialog. The framework does this automatically 銆// when the application's main window is not a dialog 銆SetIcon(m_hIcon, TRUE); // Set big icon 銆SetIcon(m_hIcon, FALSE); // Set small icon 銆// TODO: Add extra initialization here 銆ctlCalendar->Create(WS_TABSTOP | WS_CHILD | 銆銆銆WS_VISIBLE | WS_BORDER | 銆銆銆MCS_NOTODAYCIRCLE, 銆CPoint(20, 20), this, 0x224); 銆return TRUE; // return TRUE unless you set the focus to a control } |
銆銆涓轟簡鑾峰彇褰撳墠鏃ュ巻鎺т歡涓夋嫨鐨勬棩鏈燂紝鍙互浣跨敤鏂規(guī)硶錛欳MonthCalCtrl::GetCurSel()錛岃鏂規(guī)硶閲嶈澆鏈?涓増鏈紝瀹冧滑鏄細
| BOOL GetCurSel(COleDateTime& refDateTime) const; BOOL GetCurSel(CTime& refDateTime) const; BOOL GetCurSel(LPSYSTEMTIME pDateTime) const; |
銆銆榪欓噷鏈変竴涓緥瀛愶細
| void CExercise1Dlg::OnRetrieveBtn() { 銆// TODO: Add your control notification handler code here 銆UpdateData(); 銆CTime tme = this->m_dtpCurrent.GetCurrentTime(); 銆this->m_Result.Format("%s", tme.Format("%A, %B %d, %Y")); 銆UpdateData(FALSE); } |
涓轟簡鎺у埗鐢ㄦ埛鏄惁鍙互閫夋嫨涓や釜浠ヤ笂鐨勬棩鏈燂紝鍦ㄥ垱寤烘帶浠舵椂鍙互鐩稿簲鍦拌緗欏歸夋嫨灞炴с備緥濡傦紝濡傛灉浣犳兂璁╃敤鎴峰湪鎺т歡涓夋嫨涓瀹氳寖鍥寸殑鏃ユ湡錛屽彲浠ュ皢澶氶」閫夋嫨灞炴ц緗負鐪熴備負浜嗗姩鎬佽緗鏃ユ湡閫夋嫨錛屽簲鐢∕CS_MULTISELECT灞炴э紝浠g爜濡備笅錛?br>
| BOOL CExercise1Dlg::OnInitDialog() { 銆CDialog::OnInitDialog(); 銆// Set the icon for this dialog. The framework does this automatically 銆// when the application's main window is not a dialog 銆SetIcon(m_hIcon, TRUE); // Set big icon 銆SetIcon(m_hIcon, FALSE); // Set small icon 銆// TODO: Add extra initialization here 銆ctlCalendar->Create(WS_TABSTOP | WS_CHILD | 銆銆銆銆WS_VISIBLE | WS_BORDER | 銆銆銆銆MCS_NOTODAYCIRCLE | MCS_MULTISELECT, 銆CPoint(20, 20), this, 0x224); 銆return TRUE; // return TRUE unless you set the focus to a control } |
![]() 鍥懼叓銆佹樉紺哄閫夋嫨鏃ユ湡鐨勬棩鍘嗘帶浠?/div> |
銆銆閫氳繃灞炴ц緗紝鐢ㄦ埛鍙互鍦ㄦ棩鍘嗘帶浠朵腑閫夋嫨澶氫釜鏃ユ湡錛屽綋鐒訛紝涔熷彲浠ラ氳繃鍔ㄦ佺紪紼嬫潵閫夋嫨澶氫釜鏃ユ湡錛岃繖鏃訛紝鍙互璋冪敤CMonthCalCtrl::SetSelRange()鏂規(guī)硶錛屽畠鏈変笁涓笉鍚岀殑鐗堟湰錛岃娉曟槸錛?br>
| BOOL SetSelRange(const COleDateTime& pMinRange, const COleDateTime& pMaxRange); BOOL SetSelRange(const CTime& pMinRange, const CTime& pMaxRange); BOOL SetSelRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); |
銆銆濡傛灉鎯寵幏鍙栦竴涓棩鍘嗘帶浠剁殑鍙夋嫨鑼冨洿錛屽彲浠ヨ皟鐢–MonthCalCtrl::GetSelRange() 鏂規(guī)硶銆?br>
銆銆涓轟簡鎺у埗鐢ㄦ埛鍙夋嫨鐨勬棩鏈熻寖鍥達紝鍙互璋冪敤CMonthCalCtrl::SetRange()鏂規(guī)硶錛屽畠涔熸湁涓変腑涓嶅悓鐨勫艦寮忥紝鍒嗗埆鏄細
| BOOL SetRange(const COleDateTime* pMinRange, const COleDateTime* pMaxRange); BOOL SetRange(const CTime* pMinRange, const CTime* pMaxRange); BOOL SetRange(const LPSYSTEMTIME pMinRange, const LPSYSTEMTIME pMaxRange); |
銆銆絎竴涓弬鏁皀MinRange鏄夋嫨鑼冨洿鐨勫紑濮嬫棩鏈燂紝鍙傛暟nMaxRange鏄彲渚涢夋嫨鐨勬渶澶ф棩鏈熴?br>