在R语言中绘制给定焦点、偏心率的复数坐标椭圆的实现方法
R语言绘制已知焦点、偏心率的复数格式椭圆方案
1 先修正数据生成逻辑
你原来的代码存在两个可优化点:
- 用
while循环执行效率低,R中向量化运算可以大幅提升速度 - 直接把复数存入
numeric类型的列会丢失虚部信息,需要把每个复数的实部、虚部分开存储
修正后的数据生成代码如下:
library(ggforce) library(ggplot2) n <- 2500 k_vec <- 0:n # 直接生成所有k的向量,用向量化运算替代循环 # 向量化计算所有F1、F2、偏心率 F1_k <- (-3/2)*((sin(2*pi*k_vec/n))^3) + (3/10)*((sin(2*pi*k_vec/n))^7) + (1i) * sin((2*pi*k_vec/1875) + (pi/6)) + (1/4)*(sin((2*pi*k_vec /1875) + (pi/6)))^3 + ((2/15) - (1/8)*cos(pi*k_vec/625)* exp(68*pi*(1i)*k_vec/n)) F2_k <- (-3/2)*((sin(2*pi*k_vec/n))^3) + (3/10)*((sin(2*pi*k_vec/n))^7) + (1i) * sin((2*pi*k_vec/1875) + (pi/6)) + (1/4)*(sin((2*pi*k_vec /1875) + (pi/6)))^3 - ((2/15) - (1/8)*cos(pi*k_vec/625)* exp(68*pi*(1i)*k_vec/n)) ecc_k <- (49/50) - (1/7)*(sin(4*pi*k_vec/n))^4 # 整理成绘图需要的参数表 ellipse_params <- data.frame( # 椭圆中心:两个焦点的中点 x0 = (Re(F1_k) + Re(F2_k))/2, y0 = (Im(F1_k) + Im(F2_k))/2, # 两焦点距离的一半是c c = Mod(F2_k - F1_k)/2, ecc = ecc_k, # 椭圆长轴旋转角:焦点连线的角度 angle = Arg(F2_k - F1_k) * 180/pi # ggforce要求角度单位为度 ) # 计算长半轴a、短半轴b ellipse_params$a <- with(ellipse_params, c / ecc) ellipse_params$b <- with(ellipse_params, sqrt(a^2 - c^2))
2 直接绘制椭圆
用ggforce的geom_ellipse图层即可直接批量绘制所有椭圆,示例代码如下:
ggplot() + geom_ellipse( data = ellipse_params, aes(x0 = x0, y0 = y0, a = a, b = b, angle = angle), fill = NA, # 填充设为透明,只保留边框 color = "steelblue", linewidth = 0.1, # 线条细一点避免重叠后太糊 alpha = 0.3 # 加透明度,重叠区域效果更好 ) + coord_equal() + # 必须加,否则椭圆会被坐标轴比例拉伸变形 theme_minimal()
3 可选优化建议
如果n=2500渲染太慢,可以做如下调整:
- 抽样绘制:比如取
ellipse_params[seq(1, nrow(ellipse_params), 5), ]只绘制1/5的椭圆 - 降低椭圆采样精度:给
geom_ellipse加参数n=20(默认是360,数值越小渲染越快) - 减少线条宽度和透明度,避免重叠后画面过暗
内容的提问来源于stack exchange,提问作者LastBorn
相关产品推荐
相关产品推荐

