-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6856814
commit 5d3abdf
Showing
7 changed files
with
444 additions
and
2 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>RBF Interpolation Visualization</title> | ||
<script src="https://d3js.org/d3.v6.min.js"></script> | ||
<link rel="stylesheet" type="text/css" href="style_dark.css"> | ||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script> | ||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script> | ||
</head> | ||
<body> | ||
<div class="content"> | ||
<h1>RBF Interpolation Visualization</h1> | ||
<p>Drag the points to see how the RBF interpolation changes.</p> | ||
|
||
<div class="flex-container"> | ||
<div class="buttons-container"> | ||
<button id="homeBtn">Home</button> | ||
<button id="infoBtn">Info</button> | ||
<button id="CG3Btn"> | ||
<!-- <img src="./images/SA_schematics_fig_a_Zeichenfläche 1.png" alt="Icon" style="height: 20px; margin-right: 5px;"> --> | ||
CG3 | ||
</button> | ||
</div> | ||
|
||
<div class="plot-container"> | ||
<svg id="rbfPlot" width="800" height="400" viewBox="0 0 1600 800"></svg> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<script type="module" src="./dist/rbf_interpolation.bundle.js"></script> | ||
|
||
<!-- Info Modal --> | ||
<div id="infoModal" class="modal"> | ||
<div class="modal-content"> | ||
<span class="close">×</span> | ||
<h2>Radial Basis Function (RBF) Interpolation - Theory</h2> | ||
<p> | ||
RBF interpolation is a method of multivariate interpolation in which the interpolated surface is a sum of radial basis functions, each associated with a different point. | ||
</p> | ||
<p> | ||
The general form of an RBF is: | ||
</p> | ||
<p> | ||
\( f(x) = \sum_{i=1}^{n} \lambda_i \phi(\| x - x_i \|) \) | ||
</p> | ||
<p> | ||
where \( \lambda_i \) are the weights, \( \phi \) is the radial basis function, \( x \) is the interpolation point, and \( x_i \) are the data points. | ||
</p> | ||
<p> | ||
Common choices for \( \phi \) include Gaussian, Multiquadric, and Inverse Multiquadric functions. | ||
</p> | ||
</div> | ||
</div> | ||
|
||
<script src="./dist/modal.bundle.js"></script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
// import { PolynomialRegressor } from '@rainij/polynomial-regression-js'; | ||
|
||
|
||
import Spline from 'cubic-spline'; | ||
|
||
const RBF = require('rbf'); | ||
|
||
const points = [ | ||
[0, 0], | ||
[0, 100] | ||
]; | ||
|
||
// values could be vectors of any dimensionality. | ||
// The computed interpolant function will return values or vectors accordingly. | ||
const values = [ | ||
0.0, | ||
1.0 | ||
] | ||
|
||
// RBF accepts a distance function as a third parameter : | ||
// either one of the following strings or a custom distance function (defaults to 'linear'). | ||
// | ||
// - linear: r | ||
// - cubic: r**3 | ||
// - quintic: r**5 | ||
// - thin-plate: r**2 * log(r) | ||
// - gaussian: exp(-(r/epsilon) ** 2) | ||
// - multiquadric: sqrt((r/epsilon) ** 2 + 1) | ||
// - inverse-multiquadric: 1 / sqrt((r/epsilon) ** 2 + 1) | ||
// | ||
// epsilon can be provided as a 4th parameter. Defaults to the average | ||
// euclidean distance between points. | ||
// | ||
var rbf = RBF(points, values /*, distanceFunction, epsilon */); | ||
|
||
console.log(rbf([0, 50])); // => 0.5 | ||
|
||
// Sample Data | ||
// const data = [{x: 10, y: 20}, {x: 20, y: 40}]; //, ...]; // Replace with your data | ||
|
||
// ************************************ | ||
// Create random points | ||
// ************************************ | ||
|
||
function seededPRNG(seed) { | ||
return function() { | ||
seed = seed * 16807 % 2147483647; | ||
return (seed - 1) / 2147483646; | ||
}; | ||
} | ||
|
||
// Set the seed for reproducibility | ||
const seed = 12315; // Change this value for different results | ||
const random = seededPRNG(seed); | ||
|
||
// Generate 10 random x,y-pairs | ||
const data = Array.from({ length: 10 }, () => ({ | ||
x: random() * 8 + 1, // Assuming you want x and y values in the range [10, 10] | ||
y: random() * 2 + 4 | ||
})); | ||
|
||
console.log(data); | ||
|
||
// ************************************ | ||
// Create (x,y)-plot | ||
// ************************************ | ||
|
||
const svg = d3.select("#rbfPlot"); | ||
|
||
const margin = { top: 40, right: 40, bottom: 60, left: 100 }; | ||
const viewBoxWidth = 1600; | ||
const viewBoxHeight = 800; | ||
const width = viewBoxWidth - margin.left - margin.right; | ||
const height = viewBoxHeight - margin.top - margin.bottom; | ||
|
||
const x = d3.scaleLinear().rangeRound([0, width]); | ||
const y = d3.scaleLinear().rangeRound([height, 0]); | ||
|
||
|
||
|
||
const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`); | ||
// Set domain limits | ||
|
||
// from data | ||
// x.domain(d3.extent(data, d => d.x)); | ||
// y.domain(d3.extent(data, d => d.y)); | ||
|
||
// manually | ||
x.domain([0, 10]); | ||
y.domain([0, 10]); | ||
|
||
// Create the X and Y axes with class names for future reference | ||
const xAxis = g.append("g") | ||
.attr("class", "x axis") // Assign class name | ||
.attr("transform", `translate(0,${height})`) | ||
.call(d3.axisBottom(x)); | ||
|
||
const yAxis = g.append("g") | ||
.attr("class", "y axis") // Assign class name | ||
.call(d3.axisLeft(y)); | ||
|
||
g.selectAll(".y.axis text") | ||
.style("font-size", "30px"); // Update font size | ||
|
||
|
||
g.selectAll(".x.axis text") | ||
.style("font-size", "30px"); // Update font size | ||
|
||
|
||
// Gridlines | ||
g.append("g") | ||
.attr("class", "grid") | ||
.attr("transform", `translate(0,${height})`) | ||
.call(d3.axisBottom(x) | ||
.tickSize(-height) | ||
.tickFormat("")); | ||
|
||
g.append("g") | ||
.attr("class", "grid") | ||
.call(d3.axisLeft(y) | ||
.tickSize(-width) | ||
.tickFormat("")); | ||
|
||
|
||
|
||
// ************************** | ||
// RBF function | ||
// ************************** | ||
|
||
// Function to update spline curve | ||
function updateRBF() { | ||
// Sort the data by x-values | ||
data.sort((a, b) => a.x - b.x); | ||
|
||
// Extract sorted xs and ys | ||
const xs = data.map(d => d.x); | ||
const ys = data.map(d => d.y); | ||
|
||
// RBF accepts a distance function as a third parameter : | ||
// either one of the following strings or a custom distance function (defaults to 'linear'). | ||
// | ||
// - linear: r | ||
// - cubic: r**3 | ||
// - quintic: r**5 | ||
// - thin-plate: r**2 * log(r) | ||
// - gaussian: exp(-(r/epsilon) ** 2) | ||
// - multiquadric: sqrt((r/epsilon) ** 2 + 1) | ||
// - inverse-multiquadric: 1 / sqrt((r/epsilon) ** 2 + 1) | ||
// | ||
// epsilon can be provided as a 4th parameter. Defaults to the average | ||
// euclidean distance between points. | ||
|
||
// create RBF function | ||
var rbf = RBF(xs, ys, 'multiquadric', .5 /*, distanceFunction, epsilon */); | ||
|
||
// Generate points for the curve at a higher resolution | ||
const curvePoints = []; | ||
const start = x.domain()[0]; | ||
const end = x.domain()[1]; | ||
const step = (end - start) / 500; // Adjust the number of points for smoothness | ||
|
||
for (let i = start; i <= end; i += step) { | ||
curvePoints.push({ x: i, y: rbf(i) }); | ||
} | ||
// Draw the curve (or update if already drawn) | ||
const line = d3.line() | ||
.x(d => x(d.x)) | ||
.y(d => y(d.y)); | ||
|
||
const path = g.selectAll('.spline-curve') | ||
.data([curvePoints]); // Bind the new curve data | ||
|
||
path.enter().append('path') | ||
.attr('class', 'spline-curve') | ||
.merge(path) | ||
.attr('fill', 'none') | ||
.attr('stroke', 'green') | ||
.attr('stroke-width', 3) | ||
.attr('d', line); | ||
} | ||
|
||
|
||
// Initial drawing of the curve | ||
updateRBF(); | ||
|
||
// ************************************ | ||
// Drag points | ||
// ************************************ | ||
|
||
// Drag event handler | ||
function dragged(event, d) { | ||
const [newX, newY] = d3.pointer(event, this); // Get the correct coordinates | ||
|
||
d.x = x.invert(newX); // Convert from screen to data coordinates | ||
d.y = y.invert(newY); // Convert from screen to data coordinates | ||
|
||
d3.select(this) | ||
.attr('cx', x(d.x)) // Update the position using the data scale | ||
.attr('cy', y(d.y)); | ||
|
||
// Update the spline curve after dragging a point | ||
updateRBF(); | ||
} | ||
|
||
// Apply drag behavior to the points | ||
g.selectAll(".dot") | ||
.data(data) | ||
.enter().append("circle") | ||
.attr("class", "dot") | ||
.attr("cx", d => x(d.x)) | ||
.attr("cy", d => y(d.y)) | ||
.attr("r", 10) | ||
.call(d3.drag().on("drag", dragged)); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters