This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/anatomy/widget/mat4d-control.html
T
2026-09-09 17:35:23 +08:00

183 lines
9.8 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mat4dControl Component | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Mat4dControl Component | HiAPI-C# 2025 ">
<link rel="icon" href="../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../public/docfx.min.css">
<link rel="stylesheet" href="../../public/main.css">
<meta name="docfx:navrel" content="../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Anatomy-Mat4dControl">
<h1 id="mat4dcontrol-component">Mat4dControl Component</h1>
<p>Mat4dControl edits and displays a 4x4 transform matrix. It is an embedded widget with no route and
no Control-Tree node of its own, reached only through the editor that hosts it.</p>
<h2 id="key-model">Key Model</h2>
<p>The persisted model is <a class="xref" href="../../api/Hi.Geom.Mat4d.html">Mat4d</a>, exposed over <code>/api/Mat4d</code> by <code>Widget/Mat4dController.cs</code>.</p>
<p>The widget's own model is a plain array of sixteen numbers, exported as <code>type Mat4</code> from
<code>wwwroot-src/src/components/widgets/Mat4Input.vue</code>. The layout is column-major, matching the backend
Mat4d: cell (row, col) resolves to index <code>col * 4 + row</code>, so indices 0 to 3 are the first column and
12 to 15 the translation column. <code>wwwroot-src/src/api/transformer.ts</code> states the same column-major
contract on the wire. A model shorter than sixteen numbers, or not an array at all, is padded out
with zeros before display, and a longer one is truncated to sixteen.</p>
<p>The widget carries no key and calls no endpoint. Its host,
<code>wwwroot-src/src/components/topo/StaticFreeformEditor.vue</code>, binds it with <code>v-model</code> and persists
each change through <code>updateStaticFreeformMat</code> from <code>wwwroot-src/src/api/transformer.ts</code>, which posts
the whole sixteen-number array to <code>/api/StaticFreeform/Update</code>; <code>Mech/Topo/StaticFreeformController.cs</code>
rejects a payload that is not exactly sixteen elements.</p>
<p>The props are <code>modelValue</code>, <code>disable</code>, <code>readonly</code>, <code>identity</code> (on by default) and <code>invert</code> (off by
default), and the emits are <code>update:modelValue</code>, <code>identity</code> and <code>invert</code>. <code>disable</code> both disables
the cells and dims the whole block.</p>
<h2 id="layout">Layout</h2>
<ul>
<li>Mat4dControl
<ul>
<li><code>Matrix Grid</code> — four rows of four numeric cells, each cell right-aligned</li>
<li><code>Identity Button</code> — present when the identity flag is set, which is the default</li>
<li><code>Invert Button</code> — present only when the invert flag is set</li>
</ul>
</li>
</ul>
<p>The cells and both buttons are inactive while the control is disabled or readonly.</p>
<h2 id="feature">Feature</h2>
<h3 id="single-input-mode">Single input mode</h3>
<p>The grid of sixteen cells is the only editing surface, and each cell shows the full precision of its
number with no rounding for display.</p>
<h3 id="matrix-operations">Matrix operations</h3>
<ul>
<li>Identity — the button raises an <code>identity</code> event and writes nothing itself; the host supplies the
matrix. StaticFreeformEditor pushes its own identity constant through <code>updateStaticFreeformMat</code>.</li>
<li>Invert — the button raises an <code>invert</code> event and computes nothing itself. StaticFreeformEditor
calls <code>invertStaticFreeformMat</code>, which posts to <code>/api/StaticFreeform/InvertMat</code> and feeds the
sixteen numbers that come back into the model.</li>
</ul>
<h3 id="commit-and-special-values">Commit and special values</h3>
<p>Each cell commits on blur or Enter, and the widget emits the entire sixteen-number array rather than
a single index. An unparseable cell reverts to its previous value, an empty cell becomes 0, and a
cell whose parsed value is unchanged emits nothing. Formatting and parsing are local to the
component: Infinity and -Infinity are shown and parsed as literal text, while NaN and a missing cell
both display as 0, so NaN is not round-tripped.</p>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../index.html">HiNC App Anatomy</a> for git repository links.</p>
<ul>
<li><code>wwwroot-src/src/components/widgets/Mat4Input.vue</code> — the widget itself: the column-major
sixteen-cell grid, the Identity and Invert buttons, and the local format, parse and commit helpers</li>
<li><code>wwwroot-src/src/components/topo/StaticFreeformEditor.vue</code> — the host, and the full binding
contract in one place: <code>v-model</code>, the two button flags, <code>@update:model-value</code>, <code>@identity</code>, <code>@invert</code></li>
<li><code>wwwroot-src/src/api/transformer.ts</code> — <code>updateStaticFreeformMat</code> and <code>invertStaticFreeformMat</code></li>
<li><code>Mech/Topo/StaticFreeformController.cs</code> — the backend behind those two endpoints: Update takes a
sixteen-element array, InvertMat returns the inverted sixteen numbers</li>
<li><code>Widget/Mat4dController.cs</code> — the <code>/api/Mat4d</code> REST surface: New, NewWithValue, Get, Update,
UpdateAt, ParseAndUpdate, SetIdentity, Transpose and Inverse. The SPA reaches none of them; the
widget's host persists through the StaticFreeform endpoints instead.</li>
<li><code>wwwroot-src/src/i18n/en/widgets.ts</code> — the Invert label and both button tooltips under <code>widgets.matInput</code></li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="vec3d-control.html">Vec3dControl Component</a> — the sibling numeric-geometry editor, and the one a reader usually wants next</li>
<li><a class="xref" href="../conventions/numeric-io-utilities.html">Numeric Input/Output</a> — why NaN and the infinities are text on the wire, and why NaN does not survive this grid</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>