- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想绘制弯曲的箭头
,不幸的是,函数中没有实现曲率参数arrows(., curve=)
。
我的解决方案是对省略号进行子集化。由于 plotrix::draw.ellipse()
画线并且我需要点子集,我写了一个函数 arrow_curved()
从 this great answer fork 代码这给出了一个令人满意的结果。
arrow_curved <- function(xc, yc, a, b, .xlim, .ylim, .srt, .lwd=1.25, .col=1) {
phi <- pi/3
t <- seq(0, 2*pi, 0.001)
x <- xc + a*cos(t)*cos(phi) - b*sin(t)*sin(phi)
y <- yc + a*cos(t)*cos(phi) + b*sin(t)*cos(phi)
w <- which(x > .xlim[1] & x < .xlim[2] & y < .ylim[2] & y > .ylim[1])
x <- x[w]; y <- y[w]
segments(x, y, x, y, lwd=.lwd, col=.col)
text(x[which.max(x)], y[which.max(x)], labels='>', srt=.srt, col=.col)
}
plot(c(0, 10), c(0, 10), type="n")
## red arrows
arrow_curved(xc=3, yc=8, a=10, b=6.5, .xlim=c(3.25, 8.15),
.ylim=c(2, 4.5), .srt=20, .lwd=1.25, .col=2)
arrows(3.25, 2, 8.15, 4.5, length=.075, col=2, lty=2) ## straight arrow
## green arrow
arrow_curved(xc=2, yc=4, a=6, b=10, .xlim=c(1, 5),
.ylim=c(1, 10), .srt=-20, .lwd=1.25, .col=3)
但是,您需要一点运气来指定参数。理想情况下,该函数的工作方式类似于 arrows()
,除了 x0, y0, x1, y1
之外,我们还可以指定曲率 curve=
参数>。此外,目前起点和终点仅与 .xlim=
和 .ylim=
参数中指定的值大致匹配(将弯曲的红色箭头与直线引用箭头进行比较)。
谁能看到改进这方面功能的方法?也许可以借助数学以某种方式轻松调整坐标,这超出了我的知识范围。
最佳答案
你的问题让我很好奇如何做到这一点,所以我又试了一次。这涉及到相当多的几何学,但这是一个有趣的挑战。
基本上,我意识到,如果要使圆弧保持圆形,两点之间的行进距离将取决于您为圆弧指定的度数。小的度数意味着几乎是一条直线,而大的度数意味着到第二点的非常迂回的方式。在大多数情况下,我关于使用样条曲线的评论可能更有意义,但如果保持箭头的圆形形式很重要,那么以下内容似乎可以做到这一点。
# helper functions to convert between radians and degrees
deg2rad <- function (deg){
stopifnot(is.numeric(deg))
(rad <- (pi/180) * deg)
}
rad2deg <- function (rad){
stopifnot(is.numeric(rad))
(deg <- rad/(pi/180))
}
# function to calculate the points on an arc between two points
# position 1: x0, y0
# position 2: x1, y1
# number of points in resulting arc line: n
# degrees of the arc connecting the points (positive is counter-clockwise,
# negative is clockwise): arcdeg
calcArc <- function(x0 = 1, y0 = 1, x1 = 4, y1 = 6, arcdeg = 30, n = 50){
if(abs(arcdeg)>-359.9 & abs(arcdeg)>359.9){stop("angle of arc (arcdeg) must be between -359.9 and 359.9")}
anglerad <- atan2(y = y1-y0, x = x1-x0) # angle between points
midpt <- list(x = mean(c(x0,x1)), y = mean(c(y0,y1))) # midpoint coordinates of chord
arcrad <- deg2rad(deg = arcdeg) # angle of arc in radians
chordlength <- sqrt((x1-x0)^2 + (y1-y0)^2) # length between points
r <- abs((chordlength/2) / sin(arcrad/2)) # radius of circle
# angle from midpoint to circle center
lut <- data.frame(
lessthan180 = c(TRUE, TRUE, FALSE, FALSE),
sign = c(1, -1, 1, -1),
rotation = c(90, -90, -90, 90))
hit <- which(lut$lessthan180 == (abs(arcdeg) < 180) & lut$sign == sign(arcdeg))
anglecen <- anglerad + deg2rad(lut$rotation[hit])
# length of midpoint to circle center
midpt2cenpt <- sqrt(r^2 - (chordlength/2)^2)
# calculate center point
cenpt <- list(x = midpt$x + midpt2cenpt*cos(anglecen),
y = midpt$y + midpt2cenpt*sin(anglecen))
# angle from circle center to arc
anglecen2arc <- anglecen + ifelse(abs(arcdeg)<180, deg2rad(180), 0)
# produce vector of arc with n points
arc <- data.frame(
rad = seq(
from = anglecen2arc - arcrad/2,
to = anglecen2arc + arcrad/2,
length.out = n
)
)
arc$x <- cenpt$x + r*cos(arc$rad)
arc$y <- cenpt$y + r*sin(arc$rad)
return(arc)
}
# function drawing the results of calcArc as a line or arrow.
# makes a conversion in plotting region units in order to maintain a circular arc
addArc <- function(x0 = 1, y0 = 1, x1 = 4, y1 = 6, arcdeg = 30, n = 50,
t = "l", col = 1, lty = 1, lwd = 1,
arrowlength = NULL, arrowangle = 30, arrowcode = 2,
result = FALSE,
...){
# calculate arc
arc <- calcArc(x0 = x0, y0 = y0, x1 = x1, y1 = y1, arcdeg = arcdeg, n = n)
# calculate arc in device units
FROM = "user"
TO = "chars"
x0 <- grconvertX(x0, from = FROM, to = TO)
x1 <- grconvertX(x1, from = FROM, to = TO)
y0 <- grconvertY(y0, from = FROM, to = TO)
y1 <- grconvertY(y1, from = FROM, to = TO)
arc2 <- calcArc(x0 = x0, y0 = y0, x1 = x1, y1 = y1, arcdeg = arcdeg, n = n)
names(arc2) <- c("rad", "xusr", "yusr")
arc <- cbind(arc, arc2[,c("xusr", "yusr")])
# convert back to user coordinates
arc$xusr <- grconvertX(arc$xusr, from = TO, to = FROM)
arc$yusr <- grconvertY(arc$yusr, from = TO, to = FROM)
lines(yusr ~ xusr, data = arc, t = t,
col = col, lty = lty, lwd = lwd, ...)
if(!is.null(arrowlength)){
arrows(x0 = arc$xusr[n-1], x1 = arc$xusr[n], y0 = arc$yusr[n-1], y1 = arc$yusr[n],
length = arrowlength, code = arrowcode, angle = arrowangle,
col = col, lty = lty, lwd = lwd, ...)
}
if(result){return(arc)}
}
plot(1, t = "n", xlim = c(-4, 6), ylim = c(0,10), xlab = "", ylab = "")
points(x = c(0,1), y = c(4,6), pch = 16, cex = 1)
addArc(x0 = 0, x1 = 1, y0 = 4, y1 = 6, arcdeg = 90, col = 4, arrowlength = 0.1, lwd = 2)
addArc(x0 = 0, x1 = 1, y0 = 4, y1 = 6, arcdeg = -90, col = 4, arrowlength = 0.1, lwd = 2)
addArc(x0 = 0, x1 = 1, y0 = 4, y1 = 6, arcdeg = -180, col = 4, arrowlength = 0.1, lwd = 2)
addArc(x0 = 0, x1 = 1, y0 = 4, y1 = 6, arcdeg = -300, col = 4, arrowlength = 0.1, lwd = 2)
df <- data.frame(x = c(0,1,1,0.5,0.5,0, 0), y = c(0,0,1,1,0.5,0.5,0))
dfmid <- data.frame(x = df$x[-nrow(df)] + diff(df$x)/2,
y = df$y[-nrow(df)] + diff(df$y)/2)
dfmid$arcdeg <- c(270, -90, 270, -270, 270, 270)
dfmid$col <- rainbow(nrow(dfmid))
plot(y ~ x, df, t = "n", xlim = c(-1,2), ylim = c(-1,2))
polygon(x = df$x, y = df$y, col = "grey70", border = NA)
points(y ~ x, dfmid)
for(i in seq(nrow(dfmid)-1)){
addArc(x0 = dfmid$x[i], y0 = dfmid$y[i], x1 = dfmid$x[i+1], y1 = dfmid$y[i+1],
arcdeg = dfmid$arcdeg[i], arrowlength = 0.1, col = dfmid$col[i],
lwd = 3, lty = 1, n = 500, t = "l")
}
关于r - 如何绘制具有精确起点和终点的弯曲箭头?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73906615/
我学习 SDL 二维编程已有一段时间了,现在我想创建一个结合使用 SDL 和 OpenGL 的程序。我是这样设置的: SDL_Init(SDL_INIT_VIDEO); window = SDL_Cr
尝试查找可在地块中使用的不同类型项目的列表 来自不同样本的投影类型: projection = list(type = "equirectangular") projection = list(typ
我正在尝试使用 Java Graphics API 绘制 GIF,但无法使用下面的代码成功绘制 GIF。仅绘制 GIF 的第一张图像或缩略图,但不播放。 public void paintCompon
我目前正在使用 JFrame 并尝试绘制一个矩形,但我不知道如何执行代码 paint(Graphics g),如何获取 Graphics 对象? package com.raggaer.frame;
这个领域的新手,希望得到一些帮助。 我有一个"Missile.java" 类,我在那里画东西。我想绘制一个 ImageView,我正在使用以下代码: ImageView v = (ImageView)
下面列出了圆形的例子 这是我的 JavaScript 代码。 最佳答案 假设您的 randomColor 是正确的,您只需要: 从 canvas.onclick 中移除 context.clearR
我在绘制和缩放 ImageView 时遇到问题。请帮帮我.. 当我画一些东西然后拖动或缩放图像时 - 绘图保留在原处,如您在屏幕截图中所见。而且我只需要简单地在图片上绘图,并且可以缩放和拖动这张图片。
我们可以在形式之外绘制图像和文本...我的意思是在字面上... 我知道问这个问题很愚蠢但是我们能不能... 最佳答案 您可以通过创建表单并将其 TransparentColor 属性设置为背景色来“作
我在绘制/布局期间收到 3 个对象分配警告 super.onDraw(canvas); canvas.drawColor(Color.WHITE); Paint textPaint = new Pai
我有一个示例时间序列数据框: df = pd.DataFrame({'year':'1990','1991','1992','1993','1994','1995','1996',
我试图想出一种简洁的方法来绘制 R 数据框中所有列的 GridView 。问题是我的数据框中既有离散值又有数值。为简单起见,我们可以使用 R 提供的名为 iris 的示例数据集。我会使用 par(mf
我有一个由 10 列和 50 行组成的 data.frame。我使用 apply 函数逐列计算密度函数。现在我想绘制我一次计算的密度。 换句话说,而不是绘图... plot(den[[1]]) plo
我想知道我们如何才能在第一个和第二个组件之外绘制个人,如下所示: 最佳答案 这可能有效: pc.cr <- princomp(USArrests, cor = TRUE) pairs(pc.cr$lo
我是Pandas和matplotlib的新手,想绘制此DataFrame season won team matches pct_won 0 20
我正在尝试为 distplot 子图编写一个 for 循环。 我有一个包含许多不同长度列的数据框。 (不包括 NaN 值) fig = make_subplots( rows=len(asse
我想创建一个具有密度的 3d 图。 我使用函数 density 首先为特定的 x 值创建一个二维图,然后该函数创建密度并将它们放入 y 变量中。现在我有第二组 x 值并将其再次放入密度函数中,然后我得
全部, 我一直在研究全局所有 MTB 步道的索引。我是 Python 人,所以对于所有涉及的步骤,我都尝试使用 Python 模块。 我能够像这样从 OSM 立交桥 API 中获取关系: from O
我正在使用 e1071 包中的支持向量机对我的数据进行分类,并希望可视化机器实际如何进行分类。但是,在使用 plot.svm 函数时,出现无法解决的错误。 脚本: library("e1071") d
我制作了以下图表,它是使用 xts 对象创建的。 我使用的代码很简单 plot(graphTS1$CCLL, type = "l", las = 2, ylab = "(c)\nCC for I
在绘制状态图时,您如何知道哪些状态放在框中,哪些状态用于转换箭头?我注意到转换也是状态。 我正在查看 this page 上的图 1 : 最佳答案 转换不是状态。转换是将对象从一种状态移动到下一种状态
我是一名优秀的程序员,十分优秀!