<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.0">Jekyll</generator><link href="http://www.stephanmichels.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://www.stephanmichels.com/" rel="alternate" type="text/html" /><updated>2021-08-03T18:31:55+02:00</updated><id>http://www.stephanmichels.com/feed.xml</id><title type="html">Stephan Michels</title><subtitle>Personal site of Stephan Michels</subtitle><entry><title type="html">Chemical Diagram Editor</title><link href="http://www.stephanmichels.com/private/2021/08/02/new_project.html" rel="alternate" type="text/html" title="Chemical Diagram Editor" /><published>2021-08-02T22:32:04+02:00</published><updated>2021-08-02T22:32:04+02:00</updated><id>http://www.stephanmichels.com/private/2021/08/02/new_project</id><content type="html" xml:base="http://www.stephanmichels.com/private/2021/08/02/new_project.html">&lt;p&gt;For some time now we have been developing a new application for MacOS for creating structure diagrams in chemistry. This application is used to create graphics of chemical structures or reactions for scientific articles, books or online content.&lt;/p&gt;

&lt;p&gt;The focus is on very good integration with MacOS. This includes a native application, support for Dark Mode and TouchBar and technologies such as QuickLook, Spotlight and a beautiful user interface.&lt;/p&gt;

&lt;p&gt;The application will support several standard exchange formats such as ChemDraw, MOL Files, Smiles and Inchi Strings.&lt;/p&gt;

&lt;p&gt;We hope to be able to start the lower test phase with selected testers soon. If you are interested, we would like to hear from you.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;/assets/images/posts/ChemEditor.png&quot;&gt;&lt;img class=&quot; wp-image-126 aligncenter&quot; alt=&quot;Screenshot of the Editor&quot; src=&quot;/assets/images/posts/ChemEditor.png&quot; width=&quot;536&quot; height=&quot;313&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Private" /><summary type="html">For some time now we have been developing a new application for MacOS for creating structure diagrams in chemistry. This application is used to create graphics of chemical structures or reactions for scientific articles, books or online content.</summary></entry><entry><title type="html">Interface Inspector</title><link href="http://www.stephanmichels.com/private/2013/09/21/interface-inspector.html" rel="alternate" type="text/html" title="Interface Inspector" /><published>2013-09-21T22:32:04+02:00</published><updated>2013-09-21T22:32:04+02:00</updated><id>http://www.stephanmichels.com/private/2013/09/21/interface-inspector</id><content type="html" xml:base="http://www.stephanmichels.com/private/2013/09/21/interface-inspector.html">&lt;p&gt;I finally finished first my own software product called &lt;a href=&quot;http://www.interface-inspector.com&quot; title=&quot;Link to Interface Inspector&quot;&gt;Interface Inspector&lt;/a&gt;. I wrote the Interface Inspector to debug my own applications during the development to see which are the visible views and their properties. I often have the problem that I don’t know why specific views are not visible or display a wrong content. With this tool I can now inspect the running application and see all necessary information. Moreover I can introspect other applications to see how they manage to build a specific design. A great way to learn from others.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://www.interface-inspector.com&quot; title=&quot;Link to Interface Inspector&quot;&gt;Interface Inspector&lt;/a&gt; is currently published as a public beta version and I hope this tool will be helpful for others too.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;/assets/images/posts/InterfaceInspector.png&quot;&gt;&lt;img class=&quot; wp-image-126 aligncenter&quot; alt=&quot;Screenshot of the Interface Inspector&quot; src=&quot;/assets/images/posts/InterfaceInspector.png&quot; width=&quot;638&quot; height=&quot;372&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Private" /><summary type="html">I finally finished first my own software product called Interface Inspector. I wrote the Interface Inspector to debug my own applications during the development to see which are the visible views and their properties. I often have the problem that I don’t know why specific views are not visible or display a wrong content. With this tool I can now inspect the running application and see all necessary information. Moreover I can introspect other applications to see how they manage to build a specific design. A great way to learn from others.</summary></entry><entry><title type="html">Debug all called Objective-C methods</title><link href="http://www.stephanmichels.com/xcode/2013/01/31/debug-all-called-objective-c-methods.html" rel="alternate" type="text/html" title="Debug all called Objective-C methods" /><published>2013-01-31T12:10:28+01:00</published><updated>2013-01-31T12:10:28+01:00</updated><id>http://www.stephanmichels.com/xcode/2013/01/31/debug-all-called-objective-c-methods</id><content type="html" xml:base="http://www.stephanmichels.com/xcode/2013/01/31/debug-all-called-objective-c-methods.html">&lt;p&gt;Once in a while I need to know which methods are called in my code. The simplest solution is to add a breakpoint on the function called objc_msgSend. This function is responsible for the call of every method in Objective-C&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;objc_msgSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;theReceiver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SEL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;theSelector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In Xcode you can add actions to breakpoints. In my case add a debugger command to evaluate the receiver and the selector. So I added following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;expr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;[%s %s]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object_getClassName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You might ask where I get the register names from. I found a good article on expaining the various registers of the different platforms: “&lt;a href=&quot;http://www.clarkcox.com/blog/2009/02/04/inspecting-obj-c-parameters-in-gdb/&quot; title=&quot;Inspecting Obj-C parameters in gdb&quot;&gt;Inspecting Obj-C parameters in gdb&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Important is that you enable “Automatically continue after evaluating”.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/Breakpoint-objc_msgSend.png&quot; alt=&quot;Breakpoint-objc_msgSend&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now you get a Output like this&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__NSCFConstantString&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__NSCFConstantString&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;copyWithZone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;valueWithRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;valueWithBytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;objCType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSConcreteValue&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resolveInstanceMethod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSConcreteValue&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSConcreteValue&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSObject&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;stringWithFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;</content><author><name>Stephan Michels</name></author><category term="Xcode" /><summary type="html">Once in a while I need to know which methods are called in my code. The simplest solution is to add a breakpoint on the function called objc_msgSend. This function is responsible for the call of every method in Objective-C</summary></entry><entry><title type="html">Implementation of an inspector tab bar</title><link href="http://www.stephanmichels.com/cocoa/2012/05/29/implementation-of-an-inspector-tab-bar.html" rel="alternate" type="text/html" title="Implementation of an inspector tab bar" /><published>2012-05-29T19:32:24+02:00</published><updated>2012-05-29T19:32:24+02:00</updated><id>http://www.stephanmichels.com/cocoa/2012/05/29/implementation-of-an-inspector-tab-bar</id><content type="html" xml:base="http://www.stephanmichels.com/cocoa/2012/05/29/implementation-of-an-inspector-tab-bar.html">&lt;p&gt;For my own project I tried to create a similar tab bar like I have seen in the Xcode&lt;br /&gt;
inspector. Some of you might be interested in the source code, so I made it free and without any&lt;br /&gt;
restriction.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/InspectorTabBar-Screen.png&quot; alt=&quot;InspectorTabBar-Screen&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It took some time to find out how to create NSButtons witch look and work identical to&lt;br /&gt;
the tab bar buttons like in Xcode. First I created an custom NSButtonCell subclass to&lt;br /&gt;
draw the shadows left and right of the button to mimic the shadow of the selected&lt;br /&gt;
button.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;drawBezelWithFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;frame&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSView&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;controlView&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Draw background only if the button is selected&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NSOnState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;[...&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;draw&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shadow&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To get the etched look of icons you have to use template images and set the bezel style&lt;br /&gt;
of the button cell.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bezelStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NSTexturedRoundedBezelStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For the functional part, I have struggled a long time with the button action which has been&lt;br /&gt;
sent on the mouse up event. I wanted to switch the views on the mouse down event. Following&lt;br /&gt;
statement allows the button to send the action of the mouse down event.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sendActionOn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSLeftMouseDownMask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The next problem was that button changed it’s state even if the button has already been&lt;br /&gt;
selected. To prevent this behavior I overrode the following method in the button cell.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// prevent automatic state changes&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextState&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Everything else was straight forward. I hope you find the tips and tricks useful. You&lt;br /&gt;
can find the source code on &lt;a href=&quot;http://github.com/smic/InspectorTabBar&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Cocoa" /><summary type="html">For my own project I tried to create a similar tab bar like I have seen in the Xcode inspector. Some of you might be interested in the source code, so I made it free and without any restriction.</summary></entry><entry><title type="html">NSRulerView und NSRulerMarker</title><link href="http://www.stephanmichels.com/cocoa/2012/02/05/nsrulerview-und-nsrulermarker.html" rel="alternate" type="text/html" title="NSRulerView und NSRulerMarker" /><published>2012-02-05T14:14:07+01:00</published><updated>2012-02-05T14:14:07+01:00</updated><id>http://www.stephanmichels.com/cocoa/2012/02/05/nsrulerview-und-nsrulermarker</id><content type="html" xml:base="http://www.stephanmichels.com/cocoa/2012/02/05/nsrulerview-und-nsrulermarker.html">&lt;p&gt;Ich wollte für ein kleines Demoprogram (für  grafische Eingabe) Lineale und Guides hinzufügen, ähnlich wie bei Photoshop und anderen Programmen. Guides sind Hilfslinien, die Linealen hinzugefügt werden, um Objekte an diesen Hilfslinien auszurichten.&lt;/p&gt;

&lt;p&gt;Nun hab ich dabei die Gelegenheit genutzt, meine Erkenntnisse bei der Implementierung der Guides zu dokumentieren.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/NSRulerView-Screen.png&quot; alt=&quot;NSRulerView-Screen&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Apple hat Lineale bereits bei der Benutzung von &lt;strong&gt;NSScrollView&lt;/strong&gt; vorgesehen und sie lassen sich mit relativ wenig Code aktivieren. Dabei werden Lineale über die Instanzen der Klasse &lt;strong&gt;NSRulerView&lt;/strong&gt; dargestellt.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setHasHorizontalRuler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setHasVerticalRuler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setRulersVisible&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Dabei lassen sich Lineare in drei Zonen unterteilen. Zunächst gibt es einen Bereich in welchem das Lineal bzw. die Skala dargestellt wird, gefolgt von einem Bereich in welchem die Marker dargestellt werden. Weiterhin gibt es noch einen Bereich für einen sogenannten &lt;em&gt;Accessory View&lt;/em&gt;. Der &lt;em&gt;Accessory View&lt;/em&gt; kann benutzt werden um verschiedene Steuerelemente unterzubringen. Ein Beispiel wäre ein Button um alle Hilfslinien zu löschen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/NSRulerView3.png&quot; alt=&quot;NSRulerView3&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Für die Marker benutzt Apple die Klasse &lt;strong&gt;NSRulerMarker&lt;/strong&gt; und sie lassen sich direkt zu einer &lt;strong&gt;NSRulerView&lt;/strong&gt; Instanz hinzufügen. Zur Darstellung benötigt die Klasse einen &lt;strong&gt;NSRulerMarker,&lt;/strong&gt; ein &lt;strong&gt;NSImage&lt;/strong&gt; sowie einen Ursprungspunkt, der die Grafik im Verhältnis zur Position des Markers positioniert.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;markerImage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;horizontalMarkerImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;NSRulerMarker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rulerMarker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSRulerMarker&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithRulerView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;horizontalRuler&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;markerLocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;location&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;markerImage&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imageOrigin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSMakePoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;markerImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;markerImage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;horizontalRulerView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rulerMarker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rulerMarker&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Für die Manipulation der Marker benutzt der &lt;em&gt;Ruler View&lt;/em&gt; eine Art Delegate Pattern, wobei sich der Delegate beim &lt;em&gt;Ruler View&lt;/em&gt; „&lt;em&gt;Client View&lt;/em&gt;“ nennt. Der &lt;em&gt;Client View&lt;/em&gt; ist beim &lt;em&gt;Scroll View&lt;/em&gt; in der Regel der &lt;em&gt;Document View&lt;/em&gt; und lässt sich wie folgt anmelden:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;horizontalRulerView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setClientView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;documentView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verticalRulerView&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setClientView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scrollView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;documentView&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Für die Funktionen „Bewegen“, „Entfernen“ und „Hinzufügen“ gibt es eine Reihe von Delegate-Methoden, welche der &lt;em&gt;Client View&lt;/em&gt; implementieren kann. Dabei gruppieren sich diese Methoden in drei Gruppen jeweils für das Bewegen, das Entfernen und das Hinzufügen der Marker. Folgende Methoden existieren z.B. für das Bewegen der Marker.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;rulerView:shouldMoveMarker:&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;rulerView:willMoveMarker:toLocation:&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;rulerView:didMoveMarker:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dabei gibt es eine Methode, die entscheidet ob die jeweilige Aktion überhaupt möglich ist. Es gibt eine Methode, die über den Fortschritt der Aktion informiert und eine Methode, die das Ende der Aktion signalisiert.&lt;/p&gt;

&lt;p&gt;Ich habe mir die Mühe gemacht zu analysieren, in welcher Reihenfolge die Methoden aufgerufen werden und habe dies in einem Sequenzdiagramm dargestellt. Zunächst habe ich analysiert was passiert, wenn ich versuche einen Marker zu bewegen. Dabei ist mir aufgefallen, dass Marker nur bewegt werden können, wenn man mit der Maus in dem Marker-Bereich des &lt;em&gt;Ruler View&lt;/em&gt; klickt. Das ist leider eine unpraktische Eigenschaft, da ich versucht habe den Marker im Lineal-Bereich anzuzeigen.&lt;/p&gt;

&lt;p&gt;Wenn ich nun in den Marker-Bereich klicke, sucht der &lt;em&gt;Ruler View&lt;/em&gt; in den gegebenen Markern nach einem Treffer und ruft mit dem gefundenen Marker die eigene Methode &lt;strong&gt;trackMarker:withMouseEvent:&lt;/strong&gt; auf. Die Methode ruft wiederum die Methode &lt;strong&gt;trackMouse:adding:&lt;/strong&gt; von diesem Marker auf und organisiert die weitere Kommunikation mit dem &lt;em&gt;Client View&lt;/em&gt;. Vermutlich verwendet der Marker eine modale Event-Verfolgungsschleife (&lt;a href=&quot;http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html&quot;&gt;Mouse-Tracking Loop Approach&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Um festzustellen ob der Marker überhaupt bewegt werden darf wird &lt;strong&gt;rulerView:shouldMoveMarker:&lt;/strong&gt; vom Client View ausgeführt und nur wenn diese Methode &lt;strong&gt;YES&lt;/strong&gt; liefert, lässt sich der Marker bewegen. Sobald nun die Mouse bewegt wird, wird der &lt;em&gt;Client View&lt;/em&gt; über die Methode &lt;strong&gt;rulerView:willMoveMarker:&lt;/strong&gt; informiert. Interessant ist der Rückgabewert der Methode. Mit dem Rückgabewert kann der &lt;em&gt;Client View&lt;/em&gt; Einfluss auf die neue Position nehmen, z.B. um nur diskrete Positionen zu erlauben.&lt;/p&gt;

&lt;p&gt;Sobald nun die Maus losgelassen wird, ist die Bewegung beendet und die Methode &lt;strong&gt;rulerView:didMoveMarker:&lt;/strong&gt; wird aufgerufen. Hier lassen sich nun Aktionen mit der neuen Position des Markers durchführen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/NSRulerView2.png&quot; alt=&quot;NSRulerView2&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Das Hinzufügen von Markern funktioniert ein wenig anders, ist aber insgesamt recht ähnlich. Eine Möglichkeit für das Hinzufügen ist über einen Klick in den Marker-Bereich. Nachdem in den Bereich geklickt wird und der &lt;em&gt;Ruler View&lt;/em&gt; keinen Marker für diese Position gefunden hat, ruft der &lt;em&gt;View&lt;/em&gt; die Methode &lt;strong&gt;rulerView:handleMouseDown:&lt;/strong&gt; vom &lt;em&gt;Client View&lt;/em&gt; auf. Diese Methode gibt dem &lt;em&gt;Client View&lt;/em&gt; die Möglichkeit auf Maus-Ereignisse einzugehen. Eine weitere Möglichkeit ist, einen Marker manuell zu instanzieren und zu dem Markern des &lt;em&gt;Ruler Views&lt;/em&gt; hinzuzufügen.&lt;/p&gt;

&lt;p&gt;Der geplante Weg ist vermutlich, dass der &lt;em&gt;Client View&lt;/em&gt; den &lt;em&gt;Ruler View&lt;/em&gt; aufruft damit dieser den Marker verwaltet. Ab dem Moment gleicht die Sequenz der Vorherigen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/NSRulerView1.png&quot; alt=&quot;NSRulerView1&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Bei meiner Suche nach der Funktionsweise der &lt;em&gt;Ruler Views&lt;/em&gt; bin ich auf ein schönen Artikel über die Darstellung von Zeilennummern im &lt;em&gt;Ruler View&lt;/em&gt; gestoßen: „&lt;a href=&quot;http://www.noodlesoft.com/blog/2008/10/05/displaying-line-numbers-with-nstextview/&quot;&gt;Displaying Line Numbers with NSTextView&lt;/a&gt;“.&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Cocoa" /><summary type="html">Ich wollte für ein kleines Demoprogram (für  grafische Eingabe) Lineale und Guides hinzufügen, ähnlich wie bei Photoshop und anderen Programmen. Guides sind Hilfslinien, die Linealen hinzugefügt werden, um Objekte an diesen Hilfslinien auszurichten.</summary></entry><entry><title type="html">Die hypot-Funktion</title><link href="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/die-hypot-funktion.html" rel="alternate" type="text/html" title="Die hypot-Funktion" /><published>2012-01-08T20:19:38+01:00</published><updated>2012-01-08T20:19:38+01:00</updated><id>http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/die-hypot-funktion</id><content type="html" xml:base="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/die-hypot-funktion.html">&lt;p&gt;In diversen Fällen ist mir aufgefallen, dass nur Wenige die Funktion &lt;em&gt;hypot&lt;/em&gt; („euclidean distance function“) kennen. Mit dieser Funktionen lässt sich elegant der Abstand zwischen zwei Punkten berechnen anstatt die Quadratwurzel aus dem Abstandsquadrat zu berechnen, welcher über den Satz von Pythagoras berechnet wurde.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;NSPoint&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sqrtf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dx&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Der Abstand lässt sich leichter und wie ich finde weniger fehleranfällig wie folgt berechnen:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;CGFloat&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hypotf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In meinen Verständnis hatte ich immer angenommen, dass die Funktion schneller sein könnte. Und um dies zu überprüfen habe ich ein kleines Programm (&lt;a href=&quot;http://gist.github.com/1579069.git&quot;&gt;git://gist.github.com/1579069.git&lt;/a&gt;) geschrieben. Ich musste allerdings feststellen, dass tatsächlich die Funktion hypot langsamer war. Da der Unterschied wie ich finde minimal ist, werde ich weiterhin die Funktion &lt;em&gt;hypot&lt;/em&gt; bevorzugen.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objective_c&quot; data-lang=&quot;objective_c&quot;&gt;&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1273819835&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;661994&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;537325&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sqrt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Result&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1273819836&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;367576&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;332056&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hypot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt; &lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Cocoa" /><category term="Computergrafik" /><summary type="html">In diversen Fällen ist mir aufgefallen, dass nur Wenige die Funktion hypot („euclidean distance function“) kennen. Mit dieser Funktionen lässt sich elegant der Abstand zwischen zwei Punkten berechnen anstatt die Quadratwurzel aus dem Abstandsquadrat zu berechnen, welcher über den Satz von Pythagoras berechnet wurde.</summary></entry><entry><title type="html">Teilkurven von Bezier-Splines</title><link href="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/teilkurven-von-bezier-splines.html" rel="alternate" type="text/html" title="Teilkurven von Bezier-Splines" /><published>2012-01-08T20:10:22+01:00</published><updated>2012-01-08T20:10:22+01:00</updated><id>http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/teilkurven-von-bezier-splines</id><content type="html" xml:base="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/08/teilkurven-von-bezier-splines.html">&lt;p&gt;&lt;img src=&quot;/assets/images/posts/SplineSubdivision1.png&quot; alt=&quot;SplineSubdivision1&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p style=&quot;text-align: left;&quot;&gt;
  Ich hatte folgendes Problem: Ich hatte eine Kurve, dargestellt durch ein Bezier-Spline, an deren Enden jeweils ein Pfeil angezeigt werden sollte. Nun sollte aber die Kurve nicht jeweils um die Länge der Pfeilspitzen verlängert werden, sondern die Kurve sollte um die Länge der Spitzen verkürzt werden.
&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/SplineSubdivision2.png&quot; alt=&quot;SplineSubdivision2&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Als Beispiel wurde hier ein &lt;a href=&quot;http://de.wikipedia.org/wiki/Spline&quot;&gt;Bezier-Spline&lt;/a&gt; mit den beiden Knotenpunkten &lt;strong&gt;p1&lt;/strong&gt; und &lt;strong&gt;p4&lt;/strong&gt;, sowie mit den Kontrollpunkten &lt;strong&gt;p2&lt;/strong&gt; und &lt;strong&gt;p3&lt;/strong&gt; dargestellt. Die Idee ist nun eine Teilkurve zu finden, welche von &lt;strong&gt;Start&lt;/strong&gt; bis &lt;strong&gt;End&lt;/strong&gt; geht.&lt;/p&gt;

&lt;p&gt;Nun lassen sich Teile von Splines nicht einfach berechnen wie z.B. bei geraden Linien, weil Splines parametrisierte Kurven sind. Selbst die Länge von Bezier-Splines lässt sich nicht ohne weiteres berechnen. Bei der Suche nach einer Lösung bin auf den wundervollen Artikel &lt;a href=&quot;http://www.antigrain.com/research/adaptive_bezier/index.html&quot;&gt;„Adaptive Subdivision of Bezier Curves“&lt;/a&gt; von Maxim Shemanarev gestoßen.&lt;/p&gt;

&lt;p&gt;Dieser Artikel handelt hauptsächlich von der Berechnung der Länge von Bezier-Splines. Seine Lösung benutzt eine ganze besondere Eigenschaft von Bezier-Splines, bei der von Bezier-Splines zwei Bruchstücke einfach über Trigonometrie berechnen werden können.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/SplineSubdivision3.png&quot; alt=&quot;SplineSubdivision3&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In der Darstellung wird gezeigt, dass wir zwei neue Kurven erhalten mit jeweils &lt;strong&gt;p1&lt;/strong&gt; und &lt;strong&gt;p1234&lt;/strong&gt; bzw. &lt;strong&gt;p1234&lt;/strong&gt; und &lt;strong&gt;p4&lt;/strong&gt; als Knotenpunkte, sowie &lt;strong&gt;p12&lt;/strong&gt; und &lt;strong&gt;p123&lt;/strong&gt; bzw. &lt;strong&gt;p234&lt;/strong&gt; und &lt;strong&gt;p34&lt;/strong&gt; als Kontrollpunkte.&lt;/p&gt;

&lt;p&gt;Mit Hilfe von Intervallschachtelung lassen sich nun die Bruchstücke immer weiter verkleinern. Dabei werden die Bruchstücke dahingehend unterschieden, ob sich die Bruchstücke in dem gewünschten Intervall befinden oder nicht.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/SplineSubdivision4.png&quot; alt=&quot;SplineSubdivision4&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Auch hier hab ich ein kleines Demo-Programm geschrieben, um den Algorithmus auszuprobieren. Der Algorithmus ist als Kategorie von NSBezierPath wegen der einfachen Wiederverwendbarkeit implementiert. Auch um die Kategorie universell zu gestalten, habe ich darauf geachtet, dass der Algorithmus mit Linien-Segmenten und auch mit unterbrochen Segmenten umgehen kann. Der Code ist wieder zu finden auf &lt;a title=&quot;Github: SplineSubdivision&quot; href=&quot;http://github.com/smic/SplineSubdivision&quot; target=&quot;_blank&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/SplineSubdivision-Screen.png&quot; alt=&quot;SplineSubdivision-Screen&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Cocoa" /><category term="Computergrafik" /><summary type="html"></summary></entry><entry><title type="html">Blobular Nachbau</title><link href="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/04/blobular-clone-2.html" rel="alternate" type="text/html" title="Blobular Nachbau" /><published>2012-01-04T09:02:06+01:00</published><updated>2012-01-04T09:02:06+01:00</updated><id>http://www.stephanmichels.com/cocoa/computergrafik/2012/01/04/blobular-clone-2</id><content type="html" xml:base="http://www.stephanmichels.com/cocoa/computergrafik/2012/01/04/blobular-clone-2.html">&lt;p&gt;Vor einiger Zeit bin ich auf ein ganz interessantes &lt;a href=&quot;http://themaninblue.com/writing/perspective/2007/04/18/&quot;&gt;Javascript Demo&lt;/a&gt;  gestoßen. Und zwar geht es um die Darstellung von zwei Kreisen mit einer Kontaktfläche, ähnlich zu zwei Tropfen, welche sich durch die Oberflächenspannung bei geringer Distanz verbinden.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/Blobular-Screen.png&quot; alt=&quot;Blobular-Screen&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Um diese Grafik zu erzeugen wird mit Hilfe einer Probe Volumen, dessen Radius die Krümmung kontrolliert, die Kontaktfläche modelliert. Im folgenden Schema wird hoffentlich verdeutlich wie ich dabei vorgegangen bin.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/Blobular1.png&quot; alt=&quot;Blobular1&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Zuerst wird die Position der Probe Volumen (&lt;strong&gt;c1&lt;/strong&gt;, &lt;strong&gt;c2&lt;/strong&gt;) mit Hilfe der Positionen der Kreise (&lt;strong&gt;b1&lt;/strong&gt;, &lt;strong&gt;b2&lt;/strong&gt;) und der Radien (&lt;strong&gt;r1&lt;/strong&gt;, &lt;strong&gt;r2&lt;/strong&gt;) bestimmt. Dabei werden die Schnittpunkte der beiden Kreise durch die Positionen der Kreise der Radien und des Radius des Probevolumens (&lt;strong&gt;rp&lt;/strong&gt;) bestimmt (grün dargestellt).&lt;/p&gt;

&lt;p&gt;Der Radius der grünen Kreise ist dabei einmal &lt;strong&gt;r1+ rp&lt;/strong&gt; und entsprechend für den anderen Kreis &lt;strong&gt;r2 + rp&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/Blobular2.png&quot; alt=&quot;Blobular2&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Wie die Schnittpunkte von zwei Kreisen berechnet werden wird ganz gut von dem Artikel „&lt;a href=&quot;http://paulbourke.net/geometry/circlesphere/&quot;&gt;Intersection of two circles&lt;/a&gt;“ von Paul Bourke beschrieben.&lt;/p&gt;

&lt;p&gt;Die Schnittpunkte bilden nun die Positionen der Probe-Volumen und mit den Winkeln zwischen Positionen der Kreise lassen sich die Winkel bestimmen, mit welchen die verschiedenen Bögen berechnet werden können.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/posts/Blobular3.png&quot; alt=&quot;Blobular3&quot; class=&quot;center-image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Jetzt gibt es noch einen Spezialfall, wenn beide Kreise weiter voneinander entfernt sind, dann fangen die Probe-Volumen an sich zu überlappen. Als Folge erhalte ich nun zwei getrennte Flächen. Dabei bilden die beiden Schnittpunkte der Probe-Volumen (&lt;strong&gt;m1&lt;/strong&gt;, &lt;strong&gt;m2&lt;/strong&gt;) weitere Stützpunkte für die resultierenden Flächen.&lt;/p&gt;

&lt;p&gt;Für Interessierte ist der Code zu finden auf &lt;a href=&quot;http://github.com/smic/Blobular&quot;&gt;Github&lt;/a&gt;. Die Kreise lassen sich per Maus verschieben und der Radius des Probe-Volumen lässt sich über das Menü steuern. Eine interessante Erweiterung für eine zukünftige Version wäre z.B. mehr als zwei Kreise zu haben.&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Cocoa" /><category term="Computergrafik" /><summary type="html">Vor einiger Zeit bin ich auf ein ganz interessantes Javascript Demo gestoßen. Und zwar geht es um die Darstellung von zwei Kreisen mit einer Kontaktfläche, ähnlich zu zwei Tropfen, welche sich durch die Oberflächenspannung bei geringer Distanz verbinden.</summary></entry><entry><title type="html">Einleitung</title><link href="http://www.stephanmichels.com/private/2011/12/13/hello-world.html" rel="alternate" type="text/html" title="Einleitung" /><published>2011-12-13T09:27:22+01:00</published><updated>2011-12-13T09:27:22+01:00</updated><id>http://www.stephanmichels.com/private/2011/12/13/hello-world</id><content type="html" xml:base="http://www.stephanmichels.com/private/2011/12/13/hello-world.html">&lt;p&gt;Hallo Zusammen,&lt;br /&gt;
ich will ein Blog führen zu den täglichen Herausforderungen, auf die ich so während meiner Arbeit treffe, in der Hoffnung, dass der eine oder andere davon profitieren kann. Die meisten Artikel werden sich auf Cocoa Programmierung für die Mac und iOS Platform beziehen, da das mein Hauptarbeitsfeld und Hobby ist.&lt;/p&gt;

&lt;p&gt;Ich arbeite hauptsächlich als freiberuflicher Programmierer an Projekten für das iPhone, iPad und Mac. In meiner Freizeit (wenn ich welche habe), schreibe ich an meinen eigenen Mac Applikationen.&lt;/p&gt;

&lt;p&gt;Ein bisschen zu meiner Person: Ich habe jahrelang mein Geld als Java Programmierer von Webapplikationen verdient und war der Sprache und Platform überdrüssig geworden. Und mal ehrlich: Kein Mensch kann Desktop Applikationen in Java ernst nehmen. Vielleicht noch Eclipse, aber das war es auch schon.&lt;/p&gt;

&lt;p&gt;Jedenfalls habe ich dann begonnen Cocoa zu programmieren, als Hobby und noch bevor das iPhone Mainstream wurde. Mit dem Einzug von iPhone und später dem iPad habe ich eine Reihe von Projekten nebenberuflich geführt. Dies war so erfolgreich, dass ich mich später dazu entschied mich selbstständig zu machen. Und bis jetzt auch noch nicht bereut habe.&lt;/p&gt;

&lt;p&gt;Aus naheliegenden Gründen bin ich deshalb immer interessiert an Anfragen bzgl. neuer Projekte. Einfach ein Mail schicken an &lt;a href=&quot;http://stephan.michels@gmail.com&quot;&gt;stephan.michels@gmail.com&lt;/a&gt;&lt;/p&gt;</content><author><name>Stephan Michels</name></author><category term="Private" /><summary type="html">Hallo Zusammen, ich will ein Blog führen zu den täglichen Herausforderungen, auf die ich so während meiner Arbeit treffe, in der Hoffnung, dass der eine oder andere davon profitieren kann. Die meisten Artikel werden sich auf Cocoa Programmierung für die Mac und iOS Platform beziehen, da das mein Hauptarbeitsfeld und Hobby ist.</summary></entry></feed>