You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Base R中自定义旋转箭头图形变形问题求助

Fixing Rotation Distortion in Custom Arrow Function

Let's break down why your arrow distorts when rotated, and fix it step by step:

The Root Causes

  • Incorrect Rotation Matrix: Your current rotation matrix uses the wrong sign combination for 2D coordinate rotation, which skews the shape instead of rotating it cleanly.
  • Off-Center Vertex Coordinates: The original arrow's vertices aren't centered at the origin (0,0), so rotating it pivots around an offset point—causing extra distortion and misalignment.

Corrected Function

Here's the revised version of your my_arrow function with fixes for both issues:

my_arrow <- function(x, y, rotate = 0, col = par("fg"), cex = 1) {
  # Original arrow vertex coordinates
  xbase <- c(1.2, 0.2, 0.2, -1.2, -1.2, 0.2, 0.2)
  ybase <- c(0, 1, 0.5, 0.5, -0.5, -0.5, -1)
  
  # Step 1: Center the shape on the origin (fixes pivot point issue)
  x_center <- mean(xbase)
  xbase_centered <- xbase - x_center
  
  # Step 2: Use the standard 2D counter-clockwise rotation matrix
  theta <- rotate * pi / 180
  rotM <- matrix(c(cos(theta), -sin(theta), 
                   sin(theta), cos(theta)), nrow = 2)
  
  # Step 3: Apply transformations in the correct order: scale → rotate → translate
  transf <- function(x1, y1) {
    scaled <- cex * c(x1, y1)
    rotated <- rotM %*% scaled
    rotated + c(x, y)
  }
  
  ans <- t(mapply(transf, xbase_centered, ybase))
  polygon(x = ans[,1], y = ans[,2], col = col)
}

Key Fixes Explained

  1. Centering the Shape: We calculate the mean of the original xbase coordinates and subtract it to shift the arrow's center to the origin. This ensures rotations pivot around the arrow's actual center, not an offset point.
  2. Correct Rotation Matrix: The standard 2D rotation matrix uses -sin(theta) in the top-right and sin(theta) in the bottom-left position. This preserves the shape's proportions during rotation, no matter the angle.
  3. Transformation Order: Scaling first, then rotation, then translation to (x,y) prevents unintended skewing that can happen if you reorder these steps.

Test the Fixed Function

Run this code to verify the rotation works without distortion:

plot(1:2, type="p", col="white", xlim=c(-5,5), ylim=c(-10,10))
# Draw arrows at different rotations to check consistency
my_arrow(0, 0, rotate = 0, col = "red")
my_arrow(2, 2, rotate = 45, col = "blue")
my_arrow(-2, -2, rotate = 90, col = "green")

You’ll now see arrows that maintain their custom shape regardless of rotation angle, and they’re properly positioned at your specified (x,y) coordinates.

内容的提问来源于stack exchange,提问作者Karsten W.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:03:00