<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-445657837784490287</id><updated>2011-07-11T01:02:08.831+02:00</updated><category term='Xcode'/><category term='mouse events'/><category term='tablet'/><category term='B-Spline'/><category term='Custom View'/><category term='Painter'/><category term='Bezier'/><category term='CocoaCast'/><category term='NSResponder'/><category term='Apple'/><category term='Key-Value'/><category term='keyboard events'/><category term='Cocoa Dev Central'/><category term='Test'/><category term='Web'/><category term='Photoshop'/><category term='Cubic'/><category term='Derivatives'/><category term='mouse'/><category term='ADC'/><category term='Spline'/><category term='event handling'/><category term='Objective-C'/><category term='Cocoa'/><category term='FreeHand'/><category term='Inkscape'/><category term='NSView'/><category term='Integrals'/><category term='Apple Development Connection'/><category term='Interface Builder'/><category term='Illustrator'/><category term='Interpolation'/><category term='OpenGL'/><category term='AppKit'/><category term='Quartz'/><title type='text'>iLearn Cocoa</title><subtitle type='html'>This is my attempt to learn Cocoa and develop a simple paint application to be used with a Wacom tablet.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>8</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-985506656426472711</id><published>2009-09-07T20:06:00.041+02:00</published><updated>2009-09-08T05:07:53.268+02:00</updated><title type='text'>8. XML parsing</title><content type='html'>While Cocoa has a NSXML class for tree based parsing of XML documents; Cocoa Touch, on iPhone, has only the event driven counterpart NSXMLParser. Therefore there are only two possible solution for XML parsing on iPhone: using NSXMLParser or libxml2.&lt;br /&gt;&lt;br /&gt;I am going to discuss the first one: NSXMLParser.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Event driven XML parsing using NSXMLParser&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;To parse a XML document with NSXMLParser we need to:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;To get the URL of the XML file.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To initialize a NSXMLParser instance using the URL.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To start the parser.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To implement some of the methods declared by the NSXMLParserDelegateEventAdditions category of the NSObject class.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;To set the instance of the class, that implements NSXMLParserDelegateEventAdditions category, as the delegate of the NSXMLParser instance.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Two of the methods, that every program will probably implement, are written in the following code.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;- (&lt;span class="keyword"&gt;void&lt;/span&gt;) parser:(&lt;span class="sysClass"&gt;NSXMLParser&lt;/span&gt; *)parser &lt;br /&gt;didStartElement:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)elementName &lt;br /&gt;   namespaceURI:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)namespaceURI &lt;br /&gt;  qualifiedName:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)qName &lt;br /&gt;     attributes:(&lt;span class="sysClass"&gt;NSDictionary&lt;/span&gt; *)attributeDict &lt;br /&gt;{&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (&lt;span class="keyword"&gt;void&lt;/span&gt;) parser:(&lt;span class="sysClass"&gt;NSXMLParser&lt;/span&gt; *)parser &lt;br /&gt;  didEndElement:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)elementName &lt;br /&gt;   namespaceURI:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)namespaceURI &lt;br /&gt;  qualifiedName:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)qName &lt;br /&gt;{&lt;br /&gt;    &lt;br /&gt;}&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;NSXMLParser is a SAX like parser. Therefore it is not aware of the XML hierarchy. It simply parse all the XML elements as a plain sequence. To get a tree hierarchy, that matches XML document hieararchy, using the NSXMLParser we have to provide our own code.&lt;br /&gt;&lt;br /&gt;To create an object hierarchy that matches XML one, first of all, we have to implement a class that supports a tree graph based hierarchy. A tipical example is a node based architecture.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;span class="keyword"&gt;@interface&lt;/span&gt; MyNode : NSObject {&lt;br /&gt;    &lt;span class="keyword"&gt;@public&lt;/span&gt;&lt;br /&gt;    &lt;span class="sysClass"&gt;NSString&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_name&lt;/span&gt;;&lt;br /&gt;    &lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_parent&lt;/span&gt;;&lt;br /&gt;    &lt;span class="sysClass"&gt;NSMutableArray&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_children&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span class="keyword"&gt;@end&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;For this class we should also declare and define some accessor methods (I don't like properties of Objective-C 2.0) like the methods to access the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_name&lt;/span&gt; field and the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_parent&lt;/span&gt; field.&lt;br /&gt;Therefore we can declare the needed methods.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;span class="keyword"&gt;@interface&lt;/span&gt; MyNode : NSObject {&lt;br /&gt;    &lt;span class="keyword"&gt;@public&lt;/span&gt;&lt;br /&gt;    &lt;span class="sysClass"&gt;NSString&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_name&lt;/span&gt;;&lt;br /&gt;    &lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_parent&lt;/span&gt;;&lt;br /&gt;    &lt;span class="sysClass"&gt;NSMutableArray&lt;/span&gt; * &lt;span class="myIdentifier"&gt;_children&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;- (&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *) name;&lt;br /&gt;- (&lt;span class="keyword"&gt;void&lt;/span&gt;) setName:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)name;&lt;br /&gt;- (&lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; *) parent;&lt;br /&gt;- (&lt;span class="keyword"&gt;void&lt;/span&gt;) setParent:(&lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; *)parent;&lt;br /&gt;&lt;span class="keyword"&gt;@end&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And then define them.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;&lt;span class="keyword"&gt;@implementation&lt;/span&gt;&lt;br /&gt;&lt;span class="macro"&gt;#pragma mark ACCESSORS&lt;/span&gt;&lt;br /&gt;&lt;span class="comment"&gt;/* _name */&lt;/span&gt;&lt;br /&gt;- (&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *) name {&lt;br /&gt;    return &lt;span class="myIdentifier"&gt;_name&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) setName:(&lt;span class="sysClass"&gt;NSString&lt;/span&gt; *)name {&lt;br /&gt;    if (&lt;span class="myIdentifier"&gt;_name&lt;/span&gt; != name) {&lt;br /&gt;        [&lt;span class="myIdentifier"&gt;_name&lt;/span&gt; &lt;span class="sysMethod"&gt;release&lt;/span&gt;];&lt;br /&gt;        &lt;span class="myIdentifier"&gt;_name&lt;/span&gt; = [name &lt;span class="sysMethod"&gt;retain&lt;/span&gt;];&lt;br /&gt;    }&lt;br /&gt;}&lt;span class="comment"&gt; /* END _name */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment"&gt;/* _parent */&lt;/span&gt;&lt;br /&gt;- (&lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; *) parent {&lt;br /&gt;    return &lt;span class="myIdentifier"&gt;_parent&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (void) setParent:(&lt;span class="myIdentifier"&gt;MyNode&lt;/span&gt; *)parent {&lt;br /&gt;    if (&lt;span class="myIdentifier"&gt;_parent&lt;/span&gt; != parent) {&lt;br /&gt;        [&lt;span class="myIdentifier"&gt;_parent&lt;/span&gt; &lt;span class="sysMethod"&gt;release&lt;/span&gt;];&lt;br /&gt;        &lt;span class="myIdentifier"&gt;_parent&lt;/span&gt; = [parent &lt;span class="sysMethod"&gt;retain&lt;/span&gt;];&lt;br /&gt;    }&lt;br /&gt;}&lt;span class="comment"&gt; /* END _parent */&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;To implement the accessor methods for &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_children&lt;/span&gt; field is a little different process. But Xcode has some macros to help us. Select the entire line of code that contains the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_children&lt;/span&gt; field declaration like the following figure.&lt;br /&gt;&lt;br /&gt;&lt;a style="background-color: #000000;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_HzkQT2tuwqg/SqXDjC8O7pI/AAAAAAAAANA/nFSe_pyN5PQ/s1600-h/select_children_declaration.png"&gt;&lt;img style="background-color: #000000; display:block; margin:0px auto 10px; text-align: center; cursor: pointer; cursor: hand; width: 320px; height: 232px;" src="http://2.bp.blogspot.com/_HzkQT2tuwqg/SqXDjC8O7pI/AAAAAAAAANA/nFSe_pyN5PQ/s320/select_children_declaration.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5378920336816270994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then choose the item "Place Accessor Decls on Clipboard" from the "Code" submenu of the "User Scripts" menu.&lt;br /&gt;&lt;br /&gt;&lt;a style="background-color: #000000;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HzkQT2tuwqg/SqXHx2gpOCI/AAAAAAAAANI/ZmBUivae0Fw/s1600-h/copy_decl_to_clip.png"&gt;&lt;img style="background-color: #000000; display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 127px;" src="http://4.bp.blogspot.com/_HzkQT2tuwqg/SqXHx2gpOCI/AAAAAAAAANI/ZmBUivae0Fw/s320/copy_decl_to_clip.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5378924989223876642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then, place the cursor in an empty line, between the end of &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;setParent:&lt;/span&gt; method declaration and the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;@end&lt;/span&gt; macro, and paste (COMMAND+V).&lt;br /&gt;&lt;br /&gt;Select once more the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_children&lt;/span&gt; field declaration...&lt;br /&gt;&lt;br /&gt;&lt;a style="background-color: #000000;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HzkQT2tuwqg/SqXJaZ6wlbI/AAAAAAAAANQ/E_RpzCQ5mpY/s1600-h/copy_def_to_clip.png"&gt;&lt;img style="background-color: #000000; display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 127px;" src="http://1.bp.blogspot.com/_HzkQT2tuwqg/SqXJaZ6wlbI/AAAAAAAAANQ/E_RpzCQ5mpY/s320/copy_def_to_clip.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5378926785435047346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;... and choose the item "Place Accessor Defs on Clipboard", this time.&lt;br /&gt;Then go to the implementation source file (MyNode.m), place the cursor in an empty line between the end of the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;setParent:&lt;/span&gt; method definition and the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;@end&lt;/span&gt; macro, and paste (COMMAND+V).&lt;br /&gt;&lt;br /&gt;Xcode will create all the KVC compliant accessor methods of the &lt;span style="font-family: Monaco, Courier new, Courier, Monospaced, Serif; font-size: 10px;"&gt;_children&lt;/span&gt; instance variable for you.&lt;br /&gt;&lt;br /&gt;So, the class MyNode is essentially implemented.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-985506656426472711?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/985506656426472711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=985506656426472711' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/985506656426472711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/985506656426472711'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2009/09/8-xml-parsing.html' title='8. XML parsing'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_HzkQT2tuwqg/SqXDjC8O7pI/AAAAAAAAANA/nFSe_pyN5PQ/s72-c/select_children_declaration.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-7244925205736716156</id><published>2009-09-07T20:04:00.002+02:00</published><updated>2009-09-07T20:06:08.762+02:00</updated><title type='text'>7. Long time absence</title><content type='html'>I am sorry for my long absence. I will restart to write about Cocoa, as soon as possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-7244925205736716156?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/7244925205736716156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=7244925205736716156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/7244925205736716156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/7244925205736716156'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2009/09/long-time-absence.html' title='7. Long time absence'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-1106494313194885699</id><published>2008-12-07T16:18:00.027+01:00</published><updated>2009-09-07T22:57:46.649+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='B-Spline'/><category scheme='http://www.blogger.com/atom/ns#' term='Test'/><category scheme='http://www.blogger.com/atom/ns#' term='NSView'/><category scheme='http://www.blogger.com/atom/ns#' term='Interpolation'/><title type='text'>6. B-Spline Test Implementation</title><content type='html'>And, finally, I have been able to implement a first B-Spline interpolation test.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HzkQT2tuwqg/SUXdK1wGLnI/AAAAAAAAAGI/AWcTsAGwxZA/s1600-h/screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 254px;" src="http://1.bp.blogspot.com/_HzkQT2tuwqg/SUXdK1wGLnI/AAAAAAAAAGI/AWcTsAGwxZA/s320/screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5279869316459015794" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This little test application loads a custom NSView subclass, where it draws a control points polyline (the blue line) and, subsequently, calculates intermediate points, using a B-Spline interpolation algorithm to draw the red curved line.&lt;br /&gt;&lt;br /&gt;Following code shows the two methods that are actually responsible for spline interpolation.&lt;br /&gt;&lt;br /&gt;&lt;div class="code"&gt;- (&lt;span class="sysClass"&gt;CGFloat&lt;/span&gt;) bWithI:(&lt;span class="keyword"&gt;int&lt;/span&gt;)i T:(&lt;span class="keyword"&gt;float&lt;/span&gt;)t {&lt;br /&gt;    &lt;span class="keyword"&gt;switch&lt;/span&gt; (i) {&lt;br /&gt;        &lt;span class="keyword"&gt;case&lt;/span&gt; -&lt;span class="number"&gt;2&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; (((-t + &lt;span class="number"&gt;3&lt;/span&gt;) * t - &lt;span class="number"&gt;3&lt;/span&gt;) * t + &lt;span class="number"&gt;1&lt;/span&gt;) / &lt;span class="number"&gt;6&lt;/span&gt;;&lt;br /&gt;        &lt;span class="keyword"&gt;case&lt;/span&gt; -&lt;span class="number"&gt;1&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; (((&lt;span class="number"&gt;3&lt;/span&gt; * t - &lt;span class="number"&gt;6&lt;/span&gt;) * t) * t + &lt;span class="number"&gt;4&lt;/span&gt;) / &lt;span class="number"&gt;6&lt;/span&gt;;&lt;br /&gt;        &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; (((-&lt;span class="number"&gt;3&lt;/span&gt; * t + &lt;span class="number"&gt;3&lt;/span&gt;) * t + &lt;span class="number"&gt;3&lt;/span&gt;) * t + &lt;span class="number"&gt;1&lt;/span&gt;) / &lt;span class="number"&gt;6&lt;/span&gt;;&lt;br /&gt;        &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;:&lt;br /&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; (t * t * t) / &lt;span class="number"&gt;6&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;- (&lt;span class="sysClass"&gt;NSPoint&lt;/span&gt;) pWithI:(&lt;span class="keyword"&gt;int&lt;/span&gt;)i T:(&lt;span class="keyword"&gt;float&lt;/span&gt;)t {&lt;br /&gt;    &lt;span class="myClass"&gt;CGFloat&lt;/span&gt; px = &lt;span class="number"&gt;0&lt;/span&gt;;&lt;br /&gt;    &lt;span class="myClass"&gt;CGFloat&lt;/span&gt; py = &lt;span class="number"&gt;0&lt;/span&gt;;&lt;br /&gt;    &lt;span class="keyword"&gt;for&lt;/span&gt; (&lt;span class="keyword"&gt;int&lt;/span&gt; j = -&lt;span class="number"&gt;2&lt;/span&gt;; j &lt;= &lt;span class="number"&gt;1&lt;/span&gt;; j++) {&lt;br /&gt;        px += [&lt;span class="keyword"&gt;self&lt;/span&gt; &lt;span class="myIdentifier"&gt;bWithI&lt;/span&gt;:j &lt;span class="myIdentifier"&gt;T&lt;/span&gt;:t] * [[[&lt;span class="keyword"&gt;self&lt;/span&gt; &lt;span class="myIdentifier"&gt;points&lt;/span&gt;] &lt;span class="sysMethod"&gt;objectAtIndex:&lt;/span&gt;i + j] &lt;span class="myIdentifier"&gt;pointValue&lt;/span&gt;].x;&lt;br /&gt;        py += [&lt;span class="keyword"&gt;self&lt;/span&gt; &lt;span class="myIdentifier"&gt;bWithI&lt;/span&gt;:j &lt;span class="myIdentifier"&gt;T&lt;/span&gt;:t] * [[[&lt;span class="keyword"&gt;self&lt;/span&gt; &lt;span class="myIdentifier"&gt;points&lt;/span&gt;] &lt;span class="sysMethod"&gt;objectAtIndex:&lt;/span&gt;i + j] &lt;span class="myIdentifier"&gt;pointValue&lt;/span&gt;].y;&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="sysMethod"&gt;NSMakePoint&lt;/span&gt;(px, py);&lt;br /&gt;}&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-1106494313194885699?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/1106494313194885699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=1106494313194885699' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/1106494313194885699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/1106494313194885699'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/12/6-b-spline-test-implementation.html' title='6. B-Spline Test Implementation'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HzkQT2tuwqg/SUXdK1wGLnI/AAAAAAAAAGI/AWcTsAGwxZA/s72-c/screenshot.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-6556510271496502804</id><published>2008-09-23T23:57:00.003+02:00</published><updated>2008-09-24T00:12:58.076+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Key-Value'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><category scheme='http://www.blogger.com/atom/ns#' term='NSResponder'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='keyboard events'/><category scheme='http://www.blogger.com/atom/ns#' term='mouse events'/><category scheme='http://www.blogger.com/atom/ns#' term='event handling'/><title type='text'>5. After the Custom View is created</title><content type='html'>&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaViewsGuide/Introduction/chapter_1_section_1.html"&gt;View Programming Guide for Cocoa&lt;/a&gt; points out some foundamental steps a developer has to take in consideration when creating a custom view class. They are listed in the &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaViewsGuide/SubclassingNSView/chapter_6_section_1.html#//apple_ref/doc/uid/TP40002978-CH7-SW4"&gt;Creating a Custom View&lt;/a&gt; chapter.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Providing methods to allocate and deallocate the view.&lt;/li&gt;&lt;li&gt;Drawing the view content.&lt;/li&gt;&lt;li&gt;Marking portion of the view  for updating in response to value changes.&lt;/li&gt;&lt;li&gt;Responding to mouse events produced by user interaction.&lt;/li&gt;&lt;li&gt;Updating mouse pointer when it is over a draggable item.&lt;/li&gt;&lt;li&gt;Responding to keyboard events.&lt;/li&gt;&lt;li&gt;Implementing &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html"&gt;NSResponder&lt;/a&gt; actions methods.&lt;/li&gt;&lt;li&gt;Providing key-value-coding compliant accessors for its settable properties.&lt;/li&gt;&lt;/ol&gt;An important guide to understand Event Handling in Cocoa is &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/Introduction/chapter_1_section_1.html"&gt;Cocoa Event-Handling Guide&lt;/a&gt;. This guide covers tips regarding mouse and keyboard events and also &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSResponder_Class/Reference/Reference.html"&gt;NSResponder&lt;/a&gt; class.&lt;br /&gt;Another foundamental document is &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/BasicPrinciples.html"&gt;Key-Value Coding Programming Guide&lt;/a&gt; that explains point 8.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-6556510271496502804?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/6556510271496502804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=6556510271496502804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/6556510271496502804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/6556510271496502804'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/09/5-after-custom-view-is-created.html' title='5. After the Custom View is created'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-2447458251995274823</id><published>2008-09-23T22:38:00.014+02:00</published><updated>2008-09-23T23:50:19.826+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interface Builder'/><category scheme='http://www.blogger.com/atom/ns#' term='Custom View'/><category scheme='http://www.blogger.com/atom/ns#' term='NSView'/><category scheme='http://www.blogger.com/atom/ns#' term='Xcode'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><category scheme='http://www.blogger.com/atom/ns#' term='Quartz'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenGL'/><title type='text'>4. More detailed informations about subclassing NSView</title><content type='html'>Either custom &lt;span style="font-style: italic;"&gt;Quartz&lt;/span&gt; views or &lt;span style="font-style: italic;"&gt;OpenGL&lt;/span&gt; views, need to subclass abstract class &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html"&gt;NSView&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In the post &lt;a href="http://ilearncocoa.blogspot.com/2008/02/1-quartz-subclassing-nsview.html"&gt;1. Quartz subclassing NSView&lt;/a&gt; I explained the two possible methods to achieve this result. My favourite one is the first one, because it is the more reliable and compatible with different versions of &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Now I just want to note once more the whole procedure visually.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;In your project right click on the Classes group and choose &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Add -&gt; New File...&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HzkQT2tuwqg/SNlbA1S2XGI/AAAAAAAAADc/Vlnf-Pi2Vco/s1600-h/new_file.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_HzkQT2tuwqg/SNlbA1S2XGI/AAAAAAAAADc/Vlnf-Pi2Vco/s200/new_file.png" alt="" id="BLOGGER_PHOTO_ID_5249326910541290594" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;New File&lt;/span&gt; chooser windows select &lt;span style="font-style: italic;"&gt;Mac OS X&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbWlwxUoI/AAAAAAAAADk/YOAsOF0J1Gk/s1600-h/macosx_cocoa.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbWlwxUoI/AAAAAAAAADk/YOAsOF0J1Gk/s320/macosx_cocoa.png" alt="" id="BLOGGER_PHOTO_ID_5249327284328944258" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Then, scroll the upper right scroll view to find &lt;span style="font-style: italic;"&gt;Objective-C&lt;/span&gt; &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html"&gt;NSView&lt;/a&gt; subclass icon, and select it.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HzkQT2tuwqg/SNlbd0CNrUI/AAAAAAAAADs/6Q-LmyoFhAs/s1600-h/objc_nsview_subclass.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_HzkQT2tuwqg/SNlbd0CNrUI/AAAAAAAAADs/6Q-LmyoFhAs/s320/objc_nsview_subclass.png" alt="" id="BLOGGER_PHOTO_ID_5249327408419286338" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Press &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Next&lt;/span&gt; button.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbmJgz82I/AAAAAAAAAD0/4JTl89KmU6I/s1600-h/next.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbmJgz82I/AAAAAAAAAD0/4JTl89KmU6I/s320/next.png" alt="" id="BLOGGER_PHOTO_ID_5249327551623721826" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the next view, give a name to your class and press &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Finish&lt;/span&gt; button.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbw1O87EI/AAAAAAAAAD8/kkwwf_2-4y8/s1600-h/give_name_and_finish.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_HzkQT2tuwqg/SNlbw1O87EI/AAAAAAAAAD8/kkwwf_2-4y8/s320/give_name_and_finish.png" alt="" id="BLOGGER_PHOTO_ID_5249327735158664258" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make both &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt; visible and drag your custom view header from &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; project window to the &lt;span style="font-style: italic;"&gt;NIB&lt;/span&gt; window, in &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt;. If &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt; is not opened yet, double click the &lt;span style="font-family:courier new;"&gt;MainMenu.xib&lt;/span&gt; file, in the &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Resources&lt;/span&gt; group of your &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; project, to open it.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_HzkQT2tuwqg/SNlb4naIiEI/AAAAAAAAAEE/nY0oFohTUBE/s1600-h/drag_header.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_HzkQT2tuwqg/SNlb4naIiEI/AAAAAAAAAEE/nY0oFohTUBE/s320/drag_header.png" alt="" id="BLOGGER_PHOTO_ID_5249327868886419522" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt;, select a custom view instance.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_HzkQT2tuwqg/SNlcHe4HCqI/AAAAAAAAAEM/B15RwhbtYx0/s1600-h/set_instance_class_to_customview.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://4.bp.blogspot.com/_HzkQT2tuwqg/SNlcHe4HCqI/AAAAAAAAAEM/B15RwhbtYx0/s320/set_instance_class_to_customview.png" alt="" id="BLOGGER_PHOTO_ID_5249328124294269602" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Open &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Inspector&lt;/span&gt; (&lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;COMMAND-SHIFT-I&lt;/span&gt;), move to the Identity panel and choose your custom view class from the &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Class&lt;/span&gt; drop down menu of &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Class Identity&lt;/span&gt; subsection.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_HzkQT2tuwqg/SNlcH-cmyvI/AAAAAAAAAEU/zzipDzsyNaY/s1600-h/set_instance_class_to_customview_identity.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_HzkQT2tuwqg/SNlcH-cmyvI/AAAAAAAAAEU/zzipDzsyNaY/s320/set_instance_class_to_customview_identity.png" alt="" id="BLOGGER_PHOTO_ID_5249328132768844530" border="0" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Now the custom view instance, in &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt;, is defined as an instance of your custom view class. And you can operate on it editing your custom view class code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-2447458251995274823?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/2447458251995274823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=2447458251995274823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/2447458251995274823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/2447458251995274823'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/09/4-more-detailed-informations-about.html' title='4. More detailed informations about subclassing NSView'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HzkQT2tuwqg/SNlbA1S2XGI/AAAAAAAAADc/Vlnf-Pi2Vco/s72-c/new_file.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-5669158934482949979</id><published>2008-08-21T17:12:00.021+02:00</published><updated>2008-08-28T01:09:06.629+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FreeHand'/><category scheme='http://www.blogger.com/atom/ns#' term='Spline'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><category scheme='http://www.blogger.com/atom/ns#' term='Quartz'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='Painter'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='Integrals'/><category scheme='http://www.blogger.com/atom/ns#' term='Web'/><category scheme='http://www.blogger.com/atom/ns#' term='Bezier'/><category scheme='http://www.blogger.com/atom/ns#' term='Photoshop'/><category scheme='http://www.blogger.com/atom/ns#' term='Interpolation'/><category scheme='http://www.blogger.com/atom/ns#' term='Cubic'/><category scheme='http://www.blogger.com/atom/ns#' term='Derivatives'/><category scheme='http://www.blogger.com/atom/ns#' term='Inkscape'/><category scheme='http://www.blogger.com/atom/ns#' term='Illustrator'/><category scheme='http://www.blogger.com/atom/ns#' term='AppKit'/><title type='text'>3. Spline Interpolation</title><content type='html'>&lt;div&gt;I have been away from this pages for a long time. Though, in the period passed, I red a lot of &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Cocoa&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Objective-C&lt;/span&gt; tutorials and guides (expecially the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Apple&lt;/span&gt; official guides).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;One of the mandatory features of the software I want to develop is smoothing of strokes I paint with the tablet (or mouse).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Why smoothing algorithm is needed?&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Tablet input data is sent to computer at a fixed sampling rate (it depends on the hardware features). Tablet hardware read pen position every &lt;span class="Apple-style-span" style="font-style: italic;"&gt;n&lt;/span&gt; milliseconds, software takes position data and connects each position with a stright line. This means that, if  the artist draws a curve fast enough, the curve will be a poly-line (i.e. a sequence of points connected by stright lines).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;table style="margin: 0px auto 10px; display: block; text-align: center;" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="margin: 0px; display: block;" src="http://3.bp.blogspot.com/_HzkQT2tuwqg/SK2OTOYjoFI/AAAAAAAAAC8/UUlnBRxs0Wo/s320/smooth_disabled.png" alt="smooth_disabled.png" id="BLOGGER_PHOTO_ID_5236998402631508050" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;i style="font-size: 10px;"&gt;A curve stroke with the smooth disabled.&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_HzkQT2tuwqg/SK2Sh-YH2ZI/AAAAAAAAADE/J7XrCxf-Qgc/s320/smooth_active.png" alt="smooth_active.png" id="BLOGGER_PHOTO_ID_5237003054079269266" border="0" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;i style="font-size: 10px;"&gt;A curve stroke with the smooth enabled.&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;As you can see it is not natural.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;To resolve this problem, professional painting softwares (like &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Painter&lt;/span&gt; or &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Photoshop&lt;/span&gt;) implemet a smoothing algorithm to grow programmatically detail between two subsequent pen positions, and give the curve a more natural appearance. These algorithms (there are several variants) are based on math functions that guarantee a good approximation and fast computing performances.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;To draw curves &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Cocoa&lt;/span&gt; provides only &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Bezier Splines&lt;/span&gt;, either in the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;AppKit&lt;/span&gt; framework, using &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSBezierPath_Class/Reference/Reference.html"&gt;NSBezierPath&lt;/a&gt; methods and in the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Quatz 2D&lt;/span&gt; functions for the &lt;a href="http://developer.apple.com/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html"&gt;CGContext&lt;/a&gt;.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;Bezier Splines&lt;/span&gt; are special case of &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Cubic Splines&lt;/span&gt; where you have to know 2 points (the start and the end point of the curve) and 2 control points (computer artists, who know vector applications like &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Illustrator&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Freehand&lt;/span&gt; or &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Inkscape&lt;/span&gt;, use to call them "handles" because they move them to control the bias and the orientation of the curve).&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;table style="margin: 0px auto 10px; display: block; text-align: center;" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_HzkQT2tuwqg/SK2n2j_P65I/AAAAAAAAADU/Bvzis9n-ToA/s320/bezier_curves.png" border="0" alt="bezier_curves.png" id="BLOGGER_PHOTO_ID_5237026497517054866" /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;i style="font-size: 10px;"&gt;2 different oriented Bezier curves.&lt;/i&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Though, &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Tablet&lt;/span&gt; input events do not carry any control points data. Those events pass only data about the points that stay on curve path.&lt;/div&gt;&lt;div&gt;This means that &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Bezier&lt;/span&gt; paths are not the solution to our problems.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then I started searching the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Web&lt;/span&gt;, looking for documentation about &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Spline Interpolation&lt;/span&gt; algorithms.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The mathematics, I should be proficient to actually understand deeply the theory beneath the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Spline Interpolation&lt;/span&gt;, involve &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Derivatives&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Integrals&lt;/span&gt; and many other complex things. Unfortunatelly my mathematics reminds in this fields have blanks, and so, I am currently not able to indipendently implement the algorithm starting from a math text.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then, I browsed the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Web&lt;/span&gt; looking for some examples that could help me to understand how to actually implement this algorithm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I found some...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-5669158934482949979?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/5669158934482949979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=5669158934482949979' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/5669158934482949979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/5669158934482949979'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/08/3-spline-interpolation.html' title='3. Spline Interpolation'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_HzkQT2tuwqg/SK2OTOYjoFI/AAAAAAAAAC8/UUlnBRxs0Wo/s72-c/smooth_disabled.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-5962447205396805411</id><published>2008-02-04T14:03:00.000+01:00</published><updated>2008-02-04T15:16:10.380+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tablet'/><category scheme='http://www.blogger.com/atom/ns#' term='mouse'/><category scheme='http://www.blogger.com/atom/ns#' term='Quartz'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='ADC'/><category scheme='http://www.blogger.com/atom/ns#' term='event handling'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa Dev Central'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple Development Connection'/><title type='text'>2. What I need?</title><content type='html'>I spent the latest hours to find resources about handling tablet and/or mouse events. This to understand how difficult can be to develop such things. Of course there are several informations about it.&lt;br /&gt;&lt;br /&gt;In the &lt;span style="font-style: italic;"&gt;Chapter 2&lt;/span&gt; of the &lt;a href="http://developer.apple.com/documentation/GraphicsImaging/Conceptual/CoreImaging/ci_intro/chapter_1_section_1.html"&gt;Core Image Programming Guide&lt;/a&gt;, the part &lt;span style="font-style: italic;"&gt;Imaging Dynamical System&lt;/span&gt;, describes a &lt;span style="font-style: italic;"&gt;MicroPaint&lt;/span&gt; application that is able to capture mouse events and draw on a canvas. The guide is available either  in the Cocoa area of &lt;a href="http://developer.apple.com/"&gt;Apple Developer Connection&lt;/a&gt; site and in the &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; included documentation. Though, even if it will be soon useful, the &lt;span style="font-style: italic;"&gt;MicroPaint&lt;/span&gt; application example focuses on the use of &lt;span style="font-family:courier new;"&gt;CIImageAccumulator&lt;/span&gt; class and not on how to actualy handle mouse events.&lt;br /&gt;There is also a &lt;span style="font-style: italic;"&gt;CIMicroPaint&lt;/span&gt; example in the &lt;span style="font-family:courier new;"&gt;/Developer/Examples/Quartz/Core Image/CIMicroPaint&lt;/span&gt; folder installed with development tools. But it is based on &lt;span style="font-style: italic;"&gt;OpenGL &lt;/span&gt;and at this point it confuses me a little.&lt;br /&gt;Talking about event handling there is the &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/Introduction/chapter_1_section_1.html"&gt;Cocoa Event-Handling Guide&lt;/a&gt; at &lt;span style="font-style: italic;"&gt;ADC&lt;/span&gt;, available also in the &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; documentation. But it does not make any example/tutorial and I want a pratical tutorial to learn quickly what to do.&lt;br /&gt;&lt;br /&gt;So, I found the &lt;a href="http://cocoadevcentral.com/articles/000047.php"&gt;Mouse Events&lt;/a&gt; article at &lt;a href="http://cocoadevcentral.com/"&gt;Cocoa Dev Central&lt;/a&gt; that introduces the reader to a tutorial for mouse event handling. I will use it for quickly understand the needed knowledge and then I will explore the examples provided by &lt;span style="font-style: italic;"&gt;Wacom&lt;/span&gt; at &lt;a href="http://www.wacomeng.com/devsupport/mac.html"&gt;Mac Software Development Support&lt;/a&gt; page.&lt;br /&gt;&lt;br /&gt;But before to do it I want to write a list of features for my application, to understand what I actually need to know to go on.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Tablet support with pressure sensitivity;&lt;/li&gt;&lt;li&gt;Layers support.&lt;/li&gt;&lt;li&gt;Alpha channel support, for each layer and the global image.&lt;/li&gt;&lt;li&gt;Blending modes support.&lt;/li&gt;&lt;li&gt;Layer transparency support.&lt;/li&gt;&lt;li&gt;Tablet strokes smoothing to avoid stright lines when user moves the pen really fast.&lt;/li&gt;&lt;/ol&gt;Reading the &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/chapter_1_section_1.html"&gt;Cocoa Drawing Guide&lt;/a&gt;, I discovered that &lt;span style="font-style: italic;"&gt;Quartz&lt;/span&gt; gives support for:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Layers&lt;/li&gt;&lt;li&gt;Gradients (also called shadings)&lt;/li&gt;&lt;li&gt;Image data sources&lt;/li&gt;&lt;li&gt;Blend modes (Cocoa uses compositing modes instead)&lt;/li&gt;&lt;li&gt;Masking images&lt;/li&gt;&lt;li&gt;Transparency layers (for grouping content)&lt;/li&gt;&lt;li&gt;Arbitrary patterns (other than images)&lt;/li&gt;&lt;/ul&gt;That means that I can skip to project my self made layers system and use the one provided by &lt;span style="font-style: italic;"&gt;Apple&lt;/span&gt; and that I can choose between two different blending systems: &lt;span style="font-style: italic;"&gt;Quartz&lt;/span&gt; blend modes or &lt;span style="font-style: italic;"&gt;Cocoa&lt;/span&gt; compositing modes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-5962447205396805411?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/5962447205396805411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=5962447205396805411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/5962447205396805411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/5962447205396805411'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/02/2-what-i-need.html' title='2. What I need?'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-445657837784490287.post-7009146161856838844</id><published>2008-02-04T08:53:00.001+01:00</published><updated>2008-09-23T23:49:12.336+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interface Builder'/><category scheme='http://www.blogger.com/atom/ns#' term='NSView'/><category scheme='http://www.blogger.com/atom/ns#' term='Xcode'/><category scheme='http://www.blogger.com/atom/ns#' term='Objective-C'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='Cocoa Dev Central'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple'/><category scheme='http://www.blogger.com/atom/ns#' term='CocoaCast'/><title type='text'>1. Quartz subclassing NSView</title><content type='html'>My aim is to create a simple 2D painting application using &lt;span style="font-style: italic;"&gt;Cocoa&lt;/span&gt;. I have already tried some tutorials on the basics of coding in &lt;span style="font-style: italic;"&gt;Objective-C&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;Cocoa&lt;/span&gt; with the &lt;span style="font-style: italic;"&gt;Apple IDE Xcode&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt; with its counterpart &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt; are two extremelly powerfull tools. Most of the work is done using interface, and they prepare automatically a skeleton of the code. Even if, for the lovers of pure coding, this could seem to be not so good, there is the advantage that the code generated this way is quite clean, compliant to &lt;span style="font-style: italic;"&gt;Apple&lt;/span&gt; standards an less error prone.&lt;br /&gt;&lt;br /&gt;I am collecting informations from a lot of different resources on line. There are two tutorial that I found particularly interesting. Those are: the &lt;a href="http://www.cocoadevcentral.com/"&gt;Cocoa Dev Central&lt;/a&gt;, &lt;a href="http://www.cocoadevcentral.com/d/intro_to_quartz_two/"&gt;Intro To Quartz II&lt;/a&gt;, and the &lt;a href="http://www.cocoacast.com/?q=node/80"&gt;Episode 18 - Custom Views&lt;/a&gt; of &lt;a href="http://www.cocoacast.com/"&gt;CocoaCast&lt;/a&gt;. They basically talk about the same thing: subclassing a &lt;span style="font-family:courier new;"&gt;NSView&lt;/span&gt; class to create a drawing canvas.&lt;br /&gt;&lt;br /&gt;All my experience comes from &lt;span style="font-style: italic;"&gt;Java&lt;/span&gt; so I have no problems to understand &lt;span style="font-style: italic;"&gt;Object Oriented&lt;/span&gt; languages, I just have some little problem to understand some &lt;span style="font-style: italic;"&gt;C&lt;/span&gt; sintax but it does not rapresent a great obstacle.&lt;br /&gt;&lt;br /&gt;So, watching this two tutorials I discovered that a class can be subclassed in two differnt ways.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Using &lt;span style="font-style: italic;"&gt;Xcode&lt;/span&gt;: in the &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Project window&lt;/span&gt; left list, it is possible to right click on the &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Classes&lt;/span&gt; subfolder (or any other project subfolder) and choose &lt;span style="font-style: italic;"&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;Add -&gt; New File...&lt;/span&gt;&lt;/span&gt;. The &lt;span style="color: rgb(153, 51, 153); font-style: italic;"&gt;Assistant&lt;/span&gt; will appear and it is possible to choose from a list preconfigured subclasses. Choose &lt;span style="font-style: italic;"&gt;&lt;span style="color: rgb(153, 51, 153);"&gt;Objective-C NSView subclass&lt;/span&gt;&lt;/span&gt; in the &lt;span style="font-style: italic;"&gt;Cocoa&lt;/span&gt; section. Then click &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Next&lt;/span&gt;. In the following view give a name to your class and click &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Finish&lt;/span&gt;. After these steps, it is necessary to drag the custom class header to &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt;, in the &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Instances&lt;/span&gt; panel of the &lt;span style="font-style: italic;"&gt;NIB&lt;/span&gt; window to make &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt; aware of the new custom class.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Using &lt;span style="font-style: italic;"&gt;Interface Builder&lt;/span&gt;: in the &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Classes&lt;/span&gt; panel of the &lt;span style="font-style: italic;"&gt;NIB&lt;/span&gt; window, search for &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;NSView&lt;/span&gt; class right click on it an choose &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Subclass NSView&lt;/span&gt;. Giva a name to the subclass and right click over it. Choose &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Create Files for SubclassName&lt;/span&gt;. It will appear a dialog window. Leave it as it is, except for &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Insert into targets:&lt;/span&gt; box. There you have to make sure that your project name check box is selected. To finish click &lt;span style="font-style: italic; color: rgb(153, 51, 153);"&gt;Choose&lt;/span&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/445657837784490287-7009146161856838844?l=ilearncocoa.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilearncocoa.blogspot.com/feeds/7009146161856838844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=445657837784490287&amp;postID=7009146161856838844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/7009146161856838844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/445657837784490287/posts/default/7009146161856838844'/><link rel='alternate' type='text/html' href='http://ilearncocoa.blogspot.com/2008/02/1-quartz-subclassing-nsview.html' title='1. Quartz subclassing NSView'/><author><name>Ender</name><uri>http://www.blogger.com/profile/18398344747820390837</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://img146.imageshack.us/img146/5875/selfportrait80x80so8.gif'/></author><thr:total>0</thr:total></entry></feed>
