瀏覽代碼

fixed some errors

Martin Thoma 11 年之前
父節點
當前提交
7fdc530b6c

+ 42 - 0
documents/math-minimal-distance-to-cubic-function/constant-visualization/constant-vis.html

@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- saved from url=(0112)file:///home/moose/Downloads/LaTeX-examples/documents/math-minimal-distance-to-cubic-function/quadratic-vis.html -->
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta charset="UTF-8">
+        <title>Quadratic visualization</title>
+        <style type="text/css">
+            span.hint {
+	            border-bottom:1px dotted #666;
+            }
+        </style>
+    </head>
+    <body>
+        <table>
+            <tbody><tr>
+                <td><span class="hint" title="constat">c</span></td>
+                <td><input type="number" step="1" value="1" id="c" onchange="updateBoard()"></td>
+            </tr>
+            <tr>
+                <td><span class="hint" title="">STRETCH_X</span></td>
+                <td><input type="number" step="1" value="3" id="STRETCH_X" min="1" onchange="updateBoard()"></td>
+                <td><span class="hint" title="">STRETCH_Y</span></td>
+                <td><input type="number" step="0.25" value="0.5" id="STRETCH_Y" min="0.1" onchange="updateBoard()"></td>
+                <td><span class="hint" title="">X_OFFSET</span></td>
+                <td><input type="number" step="16" value="-128" id="X_OFFSET" onchange="updateBoard()"></td>
+                <td><span class="hint" title="">Y_OFFSET</span></td>
+                <td><input type="number" step="16" value="256" id="Y_OFFSET" onchange="updateBoard()"></td>
+            </tr>
+            <tr>
+                <td><span class="hint" title="visualize distance">pDistance</span></td>
+                <td><input type="checkbox" id="pDistance" onchange="updateBoard()"></td>
+                <td><span class="hint" title="How much will points be spread for voronoi? USE 1 WITH CAUTION! The bigger the value, the quicker the computation.">spread</span></td>
+                <td><input type="number" step="1" value="1" id="density" min="1" onchange="updateBoard()"></td>
+                <td><a href="constant-vis.html">clear board</a></td>
+            </tr>
+        </tbody></table>
+        <canvas id="myCanvas" width="1316" height="535" style="border: 1px solid rgb(0, 0, 0); cursor: crosshair;"> </canvas>
+    <script type="text/javascript" src="constant-vis.js">
+
+    </script>
+
+
+</body></html>

+ 233 - 0
documents/math-minimal-distance-to-cubic-function/constant-visualization/constant-vis.js

@@ -0,0 +1,233 @@
+'use strict';
+
+/* global variables */
+var STRETCH_X = 3;
+var STRETCH_Y = 0.5;
+var X_MIN = -10;
+var X_MAX = +10;
+var Y_MIN = -10;
+var Y_MAX = +10;
+var X_OFFSET = -128;
+var Y_OFFSET = 256;
+var INITIAL_RADIUS = 20;
+var POINT_RADIUS = 5;
+
+/*******************************************************************/
+/* Graphics                                                        */
+/*******************************************************************/
+/** 
+ * Calculates coordinates from worldspace to screenspace
+ * @param {Number} x the coordinate you want to transform
+ * @param {bool} isX true iff x is a x-coordinate, otherwise false
+ * @return {Number} transformed coordinate
+ */
+function c(x, isX) {
+    if (isX) {
+        return STRETCH_X * (x - X_OFFSET);
+    }
+
+    return STRETCH_Y * (-x + Y_OFFSET);
+}
+
+/** 
+ * Calculates coordinates from screenspace to worldspace
+ * @param {Number} x the coordinate you want to transform
+ * @param {bool} isX true iff x is a x-coordinate, otherwise false
+ * @return {Number} transformed coordinate
+ */
+function r(x, isX) {
+    if (isX) {
+        return (x / STRETCH_X) + X_OFFSET;
+    }
+
+    return (-x / STRETCH_Y) + Y_OFFSET;
+}
+
+function setCursorByID(id,cursorStyle) {
+    var elem;
+    if (document.getElementById &&
+    (elem=document.getElementById(id)) ) {
+        if (elem.style) elem.style.cursor=cursorStyle;
+    }
+}
+
+function drawEllipse(centerX, centerY, width, height) {
+    context.beginPath() ;
+
+    var x             = centerX;
+    var y             = centerY;
+    var rx            = width;
+    var ry            = height;
+    var rotation      = 0; // The rotation of the ellipse (in radians)
+    var start         = 0; // The start angle (in radians)
+    var end           = 2 * Math.PI; // The end angle (in radians)
+    var anticlockwise = false;
+
+    context.ellipse(x, y, rx, ry, rotation, start, end, anticlockwise);
+    context.fillStyle = "rgba(255, 0, 0, 0.5)";
+    context.fill();
+}
+
+function getColor(i, transparency) {
+    //var t = (i+1)*(360/k);
+    //var color = 'hsla('+t+', 100%, 50%, '+transparency+')';
+    var x = i / 256;
+    if (x > 1) {x = 1.0;}
+    x = parseInt(x*255);
+    var color = 'rgba('+x+','+x+','+x+','+transparency+')';
+    return color;
+}
+
+function drawFunction(canvas) {
+    var add = parseInt(document.getElementById("density").value);
+
+    context.beginPath();
+    context.fillStyle = 'red';
+
+    context.moveTo(0, c(getValue(r(0))), false);
+    for (var xS=0; xS < canvas.width; xS+=add) {
+        var x = r(xS);
+        var y = getValue(x);
+        context.lineTo(c(x, true), c(y, false));
+    }
+
+    context.closePath();
+    context.stroke();
+}
+
+/*******************************************************************/
+/* Math                                                            */
+/*******************************************************************/
+function euklideanDist(p1, p2) {
+    return Math.sqrt(
+                  Math.pow(p1["x"]-p2["x"], 2) 
+                + Math.pow(p1["y"]-p2["y"], 2));
+}
+
+/** 
+ * Calculates the value of a constant function at x
+ * @param {Number} x
+ * @return {Number} f(x)
+ */
+function getValue(x) {
+    var c1 = parseFloat(document.getElementById("c").value);
+    return c1;
+}
+
+/** 
+ * Calculates the drivate f'(x)
+ * @param {Number} x
+ * @return {Number} f'(x)
+ */
+function getDValue(x) {
+    var a = parseFloat(document.getElementById("a").value);
+    var b = parseFloat(document.getElementById("b").value);
+    return 2*a*x+b;
+}
+
+/** 
+ * Calculates the drivate f''(x)
+ * @param {Number} x
+ * @return {Number} f''(x)
+ */
+function getDDValue(x) {
+    var a = parseFloat(document.getElementById("a").value);
+    return 2*a;
+}
+
+/** 
+ * Calculates (f(x)^2)' = ((a*x*x+b*x+c)^2)' = 2 (b + 2 a x) (c + x (b + a x))
+ * @param {Number} x
+ * @return {Number} (f(x)^2)'
+ */
+function gedSquaredValueD(x) {
+    var a = parseFloat(document.getElementById("a").value);
+    var b = parseFloat(document.getElementById("b").value);
+    var c1 = parseFloat(document.getElementById("c").value);
+    return 2*(2*a*x+b)*(x*(a*x+b)+c1);
+}
+
+/** 
+ * Calculates (f(x)^2)'' = ((a*x*x+b*x+c)^2)'' = 2 (b^2 + 6 a b x + 2 a (c + 3 a x^2))
+ * @param {Number} x
+ * @return {Number} (f(x)^2)''
+ */
+function gedSquaredValueDD(x) {
+    var a = parseFloat(document.getElementById("a").value);
+    var b = parseFloat(document.getElementById("b").value);
+    var c1 = parseFloat(document.getElementById("c").value);
+
+    return 2*(b*b+6*a*b*x+2*a*(c1+3*a*x*x));
+}
+
+function findMin(p) {
+    return p.x;
+}
+
+/*******************************************************************/
+/* Start / Update                                                  */
+/*******************************************************************/
+function drawBoard(canvas, mouseCoords, radius) {
+    var context = canvas.getContext('2d');
+    context.canvas.width  = window.innerWidth - 50;
+    context.canvas.height = window.innerHeight - 120;
+    context.clearRect(0, 0, canvas.width, canvas.height);
+
+    drawFunction(canvas);
+    if (document.getElementById("pDistance").checked) {
+        var add = parseInt(document.getElementById("density").value)+10;
+        for (var x=0; x < canvas.width; x+=add) {
+            for (var y=0; y < canvas.height; y+=add) {
+                var dist = getDist({"x":r(x,true), "y":r(y,false)}, findMin({"x":r(x,true), "y":r(y,false)}));
+                context.fillStyle = getColor(dist,0.5);
+                context.fillRect(x, y, add/2, add/2);
+            }
+        }
+    }
+}
+
+function updateBoard(){
+    var canvas = document.getElementById("myCanvas");
+    STRETCH_X = parseFloat(document.getElementById("STRETCH_X").value);
+    STRETCH_Y = parseFloat(document.getElementById("STRETCH_Y").value);
+    X_OFFSET = parseFloat(document.getElementById("X_OFFSET").value);
+    Y_OFFSET = parseFloat(document.getElementById("Y_OFFSET").value);
+    drawBoard(canvas, {"x":0,"y":0}, INITIAL_RADIUS);
+}
+
+var canvas = document.getElementById("myCanvas");
+var context = canvas.getContext("2d");
+drawBoard(canvas, {"x":0,"y":0}, INITIAL_RADIUS);
+setCursorByID("myCanvas", "crosshair");
+
+/** get the current position of the mouse */
+function getMouseCoords(canvas, evt) {
+    var rect = canvas.getBoundingClientRect();
+    return {
+        "x": evt.clientX - rect.left,
+        "y": evt.clientY - rect.top
+    };
+}
+
+/** event listeners */
+canvas.addEventListener('mousemove',
+    function (evt) {
+        var mouseCoords = getMouseCoords(canvas, evt);
+        drawBoard(canvas, mouseCoords, 10);
+        // draw coordinates next to mouse
+        context.fillStyle = "blue";
+        context.font = "bold 16px Arial";
+        var x = r(mouseCoords.x, true).toFixed(3);
+        var y = r(mouseCoords.y, false).toFixed(3);
+        context.fillText("(" + x + ", " + y + ")", mouseCoords.x + 5, mouseCoords.y - 5);
+        var minX = findMin({"x": r(mouseCoords.x,true), "y": r(mouseCoords.y,false)});
+        var minY = getValue(minX);
+        context.beginPath();
+        context.moveTo(c(minX,true), c(minY, false));
+        context.lineTo(mouseCoords.x, mouseCoords.y, false);
+        context.stroke();
+        var minRadius = euklideanDist({"x": r(mouseCoords.x,true), "y": r(mouseCoords.y,false)}, {"x":minX,"y":minY});
+        
+        /* Draw circle */
+        drawEllipse(mouseCoords.x, mouseCoords.y, minRadius*STRETCH_X, minRadius*STRETCH_Y);
+    }, false);

二進制
documents/math-minimal-distance-to-cubic-function/math-minimal-distance-to-cubic-function.pdf


+ 3 - 6
documents/math-minimal-distance-to-cubic-function/problem-description.tex

@@ -1,18 +1,15 @@
 \chapter{Description of the Problem}
 Let $f: D \rightarrow \mdr$ with $D \subseteq \mdr$ be a polynomial function and $P \in \mdr^2$
 be a point. Let $d_{P,f}: \mdr \rightarrow \mdr_0^+$
-be the Euklidean distance of a point $P$ and a point $\left (x, f(x) \right )$
+be the Euklidean distance of a point $P$ to a point $\left (x, f(x) \right )$
 on the graph of $f$:
 \[d_{P,f} (x) := \sqrt{(x_P - x)^2 + (y_P - f(x))^2}\]
 
 Now there is finite set $M = \Set{x_1, \dots, x_n} \subseteq D$ of minima for given $f$ and $P$:
 \[M = \Set{x \in D | d_{P,f}(x) = \min_{\overline{x} \in D} d_{P,f}(\overline{x})}\] 
 
-But minimizing $d_{P,f}$ is the same as minimizing $d_{P,f}^2$:
-\begin{align}
-    d_{P,f}(x)^2    &= \sqrt{(x_P - x)^2 + (y_P - f(x))^2}^2\\
-                &= x_p^2 - 2x_p x + x^2 + y_p^2 - 2y_p f(x) + f(x)^2
-\end{align}
+But minimizing $d_{P,f}$ is the same as minimizing 
+$d_{P,f}^2 = x_p^2 - 2x_p x + x^2 + y_p^2 - 2y_p f(x) + f(x)^2$.
 
 \begin{theorem}[Fermat's theorem about stationary points]\label{thm:required-extremum-property}
     Let $x_0$ be a local extremum of a differentiable function $f: \mathbb{R} \rightarrow \mathbb{R}$.

+ 5 - 6
documents/math-minimal-distance-to-cubic-function/quadratic-min-visualization/quadratic-vis.js

@@ -78,7 +78,7 @@ function getColor(i, transparency) {
     return color;
 }
 
-function drawQuadraticFunction(canvas) {
+function drawFunction(canvas) {
     var add = parseInt(document.getElementById("density").value);
 
     context.beginPath();
@@ -88,7 +88,6 @@ function drawQuadraticFunction(canvas) {
     for (var xS=0; xS < canvas.width; xS+=add) {
         var x = r(xS);
         var y = getValue(x);
-        //context.fillRect(c(x), c(y, false), add/2, add/2);
         context.lineTo(c(x, true), c(y, false));
     }
 
@@ -215,7 +214,7 @@ function drawBoard(canvas, mouseCoords, radius) {
     context.canvas.height = window.innerHeight - 120;
     context.clearRect(0, 0, canvas.width, canvas.height);
 
-    drawQuadraticFunction(canvas);
+    drawFunction(canvas);
     if (document.getElementById("pDistance").checked) {
         var add = parseInt(document.getElementById("density").value)+10;
         for (var x=0; x < canvas.width; x+=add) {
@@ -262,13 +261,13 @@ canvas.addEventListener('mousemove',
         var x = r(mouseCoords.x, true).toFixed(3);
         var y = r(mouseCoords.y, false).toFixed(3);
         context.fillText("(" + x + ", " + y + ")", mouseCoords.x + 5, mouseCoords.y - 5);
-        var minX = findMin({"x": mouseCoords.x, "y": mouseCoords.y});
+        var minX = findMin({"x": r(mouseCoords.x,true), "y": r(mouseCoords.y,false)});
         var minY = getValue(minX);
         context.beginPath();
-        context.moveTo(c(minX, true), c(minY, false), false);
+        context.moveTo(c(minX,true), c(minY, false));
         context.lineTo(mouseCoords.x, mouseCoords.y, false);
         context.stroke();
-        var minRadius = getDist({"x":x, "y":y}, minX);
+        var minRadius = euklideanDist({"x": r(mouseCoords.x,true), "y": r(mouseCoords.y,false)}, {"x":minX,"y":minY});
         
         /* Draw circle */
         drawEllipse(mouseCoords.x, mouseCoords.y, minRadius*STRETCH_X, minRadius*STRETCH_Y);