{"id":197651,"date":"2025-11-20T13:34:48","date_gmt":"2025-11-20T13:34:48","guid":{"rendered":"https:\/\/innovationspace.ansys.com\/knowledge\/?post_type=topic&#038;p=197651"},"modified":"2025-11-24T17:37:25","modified_gmt":"2025-11-24T17:37:25","slug":"implementing-gesture-controls-and-animations-in-scade","status":"publish","type":"topic","link":"https:\/\/innovationspace.ansys.com\/knowledge\/forums\/topic\/implementing-gesture-controls-and-animations-in-scade\/","title":{"rendered":"Implementing gesture controls and animations in SCADE"},"content":{"rendered":"<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-banner.jpeg\" style=\"max-height: 700px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Modern avionics applications increasingly rely on gesture\u2011based interactions: zooming into a map, rotating a tactical display, or adjusting range rings with intuitive two\u2011finger motions. To support these HMI paradigms, Ansys SCADE supports gesture-based controls. We illustrate these in our <a href=\"https:\/\/github.com\/ansys\/scade-example-multi-touch-cockpit\">scade-example-multi-touch-cockpit<\/a> model.<\/p>\n<p>The application supports advanced multi-touch gestures for intuitive interaction:<\/p>\n<ul>\n<li><strong>Swipe<\/strong>: Navigate between pages with a swipe gesture.<\/li>\n<li><strong>Pinch-to-Zoom<\/strong>: Adjust the zoom level of the map using pinch gestures.<\/li>\n<li><strong>Rotate<\/strong>: Rotate the map for customized views.<\/li>\n<\/ul>\n<p>All gesture logic is implemented in deterministic state machines and mathematical operators inside <strong>Ansys SCADE Suite<\/strong>.<\/p>\n<p>In this article, we&#8217;ll dive into it and explain how the logic for various gestures is implemented in the public example model.<\/p>\n<p>But first, let&#8217;s look at all three gestures in action:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-cockpit-gestures.gif\" style=\"max-height: 540px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<h3  id=\"OVERALL-GESTURE-ARCHITECTURE\">Overall gesture architecture<\/h3>\n<p>The gesture system is decomposed into three dedicated SCADE components:<\/p>\n<table style=\"max-width: 1000px\">\n<tr>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><strong>Gesture<\/strong><\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><strong>SCADE Node<\/strong><\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><strong>Purpose<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Swipe Navigation<\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><code>hmiManagement<\/code> (<code>posXManagement<\/code>\/ <code>mouseManagement<\/code>)<\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Slide between pages <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Pinch-to-Zoom<\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><code>zoomAndRotate<\/code><\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Map scaling<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Rotation<\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p><code>zoomAndRotate<\/code><\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px\">\n<p>Map rotation in degrees<\/p>\n<\/td>\n<\/tr>\n<\/table>\n<h3  id=\"SWIPE-GESTURE-NAVIGATING-BETWEEN-PAGES\">Swipe gesture: navigating between pages<\/h3>\n<p>The <strong>Swipe<\/strong> gesture is implemented in diagrams of the <code>hmiManagement<\/code> operator:<\/p>\n<ul>\n<li><code>mouseManagement<\/code> detects touch<a href=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-touch.gif\">,<\/a> click, long press, and the beginning of a swipe<\/li>\n<li><code>posXManagement<\/code> manages the horizontal sliding animation<\/li>\n<\/ul>\n<p>Let&#8217;s start by detecting the swipe. A swipe gesture begins when:<\/p>\n<ul>\n<li>a finger is pressed inside a valid area<\/li>\n<li>finger press time exceeds a certain duration<\/li>\n<\/ul>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-mouse-management-state-machine-fixed.svg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>When this state machine moves to state Selected, and we detect a movement delta, a swipe begins and the left (or right) panel starts sliding horizontally.<\/p>\n<p>To provide a legible user experience, the interface must also ensure that the <strong>selected area<\/strong> (PFD or HUD) appears <strong>in front<\/strong> of the other during the swipe. This is achieved by dynamically computing a <strong>drawing order<\/strong> that is transmitted to <strong>SCADE Display<\/strong>.<\/p>\n<p>In SCADE Display, every graphical layer or group (e.g., PFD area, HUD area, menus) has an integer <strong>Drawing Order<\/strong>. Layers with a <strong>higher value<\/strong> are drawn <strong>on top<\/strong> of layers with a lower value.<\/p>\n<p>In our model, when we detect a swipe, we detect which of the two halves of the screen is active (<code>PFD_AREA<\/code> or <code>HUD_AREA<\/code>). We then dynamically produce a <code>drawingOrders[]<\/code> output, sent to SCADE Display, which updates the Z-ordering of the graphics.<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-drawing-order-fixed.svg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<h3  id=\"PINCH-TO-ZOOM-GESTURE\">Pinch-to-zoom gesture<\/h3>\n<p>Pinch-to-zoom is implemented in the <code>zoomAndRotate<\/code> operator. As the name suggests, it also handles rotation, as both gestures require <strong>two active fingers<\/strong>:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-zoom-and-rotate-fixed.svg\" style=\"max-height: 800px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>Once both fingers are down, the <code>SM1<\/code> state machine transitions to zooming. Initial values are captured on the <em>raising edge<\/em> when both fingers are pressed, ensuring deterministic behavior.<\/p>\n<p>To compute the distance between the two fingers for pinch-to-zoom, we use the classic Pythagorean theorem ($c^2=a^2+b^2$).<\/p>\n<p>Let&#8217;s define:<\/p>\n<ul>\n<li>$p_0 = (x_0, y_0)$ : position of the first finger<\/li>\n<li>$p_1 = (x_1, y_1)$ : position of the second finger<\/li>\n<\/ul>\n<p>In our formula, we simply replace $a$ with $x_1\u2212x_0$, $b$ with $y_1\u2212y_0$, and replace the hypotenuse $c$ with $D^2$. We then apply the square root to both sides of the equation to isolate distance $D$:<\/p>\n<p>$D=\\sqrt{(x_1-x_0)^2+(y_1-y_0)^2}$<\/p>\n<p>Or, as a SCADE diagram:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-two-finger-distance-fixed.svg\" style=\"max-height: 250px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<p>After years of being told <em>&#8220;You&#8217;ll use this in real life someday!&#8221;<\/em> during math class, we can finally confirm: <strong>Pythagoras genuinely helps&#8230; manage zoom on a certifiable avionics cockpit map. <\/strong>Who knew the old Greek mathematician would become such a reliable co-pilot?<\/p>\n<p>When two fingers become active simultaneously, SCADE captures:<\/p>\n<ul>\n<li>the initial distance<\/li>\n<li>the initial zoom factor<\/li>\n<li>the initial finger positions<\/li>\n<\/ul>\n<p>$$D_{begin}=\\sqrt{(x_{1,begin}-x_{0,begin})^2+(y_{1,begin}-y_{0,begin})^2}$$<\/p>\n<p>At every cycle during the gesture, we compute the current finger distance:<\/p>\n<p>$$D_{current}=\\sqrt{(x_1-x_0)^2+(y_1-y_0)^2}$$<\/p>\n<p>This formulation naturally handles all scenarios:<\/p>\n<ul>\n<li>If $D_{current}&gt;D_{begin}$, the user is pinching out and the map zooms in.<\/li>\n<li>If $D_{current}=D_{begin}$, the user is not pinching and zoom factor stays the same.<\/li>\n<li>Otherwise, the user is pinching in and the map zooms out.<\/li>\n<\/ul>\n<p>As a SCADE diagram, this yields:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-zoom-factor-fixed.svg\" style=\"max-height: 300px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<h3  id=\"TWO-FINGER-ROTATION-GESTURE\">Two-finger rotation gesture<\/h3>\n<p>Rotation uses the <strong>orientation of the segment<\/strong> defined by the two fingers. At each cycle, we compute the angle of this segment using the atan2 function, compare it to the initial angle, and compute the difference.<\/p>\n<p>Again, let&#8217;s define:<\/p>\n<ul>\n<li>$p_0 = (x_0, y_0)$ : position of the first finger<\/li>\n<li>$p_1 = (x_1, y_1)$ : position of the second finger<\/li>\n<\/ul>\n<p>We first build the vector from finger 0 to finger 1:<\/p>\n<p>$$\\vec{v}=(dx,dy)=(x_1-x_0, y_1-y_0)$$<\/p>\n<p>The <strong>orientation<\/strong> of this vector is:<\/p>\n<p>$$\\theta=atan2(dy,dx)$$<\/p>\n<p>$atan2$ returns the angle in <strong>radians<\/strong>, in the range $(-\\pi, \\pi]$, taking into account the signs of both $dx$ and $dy$. Unlike a simple arctangent, $atan2$ correctly distinguishes all four quadrants, which is essential for a robust rotation gesture.<\/p>\n<ul>\n<li>$\\theta_{current}$: angle at the current frame<\/li>\n<li>$\\theta_{init}$: angle at the init frame (built from <code>oP0<\/code>, <code>oP1<\/code>)<\/li>\n<\/ul>\n<p>The incremental change is:<\/p>\n<p><em>$$\\Delta\\theta=\\theta_{current}-\\theta_{init}$$<\/em><\/p>\n<p>The SCADE model then converts this delta from radians to degrees and adds it to the starting angle of the gesture:<\/p>\n<p>$$\\Delta\\theta_{deg}=\\Delta\\theta\\times\\frac{360}{2\\pi}$$<\/p>\n<p>Or, as a SCADE diagram:<\/p>\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-056-rotate-angle-fixed.svg\" style=\"max-height: 400px !important\" \/><br \/>\n    <em><\/em>\n<\/p>\n<h3  id=\"CONCLUSION\">Conclusion<\/h3>\n<p>In this article, we explored implementation of swipe navigation, pinch-to-zoom, and rotation gestures in SCADE. We showed how complex multi-touch behavior can be modeled with graphical state machines, computed using mathematical operators, translated into deterministic C code, and deployed in avionics-grade HMIs. This approach provides a reusable foundation for touchscreen interactions on MFDs, HUDs, map displays, and tactical interfaces.<\/p>\n<p>If you&#8217;d like to explore the model used in this article, you can find it <a href=\"https:\/\/github.com\/ansys\/scade-example-multi-touch-cockpit\">here on the Ansys GitHub<\/a> (<a href=\"https:\/\/multi-touch-cockpit.examples.scade.docs.pyansys.com\/\">link to docs<\/a>).<\/p>\n<h3  id=\"ABOUT-THE-AUTHOR\">About the author<\/h3>\n<table style=\"max-width: 1000px;border: none !important\">\n<tr>\n<td style=\"padding: 0px 10px;min-width: 150px;border: none !important\">\n<p style=\"text-align: center\">\n    <img decoding=\"async\" src=\"https:\/\/innovationspace.ansys.com\/knowledge\/wp-content\/uploads\/sites\/4\/2025\/11\/scade-053-author.png\" style=\"max-height: 150px !important\" \/><br \/>\n                <em><\/em>\n<\/p>\n<\/td>\n<td style=\"padding: 0px 10px;min-width: 150px;border: none !important\">\n<p><strong>Ludovic Oddos<\/strong> (<a href=\"https:\/\/www.linkedin.com\/in\/ludovicoddos\/\">LinkedIn<\/a>) is a Lead Product Specialist at Ansys. He has been supporting SCADE field engagements, in many industries, for more than 15 years. He has deep expertise in embedded software and its integration into various target environments.<\/p>\n<\/td>\n<\/tr>\n<\/table>\n","protected":false},"template":"","class_list":["post-197651","topic","type-topic","status-publish","hentry","topic-tag-gestures","topic-tag-hmi","topic-tag-pinch","topic-tag-rotate","topic-tag-scade-display","topic-tag-scade-suite","topic-tag-swipe","topic-tag-zoom"],"aioseo_notices":[],"acf":[],"custom_fields":[{"0":{"_edit_lock":["1764005777:1769"],"_edit_last":["1769"],"_aioseo_title":[null],"_aioseo_description":[null],"_aioseo_keywords":["a:0:{}"],"_aioseo_og_title":[""],"_aioseo_og_description":[""],"_aioseo_og_article_section":[""],"_aioseo_og_article_tags":["a:0:{}"],"_aioseo_twitter_title":[""],"_aioseo_twitter_description":[""],"filter_by_optics_product":["Lumerical"],"_filter_by_optics_product":["field_64fb192ba3121"],"application_name":[""],"_application_name":["field_64a80903c8e15"],"family":[""],"_family":["field_64a809229a857"],"siebel_km_number":[""],"_siebel_km_number":["field_63ecbffce60db"],"salesforce_km_number":[""],"_salesforce_km_number":["field_63ecc018e60dc"],"km_published_date":[""],"_km_published_date":["field_64c77704499dd"],"product_version":[""],"_product_version":["field_64c776cb4fd2e"],"_bbp_forum_id":["27825"],"_bbp_topic_id":["197671"],"_bbp_author_ip":["213.68.15.130"],"_bbp_last_reply_id":["0"],"_bbp_last_active_id":["197652"],"_bbp_last_active_time":["2025-11-20 13:34:48"],"_bbp_reply_count":["0"],"_bbp_reply_count_hidden":["0"],"_bbp_voice_count":["0"],"_btv_view_count":["445"],"_bbp_likes_count":["4"]},"test":"solution"}],"_links":{"self":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/197651","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics"}],"about":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/types\/topic"}],"version-history":[{"count":7,"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/197651\/revisions"}],"predecessor-version":[{"id":197671,"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/topics\/197651\/revisions\/197671"}],"wp:attachment":[{"href":"https:\/\/innovationspace.ansys.com\/knowledge\/wp-json\/wp\/v2\/media?parent=197651"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}