mirror of
https://github.com/MartinThoma/LaTeX-examples.git
synced 2025-04-19 11:38:05 +02:00
misc
This commit is contained in:
parent
145238524e
commit
1bcec68935
4 changed files with 363 additions and 17 deletions
|
@ -1,7 +1,8 @@
|
|||
SOURCE = math-minimal-distance-to-cubic-function
|
||||
make:
|
||||
pdflatex $(SOURCE).tex -output-format=pdf
|
||||
pdflatex $(SOURCE).tex -output-format=pdf
|
||||
make clean
|
||||
|
||||
clean:
|
||||
rm -rf $(TARGET) *.class *.html *.log *.aux *.out
|
||||
rm -rf $(TARGET) *.class *.log *.aux *.out
|
||||
|
|
|
@ -30,21 +30,38 @@
|
|||
\begin{document}
|
||||
\maketitle
|
||||
\begin{abstract}
|
||||
In this paper I want to discuss how to find all points on a a cubic
|
||||
When you have a selfdriving car, you have to plan which path you
|
||||
want to take. A reasonable choice for the representation of this
|
||||
path is a cubic spline. But you also have to be able to calculate
|
||||
how to steer to get or to remain on this path. A way to do this
|
||||
is applying the \href{https://en.wikipedia.org/wiki/PID_algorithm}{PID algorithm}.
|
||||
But this algorithm needs to know the current error. So you need to
|
||||
be able to get the minimal distance of a point to a cubic spline.
|
||||
As you need to get the signed error (and one steering direction might
|
||||
be prefered), it is not only necessary to
|
||||
get the minimal absolute distance, but also to get all points
|
||||
on the spline with minimal distance.
|
||||
|
||||
In this paper I want to discuss how to find all points on a cubic
|
||||
function with minimal distance to a given point.
|
||||
As other representations of paths might be easier to understand and
|
||||
to implement, I will also cover the problem of finding the minimal
|
||||
distance of a point to a polynomial of degree 0, 1 and 2.
|
||||
\end{abstract}
|
||||
|
||||
\section{Description of the Problem}
|
||||
Let $f: \mdr \rightarrow \mdr$ be a polynomial function and $P \in \mdr^2$
|
||||
be a point. Let $d: \mdr^2 \times \mdr^2 \rightarrow \mdr_0^+$
|
||||
be the euklidean distance of two points:
|
||||
be the Euklidean distance of two points:
|
||||
\[d \left ((x_1, y_1), (x_2, y_2) \right) := \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}\]
|
||||
|
||||
Now there is finite set of points $x_1, \dots, x_n$ such that
|
||||
Now there is \todo{Should I proof this?}{finite set} $x_1, \dots, x_n$ such that
|
||||
\[\forall \tilde x \in \mathbb{R} \setminus \{x_1, \dots, x_n\}: d(P, (x_1, f(x_1))) = \dots = d(P, (x_n, f(x_n))) < d(P, (\tilde x, f(\tilde x)))\]
|
||||
|
||||
The task is now to find those $x_1, \dots, x_n$ for given $f, P$.
|
||||
|
||||
\section{Minimal distance to a constant function}
|
||||
Let $f(x) = c$ with $c \in \mdr$ be a function.
|
||||
Let $f(x) = c$ with $c \in \mdr$ be a constant function.
|
||||
|
||||
\begin{figure}[htp]
|
||||
\centering
|
||||
|
@ -72,21 +89,26 @@ Let $f(x) = c$ with $c \in \mdr$ be a function.
|
|||
\addplot[domain=-5:5, thick,samples=50, green] {2};
|
||||
\addplot[domain=-5:5, thick,samples=50, blue] {3};
|
||||
\addplot[black, mark = *, nodes near coords=$P$,every node near coord/.style={anchor=225}] coordinates {(2, 2)};
|
||||
\addplot[blue, mark = *, nodes near coords=$P_{h,\text{min}}$,every node near coord/.style={anchor=225}] coordinates {(2, 3)};
|
||||
\addplot[green, mark = x, nodes near coords=$P_{g,\text{min}}$,every node near coord/.style={anchor=120}] coordinates {(2, 2)};
|
||||
\addplot[red, mark = *, nodes near coords=$P_{f,\text{min}}$,every node near coord/.style={anchor=225}] coordinates {(2, 1)};
|
||||
\draw[thick, dashed] (axis cs:2,0) -- (axis cs:2,3);
|
||||
\addlegendentry{$f(x)=1$}
|
||||
\addlegendentry{$g(x)=2$}
|
||||
\addlegendentry{$h(x)=3$}
|
||||
\end{axis}
|
||||
\end{tikzpicture}
|
||||
\caption{3 constant functions}
|
||||
\caption{3 constant functions and their points with minimal distance}
|
||||
\label{fig:constant-min-distance}
|
||||
\end{figure}
|
||||
|
||||
Then $(x_P,f(x_P))$ has
|
||||
minimal distance to $P$. Every other point has higher distance.
|
||||
See Figure~\ref{fig:constant-min-distance}.
|
||||
|
||||
\section{Minimal distance to a linear function}
|
||||
Let $f(x) = m \cdot x + t$ with $m \in \mdr \setminus \Set{0}$ and
|
||||
$t \in \mdr$ be a function.
|
||||
$t \in \mdr$ be a linear function.
|
||||
|
||||
\begin{figure}[htp]
|
||||
\centering
|
||||
|
@ -118,27 +140,33 @@ $t \in \mdr$ be a function.
|
|||
\end{axis}
|
||||
\end{tikzpicture}
|
||||
\caption{The shortest distance of $P$ to $f$ can be calculated by using the perpendicular}
|
||||
\label{fig:linear-min-distance}
|
||||
\end{figure}
|
||||
|
||||
Now you can drop a perpendicular through $P$ on $f(x)$. The slope $f_\bot$
|
||||
of the perpendicular is $- \frac{1}{m}$. Then:
|
||||
|
||||
Now you can drop a perpendicular $f_\bot$ through $P$ on $f(x)$. The slope of $f_\bot$
|
||||
is $- \frac{1}{m}$. Now you can calculate $f_\bot$:\nobreak
|
||||
\begin{align}
|
||||
f_\bot(x) &= - \frac{1}{m} \cdot x + t_\bot\\
|
||||
\Rightarrow y_P &= - \frac{1}{m} \cdot x_P + t_\bot\\
|
||||
\Leftrightarrow t_\bot &= y_P + \frac{1}{m} \cdot x_P\\
|
||||
\Leftrightarrow t_\bot &= y_P + \frac{1}{m} \cdot x_P
|
||||
\end{align}
|
||||
|
||||
Now find the point $(x, f(x))$ where the perpendicular crosses the function:
|
||||
\begin{align}
|
||||
f(x) &= f_\bot(x)\\
|
||||
\Leftrightarrow m \cdot x + t &= - \frac{1}{m} \cdot x + \left(y_P + \frac{1}{m} \cdot x_P \right)\\
|
||||
\Leftrightarrow \left (m + \frac{1}{m} \right ) \cdot x &= y_P + \frac{1}{m} \cdot x_P - t\\
|
||||
\Leftrightarrow x &= \frac{m}{m^2+1} \left ( y_P + \frac{1}{m} \cdot x_P - t \right )
|
||||
\end{align}
|
||||
|
||||
There is only one point with minimal distance.
|
||||
There is only one point with minimal distance. See Figure~\ref{fig:linear-min-distance}.
|
||||
\clearpage
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Quadratic functions %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Minimal distance to a quadratic function}
|
||||
Let $f(x) = a \cdot x^2 + b \cdot x + c$ with $a \in \mdr \setminus \Set{0}$ and
|
||||
$b, c \in \mdr$ be a function.
|
||||
$b, c \in \mdr$ be a quadratic function.
|
||||
|
||||
\begin{figure}[htp]
|
||||
\centering
|
||||
|
@ -239,7 +267,7 @@ Minimizing $d$ is the same as minimizing $d^2$:
|
|||
\begin{align}
|
||||
d(x)^2 &= x_p^2 - 2x_p x + x^2 + y_p^2 - 2y_p f(x) + f(x)^2\\
|
||||
(d(x)^2)' &= -2 x_p + 2x -2y_p(f(x))' + (f(x)^2)'\\
|
||||
0 &\stackrel{!}{=} -2 x_p + 2x -2y_p(f(x))' + (f(x)^2)'
|
||||
0 &\stackrel{!}{=} -2 x_p + 2x -2y_p(f(x))' + (f(x)^2)' \label{eq:minimizing}
|
||||
\end{align}
|
||||
|
||||
Now we use thet $f(x) = ax^2 + bx + c$:
|
||||
|
@ -274,9 +302,12 @@ So the minimum for $a=1, b=c=d=0$ is:
|
|||
|
||||
\subsection{Calculate points with minimal distance}
|
||||
\todo[inline]{Write this}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% Cubic %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Minimal distance to a cubic function}
|
||||
Let $f(x) = a \cdot x^3 + b \cdot x^2 + c \cdot x + d$ with $a \in \mdr \setminus \Set{0}$ and
|
||||
Let $f(x) = a \cdot x^3 + b \cdot x^2 + c \cdot x + d$ be a cubic function
|
||||
with $a \in \mdr \setminus \Set{0}$ and
|
||||
$b, c, d \in \mdr$ be a function.
|
||||
|
||||
\subsection{Number of points with minimal distance}
|
||||
|
@ -292,5 +323,16 @@ For $b^2 \geq 3ac$
|
|||
|
||||
\todo[inline]{Write this}
|
||||
\subsection{Calculate points with minimal distance}
|
||||
When you want to calculate points with minimal distance, you can
|
||||
take the same approach as in Equation \ref{eq:minimizing}:
|
||||
|
||||
\begin{align}
|
||||
0 &\stackrel{!}{=} -2 x_p + 2x -2y_p(f(x))' + (f(x)^2)'\\
|
||||
\Leftrightarrow 0 &\stackrel{!}{=} 2 f(x) \cdot f'(x) - 2 y_p f'(x) + 2x - 2 x_p\\
|
||||
\Leftrightarrow 0 &\stackrel{!}{=} \underbrace{\left (2 f(x) - 2 y_p \right ) \cdot f'(x)}_{\text{Polynomial of degree 5}} + \underbrace{2x - 2 x_p}_{\text{:-(}}
|
||||
\end{align}
|
||||
|
||||
|
||||
|
||||
\todo[inline]{Write this}
|
||||
\end{document}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<!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 for x*x">a</span></td>
|
||||
<td><input type="number" step="1" value="1" id="a" min="1" onchange="updateBoard()"></td>
|
||||
<td><span class="hint" title="constant for x">b</span></td>
|
||||
<td><input type="number" step="1" value="1" id="b" min="1" onchange="updateBoard()"></td>
|
||||
<td><span class="hint" title="constant">c</span></td>
|
||||
<td><input type="number" step="1" value="1" id="c" min="1" 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="./quadratic-vis_files/quadratic-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="quadratic-vis.js">
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
</body></html>
|
|
@ -0,0 +1,257 @@
|
|||
'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 drawQuadraticFunction(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.fillRect(c(x), c(y, false), add/2, add/2);
|
||||
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 cubic function at x
|
||||
* @param {Number} x
|
||||
* @return {Number} f(x)
|
||||
*/
|
||||
function getValue(x) {
|
||||
var a = parseFloat(document.getElementById("a").value);
|
||||
var b = parseFloat(document.getElementById("b").value);
|
||||
var c1 = parseFloat(document.getElementById("c").value);
|
||||
return a*x*x+b*x+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) {
|
||||
var a = parseFloat(document.getElementById("a").value);
|
||||
var b = parseFloat(document.getElementById("b").value);
|
||||
var c1 = parseFloat(document.getElementById("c").value);
|
||||
|
||||
var currentMinX = p.x;
|
||||
for (var i=0; i < 10; i++) {
|
||||
// Funktionswert
|
||||
var fx = -2.0*p.x+2.0*currentMinX-2.0*p.y*getDValue(currentMinX) +gedSquaredValueD(currentMinX);
|
||||
var fxd = 2.0 -2.0*p.y*getDDValue(currentMinX)+gedSquaredValueDD(currentMinX);
|
||||
if (Math.abs(fxd) < 0.0001) {
|
||||
return currentMinX;
|
||||
}
|
||||
|
||||
// x_{n+1} = x_n - f(x_n)/f'(x_n) wenn x gesucht, sodass f(x) = 0 gilt
|
||||
currentMinX -= fx / fxd;
|
||||
}
|
||||
return currentMinX;
|
||||
}
|
||||
|
||||
function getDist(p, minX) {
|
||||
var minY = getValue(minX);
|
||||
return euklideanDist({"x":minX, "y":minY}, {"x":p.x, "y":p.y});
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
/* 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);
|
||||
|
||||
drawQuadraticFunction(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":x, "y":y});
|
||||
var minY = getValue(minX);
|
||||
context.beginPath();
|
||||
context.moveTo(c(minX, true), c(minY, false), false);
|
||||
context.lineTo(mouseCoords.x, mouseCoords.y, false);
|
||||
context.stroke();
|
||||
var minRadius = getDist({"x":x, "y":y}, minX);
|
||||
|
||||
/* Draw circle */
|
||||
drawEllipse(mouseCoords.x, mouseCoords.y, minRadius*STRETCH_X, minRadius*STRETCH_Y);
|
||||
}, false);
|
Loading…
Add table
Add a link
Reference in a new issue