渐近线如何使不透明圆环上的圆圈逐渐消失

渐近线如何使不透明圆环上的圆圈逐渐消失

我需要在圆环上画点。3D 点没有用,因为它们是球体。我成功计算了范数向量并在圆环上画了圆,稍后我会填充它们。

可以看到,圆环是不透明的,所有圆圈都正常绘制。有没有办法让通常不可见的圆圈变得不透明?

我想到的一个解决方案是,从小圆的中心到透视点画一条线,并计算与圆环的交点。如果点的距离最小,则正常绘制圆,否则,将其绘制为不透明。

还有更好的解决办法吗?

在此处输入图片描述

settings.outformat="pdf";

settings.prc=false;
settings.render=0;

import graph3;

size(4cm,0);

pen surfPen=white+opacity(0.2);
pen xarcPen=deepblue+0.7bp;
pen yarcPen=deepred+0.7bp;

currentprojection=perspective(5,5,6);

real R=3;       //Radius of big circle
real a=1;       //Radius of little circle

triple fs(pair t) {
  return ((R+a*Cos(t.y))*Cos(t.x),(R+a*Cos(t.y))*Sin(t.x),a*Sin(t.y));
}

triple centerXYNormal(pair t) {

  triple P = (((R)*Cos(t.x)),(R)*Sin(t.x),0);
  triple T = fs(t);
  return (T.x - P.x, T.y - P.y, T.z - P.z);

}

surface s=surface(fs,(0,0),(360,360),8,8,Spline);
draw(s,surfPen,render(compression=Low,merge=true));

int m=3;
int n=16;

pair p,q,v;

for(int i=1;i<=n;++i){
  for(int j=0;j<m;++j){
    p=(j*360/m,(i%n)*360/n);
    path3 mycircle = circle(c=fs(p), r=0.1,normal=centerXYNormal(p));
    draw(mycircle, blue);
  }
}

答案1

我认为你有两种选择:

  1. 自己找出哪些圆圈是隐藏的,哪些圆圈在前景,然后按照你的建议绘制它们。
  2. 选择settings.render不同于0。在这种情况下,asymptote您将免于进行 1 下的计算,但它也将生成像素图形而不是矢量图形。

在这个例子中,我选择选项 2,并稍微增加不透明度以使效果更加明显。

在此处输入图片描述

settings.outformat="pdf";

settings.prc=false;
settings.render=10;

import graph3;

size(4cm,0);

pen surfPen=white+opacity(0.5);
pen xarcPen=deepblue+0.7bp;
pen yarcPen=deepred+0.7bp;

currentprojection=perspective(5,5,6);

real R=3;       //Radius of big circle
real a=1;       //Radius of little circle

triple fs(pair t) {
  return ((R+a*Cos(t.y))*Cos(t.x),(R+a*Cos(t.y))*Sin(t.x),a*Sin(t.y));
}

triple centerXYNormal(pair t) {

  triple P = (((R)*Cos(t.x)),(R)*Sin(t.x),0);
  triple T = fs(t);
  return (T.x - P.x, T.y - P.y, T.z - P.z);

}

surface s=surface(fs,(0,0),(360,360),8,8,Spline);
draw(s,surfPen,render(compression=Low,merge=true));

int m=3;
int n=16;

pair p,q,v;

for(int i=1;i<=n;++i){
  for(int j=0;j<m;++j){
    p=(j*360/m,(i%n)*360/n);
    path3 mycircle = circle(c=fs(p), r=0.1,normal=centerXYNormal(p));
    draw(mycircle, blue);
  }
}

PS 这些圆圈实际上并不在圆环上,但它们足够小,所以这并不重要。

答案2

Pumuckl 的回答如果只想要像素图形,而我并不需要,那么这很好。我使用光线追踪来实现它。对于每个圆,都会形成从透视点和圆心穿过的线。计算线与圆环的交点。方程取自余弦猫(没有 HTTPS!)这很有帮助,谢谢。最多有 4 个未知数,所以我使用了quarticroots数学。这个函数减少了实现时间,也感谢作者。

然后找到最小距离,但是,我遇到了一个由于浮点计算而导致的错误。我通过测试解决了它

if ( distance3D(min,fs(p)) < 0.005)

结果如下,目前丑陋的完整代码如下GitHub

在此处输入图片描述

相关内容