{"id":638,"date":"2025-03-03T09:43:48","date_gmt":"2025-03-03T00:43:48","guid":{"rendered":"https:\/\/barbegenerativediary.com\/en\/?p=638"},"modified":"2025-06-20T10:12:40","modified_gmt":"2025-06-20T01:12:40","slug":"fabrik-forward-and-backward-reaching-inverse-kinematics-in-processing","status":"publish","type":"post","link":"https:\/\/barbegenerativediary.com\/en\/tutorials\/fabrik-forward-and-backward-reaching-inverse-kinematics-in-processing\/","title":{"rendered":"FABRIK &#8211; Forward And Backward Reaching Inverse Kinematics in Processing"},"content":{"rendered":"\n<p>This article introduces the FABRIK algorithm, a method used for inverse kinematics in applications like robotic arms and character animation. Unlike traditional approaches that rely on joint rotations and matrix calculations, FABRIK adjusts segments forward and backward iteratively using simple geometric calculations to reach the target position.<\/p>\n\n\n\n<p><strong>The full sample code for this article is available for download on Patreon after following.<\/strong><br>(It uses Processing for the implementation.)<br>\u2615 <strong>Support my Work:) \/  <a href=\"https:\/\/www.patreon.com\/barbe_generative_diary\/membership\" target=\"_blank\" rel=\"noopener\" title=\"\">Coffee Supplier on Patreon<\/a><\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Understanding FABRIK<\/strong><\/h2>\n\n\n\n<p>FABRIK (Forward And Backward Reaching Inverse Kinematics) was proposed in 2011 by Andreas Aristidou and Joan Lasenby as a more intuitive and efficient alternative to traditional inverse kinematics methods. Instead of calculating joint angles, FABRIK moves each segment based on its distance to the target while maintaining segment lengths.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How FABRIK Works<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Forward Reaching:<\/strong><br>1. Move the end effector towards the target position.<br>2. Adjust each joint sequentially while preserving segment lengths.<\/li>\n\n\n\n<li><strong>Backward Reaching:<\/strong><br>1. Fix the root position.<br>2. Adjust the joints in reverse order to maintain segment lengths and refine alignment.<\/li>\n<\/ul>\n\n\n\n<p>These steps repeat until the end effector is close enough to the target.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Comparison with Other Methods<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CCD (Cyclic Coordinate Descent):<\/strong>&nbsp;Adjusts each joint individually to get closer to the target. It\u2019s simple and fast but doesn\u2019t always guarantee smooth movement.<\/li>\n\n\n\n<li><strong>Jacobian Inverse Methods:<\/strong>&nbsp;Uses matrices to determine optimal movements. While effective, they require complex calculations and can be computationally expensive.<\/li>\n\n\n\n<li><strong>FABRIK:<\/strong>&nbsp;Intuitive, fast, and avoids complex matrix operations, making it ideal for real-time applications.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Implementing FABRIK in Processing<\/strong><\/h2>\n\n\n\n<p>Here\u2019s how to implement FABRIK in Processing step by step.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1. Define the EndEffector Class<\/strong><\/h3>\n\n\n\n<p>Each end effector represents a joint in the kinematic chain. It has a position and a fixed length, which ensures that movements adhere to the constraints of the system.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nclass EndEffector {\n\u00a0\u00a0\u00a0\u00a0\u00a0PVector pos;\n\u00a0\u00a0\u00a0\u00a0\u00a0float leng;\n\u00a0\u00a0\u00a0\u00a0\u00a0EndEffector(float x, float y, float len) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pos = new PVector(x, y);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0leng = len;\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2. Initialize the End Effectors<\/strong><\/h3>\n\n\n\n<p>We create a list of end effectors, defining a chain of connected joints. The number of end effectors determines the flexibility of the system.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nArrayList<EndEffector> effectors = new ArrayList<>();\nint numEffectors = 10;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3. Forward Reaching<\/strong><\/h3>\n\n\n\n<p>The forward reaching step moves the end effector toward the target while keeping all segment lengths fixed.<\/p>\n\n\n\n<p><strong>3-1. Set the end effector&#8217;s position to the target<\/strong><br>Since the end effector is the last joint, we move it directly to the target position.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nEndEffector endEffector = effectors.get(effectors.size() - 1);\nendEffector.pos = target.copy();\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1024\" height=\"576\" data-src=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/01Forward.webp\" alt=\"\" class=\"wp-image-639 lazyload\" data-srcset=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/01Forward.webp 1024w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/01Forward-300x169.webp 300w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/01Forward-768x432.webp 768w\" data-sizes=\"(max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/576;\" \/><\/figure>\n\n\n\n<p><strong>3-2. Move each joint toward the next one<\/strong><br>We iterate backward from the second-to-last joint to the first. Each joint moves toward the next joint (closer to the target) while preserving its length.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nfor (int i = effectors.size() - 2; i >= 0; i--) {\n     EndEffector current = effectors.get(i);\n     PVector direction = PVector.sub(endEffector.pos, current.pos); \/\/ Calculate direction\n     direction.setMag(current.leng); \/\/ Set vector magnitude to match segment length\n     current.pos = PVector.sub(endEffector.pos, direction); \/\/ Move joint to new position\n     endEffector = current;\n}\n<\/code><\/pre>\n\n\n\n<p>The <a href=\"https:\/\/processing.org\/reference\/PVector_setMag_.html\">setMag(current.length)<\/a>&nbsp;method scales the vector to ensure that the joint moves <strong>exactly<\/strong>&nbsp;the correct distance while maintaining constraints.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4. Backward Reaching<\/strong><\/h3>\n\n\n\n<p>After the forward reaching step, the root position may have moved. The backward reaching step restores the root to its original position while preserving segment lengths.<\/p>\n\n\n\n<p><strong>4-1. Fix the root position<\/strong><br>The root (first joint) remains fixed at its initial position.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nEndEffector previous = effectors.get(0);\nprevious.pos = root;\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1024\" height=\"576\" data-src=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/02Backward.webp\" alt=\"\" class=\"wp-image-640 lazyload\" data-srcset=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/02Backward.webp 1024w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/02Backward-300x169.webp 300w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2025\/03\/02Backward-768x432.webp 768w\" data-sizes=\"(max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/576;\" \/><\/figure>\n\n\n\n<p><strong>4-2. Move each joint forward<\/strong><br>We iterate through the chain from the root toward the end effector, adjusting each joint while keeping segment lengths fixed.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nfor (int i = 1; i < effectors.size(); i++) {\n\u00a0\u00a0\u00a0\u00a0\u00a0EndEffector current = effectors.get(i);\n\u00a0\u00a0\u00a0\u00a0\u00a0PVector direction = PVector.sub(current.pos, previous.pos); \/\/ Calculate direction\n\u00a0\u00a0\u00a0\u00a0\u00a0direction.setMag(previous.leng); \/\/ Maintain segment length\n\u00a0\u00a0\u00a0\u00a0\u00a0current.pos = PVector.add(previous.pos, direction); \/\/ Move joint to new position\n\u00a0\u00a0\u00a0\u00a0\u00a0previous = current;\n}\n<\/code><\/pre>\n\n\n\n<p>This step ensures that the chain remains connected and respects length constraints while aligning properly with the root.<\/p>\n\n\n\n<p><strong>5. Visualizing the End Effectors<\/strong><\/p>\n\n\n\n<p>We draw lines between end effectors to visualize the kinematic chain and observe its movement in real-time.<\/p>\n\n\n\n<pre><code class=\"language-processing\">\nfor (int i = 0; i < effectors.size() - 1; i++) {\n\u00a0\u00a0\u00a0\u00a0\u00a0PVector current = effectors.get(i).pos;\n\u00a0\u00a0\u00a0\u00a0\u00a0PVector next = effectors.get(i + 1).pos;\n\u00a0\u00a0\u00a0\u00a0\u00a0line(current.x, current.y, next.x, next.y);\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Final Thoughts<\/strong><\/h3>\n\n\n\n<p>FABRIK is a simple yet efficient algorithm for inverse kinematics, making it a great choice for real-time applications. You can extend this implementation by adding constraints for joint rotation or adapting it to work in 3D.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>If you need the complete code, it is available for download in the attached file on <a href=\"https:\/\/www.patreon.com\/posts\/fabrik-forward-123304151?utm_medium=clipboard_copy&amp;utm_source=copyLink&amp;utm_campaign=postshare_creator&amp;utm_content=join_link\" target=\"_blank\" rel=\"noopener\" title=\"\">Patreon<\/a>.<\/strong><\/li>\n\n\n\n<li><strong>For a deeper dive into the theory behind FABRIK, check out the research paper \"FABRIK: A fast, iterative solver for the Inverse Kinematics problem\"&nbsp;by Andreas Aristidou and Joan Lasenby.<\/strong><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Recommended Book<\/em><\/h2>\n\n\n\n<p><a href=\"https:\/\/amzn.to\/3EBuSDS\">\"Grid Systems in Graphic Design\" by Josef M\u00fcller-Brockmann\"<\/a><\/p>\n\n\n\n<p>This book discusses grid systems, a layout method that enhances design coherence and readability by arranging text and images based on continuous rows and columns. Originally conceived for print layouts, grid systems are now utilized in all design fields, including web design. Even when creating 2D graphics with tools like Processing or P5.js, there is much to learn from this system. First published in 1981.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"1024\" height=\"576\" data-src=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2023\/06\/Grid-Systems-Raster-Systeme.webp\" alt=\"Grid-Systems-Raster-Systeme\" class=\"wp-image-244 lazyload\" data-srcset=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2023\/06\/Grid-Systems-Raster-Systeme.webp 1024w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2023\/06\/Grid-Systems-Raster-Systeme-300x169.webp 300w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2023\/06\/Grid-Systems-Raster-Systeme-768x432.webp 768w\" data-sizes=\"(max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/576;\" \/><\/figure>\n\n\n\n<p>\ud83c\udf10 <strong>Support my Website<\/strong><br>By using our affiliate links, you\u2019re helping my content and allows me to keep creating valuable articles. I appreciate it so much:)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"BGD_SOUNDS\"><em>BGD_SOUNDS (barbe_generative_diary SOUNDS)<\/em><\/h2>\n\n\n\n<p>barbe_generative_diary SOUNDS will start sharing and selling a variety of field recordings collected for use in my artwork \u201cSound Visualization\u201d experiments. All sounds are royalty-free.<\/p>\n\n\n\n<p><a href=\"https:\/\/barbegenerativediary.bandcamp.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Link \/ BGD_SOUNDS on bandcamp<\/strong><\/a><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" width=\"1024\" height=\"731\" data-src=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2024\/07\/240801_bandcamp-top-BGD_SOUNDS.webp\" alt=\"\" class=\"wp-image-554 lazyload\" data-srcset=\"https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2024\/07\/240801_bandcamp-top-BGD_SOUNDS.webp 1024w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2024\/07\/240801_bandcamp-top-BGD_SOUNDS-300x214.webp 300w, https:\/\/barbegenerativediary.com\/en\/wp-content\/uploads\/2024\/07\/240801_bandcamp-top-BGD_SOUNDS-768x548.webp 768w\" data-sizes=\"(max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/731;\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>This article introduces the FABRIK algorithm, a method used for inverse kinematics in applications like robotic arms and character animation.<\/p>\n","protected":false},"author":1,"featured_media":641,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15,13],"tags":[],"class_list":["post-638","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-processing-tutorials","category-tutorials"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/posts\/638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/comments?post=638"}],"version-history":[{"count":7,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/posts\/638\/revisions"}],"predecessor-version":[{"id":783,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/posts\/638\/revisions\/783"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/media\/641"}],"wp:attachment":[{"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/media?parent=638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/categories?post=638"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/barbegenerativediary.com\/en\/wp-json\/wp\/v2\/tags?post=638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}