我正在开发一个涉及从一组定义的点(数万个点)创建样条线的项目.
我首先为前1000个点创建样条曲线并使用箭头模拟该路径上的"驱动"(使用样条上的切线和当前点绘制).当我接近路径的末端时,我接下来的1000个点并创建一个新的样条曲线并继续我的"驾驶".
我遇到的问题是样条曲线(前一个样条曲线和当前样条曲线)最后不匹配.通过不匹配我的意思是它们没有相同的切线(一阶导数不匹配)并且前一个样条曲线的最后一个点与新样条曲线上的第一个点之间存在差异(这是因为我没有使用插值样条曲线但平滑样条曲线 - 参见下面的注1).当切换到新创建的样条曲线时,这使我的箭头在样条曲线的末尾"跳跃".
注1:我没有使用插值样条.我正在使用平滑的样条线.有关详细信息,请参见此处和此处.这意味着,一套作为输入给出可能不在所产生的样点(在我的情况下,他们都相当接近样-但通常不是花键).
注2:使用插值样条是不可能的,因为我在用于计算样条曲线的数据中有很多噪声.
注3:在具有2 GB RAM的3Ghz PC(我们的应用程序目标平台)上计算整个点集的样条曲线需要花费大量时间(超过30秒); 这样做也是不可能的.
我有兴趣在切换样条线时克服那些不必要的"跳跃".
所以我的问题是:
谢谢你的任何想法,
尤利安
我有一个较大的3D numpy标量值数组(如果必须,可以称之为"音量").我想在一系列不规则的,而不是所有已知的前置非整数xyz坐标上插入一个平滑的标量场.
现在,Scipy对此的支持非常好:我使用了过滤音量
filtered_volume = scipy.ndimage.interpolation.spline_filter(volume)
Run Code Online (Sandbox Code Playgroud)
并调用
scipy.ndimage.interpolation.map_coordinates(
filtered_volume,
[[z],[y],[x]],
prefilter=False)
Run Code Online (Sandbox Code Playgroud)
对于感兴趣的(x,y,z),获得表面上很好的(平滑等)插值.
到现在为止还挺好.但是,我的应用程序还需要插值字段的局部导数.目前我通过中心差分获得这些:我还在6个额外点处对体积进行采样(这至少可以通过一次调用完成map_coordinates)并计算例如来自的x导数(i(x+h,y,z)-i(x-h,y,z))/(2*h).(是的,我知道我可以将额外的水龙头数量减少到3并做出"单侧"差异,但不对称会让我烦恼.)
我的直觉是应该有一个更直接的方法来获得渐变,但我不知道足够的样条数学(还)来弄明白,或者了解Scipy实现的内容:scipy/scipy/ndimage/src/ni_interpolation.c.
有没有比中央差分"更直接"获得渐变的更好方法?优选地,允许使用现有功能获得它们而不是攻击Scipy的内部.
我认为我的问题类似于:将对象的旋转方向旋转到THREE.JS中的样条点切线,但是我无法正确访问jsfiddle并且我在解释的第二部分中遇到了困难.
基本上,我创建了这个jsfiddle:http://jsfiddle.net/jayfield1979/qGPTT/2/,它演示了一个简单的立方体,遵循由样条曲线创建的路径SplineCurve3.使用标准的TrackBall鼠标交互进行导航.
沿着路径定位立方体很简单.但是我有两个问题.
首先,我使用spline.getTanget( t )where t是路径上的位置,以使立方体旋转(Y轴仅为UP).我想我错过了一些东西,因为即使我提取.y了所提供的切线的属性,旋转仍然显得不合适.是否需要进行一些正规化?
其次,沿着路径的速度变化很大,显然在创建更紧凑的曲线时会堆积更多的点,但我想知道有没有办法重构路径以更均匀地分布点之间的空间?我遇到了这个reparametrizeByArcLength功能,但很难找到如何使用它的解释.
如果对数学假人有任何帮助或解释,我们将非常感激.
我想绘制一个受限制的三次样条曲线作为主图,并添加一个盒子和须状图来显示X变量的变化.然而,下铰链(x = 42),中间(x = 51)和上铰链(x = 61)与主曲线的相应网格线不完全吻合.
library(Hmisc)
library(rms)
library(ggplot2)
library(gridExtra)
data(pbc)
d <- pbc
rm(pbc)
d$status <- ifelse(d$status != 0, 1, 0)
dd = datadist(d)
options(datadist='dd')
f <- cph(Surv(time, status) ~ rcs(age, 4), data=d)
p <- Predict(f, fun=exp)
df <- data.frame(age=p$age, yhat=p$yhat, lower=p$lower, upper=p$upper)
### 1st PLOT: main plot
(g <- ggplot(data=df, aes(x=age, y=yhat)) + geom_line(size=1))
# CI
(g <- g + geom_ribbon(data=df, aes(ymin=lower, ymax=upper), alpha=0.5, linetype=0, fill='#FFC000'))
# white background
(g <- g + theme_bw())
# X-axis
(breaks …Run Code Online (Sandbox Code Playgroud) 我需要在 python 中评估 b 样条线。为此,我编写了下面的代码,效果非常好。
import numpy as np
import scipy.interpolate as si
def scipy_bspline(cv,n,degree):
""" bspline basis function
c = list of control points.
n = number of points on the curve.
degree = curve degree
"""
# Create a range of u values
c = cv.shape[0]
kv = np.clip(np.arange(c+degree+1)-degree,0,c-degree)
u = np.linspace(0,c-degree,n)
# Calculate result
return np.array(si.splev(u, (kv,cv.T,degree))).T
Run Code Online (Sandbox Code Playgroud)
给它 6 个控制点并要求它评估曲线上的 100k 个点是一件轻而易举的事:
# Control points
cv = np.array([[ 50., 25., 0.],
[ 59., 12., 0.],
[ 50., …Run Code Online (Sandbox Code Playgroud) 我想显示一个由创建的图,geom_smooth()但是对我来说,能够描述如何创建该图很重要。
我可以从文档中看到,当n> = 1000时,使用gam作为平滑函数,但是我看不到使用了多少个结或使用哪个函数生成了平滑。
例:
library(ggplot2)
set.seed(12345)
n <- 3000
x1 <- seq(0, 4*pi,, n)
x2 <- runif(n)
x3 <- rnorm(n)
lp <- 2*sin(2* x1)+3*x2 + 3*x3
p <- 1/(1+exp(-lp))
y <- ifelse(p > 0.5, 1, 0)
df <- data.frame(x1, x2, x3, y)
# default plot
ggplot(df, aes(x = x1, y = y)) +
geom_smooth()
# specify method='gam'
# linear
ggplot(df, aes(x = x1, y = y)) +
geom_smooth(method = 'gam')
# specify gam and splines
# Shows …Run Code Online (Sandbox Code Playgroud) 我在Matlab中寻找(一个理想的内置)函数,以与R中相同的方式计算B样条基矩阵,例如对于具有20个等间距3度的样条的样条基础,我会在R中做
require(splines)
B = bs(x = seq(0,1,length.out=100),
knots = seq(0, 1, length.out=20), # 20 knots
degree = 3,
intercept = FALSE)
matplot(B,type="l")
Run Code Online (Sandbox Code Playgroud)
为了在Matlab中得到相同的结果,我想我可以使用它
B = spcol(linspace(0,1,20),3,linspace(0,1,100));
plot(B);
Run Code Online (Sandbox Code Playgroud)
但是可以看出边界结然后丢失了.有任何想法,Matlab中的等效语法与R中的相同吗?
PS R用于的代码bs()有点简化:
basis <- function(x, degree, i, knots) {
if(degree == 0){
B <- ifelse((x >= knots[i]) & (x < knots[i+1]), 1, 0)
} else {
if((knots[degree+i] - knots[i]) == 0) {
alpha1 <- 0
} else {
alpha1 <- (x - knots[i])/(knots[degree+i] - knots[i])
}
if((knots[i+degree+1] - knots[i+1]) == …Run Code Online (Sandbox Code Playgroud) 请原谅我的长代码示例,但我无法弄清楚如何用更少的代码正确解释我的问题:
let c = document.querySelector("canvas");
let ctx = c.getContext("2d");
class BezierCurve {
constructor(x1, y1, cpX, cpY, x2, y2) {
this.f = 0;
this.x1 = x1;
this.y1 = y1;
this.cpX = cpX;
this.cpY = cpY;
this.x2 = x2;
this.y2 = y2;
this.pointCache = this.calcPoints();
}
calcX(t) { return (1 - t) * (1 - t) * this.x1 + 2 * (1 - t) * t * this.cpX + t * t * this.x2; }
calcY(t) { return (1 - t) * …Run Code Online (Sandbox Code Playgroud)我需要在 R 脚本中使用“not-a-knot”三次样条进行插值。
尽管有一些用于样条的 R 软件包,但它们似乎都没有考虑“非结”类型,即使据说它是一种相当“流行”的三次样条类型,并且在 Matlab 中可用。
我担心“无结”三次样条还有另一个名称。它是三次样条,其中两个额外条件与第二个和前最后一个结中的三阶导数连续性有关(而不是像自然三次样条或其他选择那样将一阶导数固定在端点结处)。