渐近线 3D 标签背景

渐近线 3D 标签背景

我想在 Asymptote 中创建一个具有“背景”的 3D 标签,让标签看起来就像是印刷在海报板上一样。我不在乎这个背景在 3D 图像旋转时是否符合广告牌效果;我这里唯一需要的是静态图片。我需要标签在它后面的表面上脱颖而出。

我知道我可以通过在标签后面放置一个白色平面来伪造它,但我不知道如何正确地形成这个平面 - 如何正确找到平面的法线以便它从视点看起来是矩形。

这是一个 MWE,其中标签的文本在其后面的表面线条中有点“丢失”。

import graph3;
size(200,200,IgnoreAspect);
currentprojection=orthographic(5,5,1);
defaultrender.merge=true;

triple f(pair t) {
    return (t.y*cos(t.x),2*t.y*sin(t.x),t.y);//
}
surface s=surface(f,(0,0),(2*pi,2),32,32,Spline);
draw(s,emissive(white),meshpen=black+.2mm);

label("plot of $x$",(2,2,1.5));

我使用 TikZ 制作一些图形,它是一种简单的方式,可以用纯色背景绘制节点,使文本易于阅读。我基本上在这里寻找相同的效果。

答案1

以下解决方案有点不合时宜,但比在图片上绘图要简单得多。它创建两个标签:一个带有文本,另一个位于文本正后方(相对于相机),带有与文本大小相同的实心框。此解决方案仅在投影为正交投影时才有效。

settings.outformat="png";
settings.render=4;
import graph3;
usepackage("color");
size(200,200,IgnoreAspect);
currentprojection=orthographic(5,5,1);

// Decreasing the tubegranularity makes the gridlines look nicer.
defaultrender.tubegranularity = 1e-3;

triple forward = -unit(currentprojection.camera);
// Take the component of currentprojection.up orthogonal to forward.
triple upvec = unit(currentprojection.up - dot(currentprojection.up,forward) * forward);
triple rightvec = cross(forward, upvec);

triple f(pair t) {
    return (t.y*cos(t.x),2*t.y*sin(t.x),t.y);
}
surface s=surface(f,(0,0),(2*pi,2),32,32,Spline);
draw(s,emissive(white),meshpen=black+.2mm);

label("plot of $x$", (2,2,1.5));
label("\colorbox{black}{plot of $x$}", (2,2,1.5) + .01 forward, white+opacity(0.9));

x 的锥形标记图

答案2

回答如下渐近线讨论

//
// bglabel3d.asy
//
settings.tex="pdflatex";
settings.prc=false;
settings.render=0;

import graph3;
size(200,200,IgnoreAspect);
currentprojection=orthographic(5,5,1);
defaultrender.merge=true;

triple f(pair t) { return (t.y*cos(t.x),2*t.y*sin(t.x),t.y); }

surface s=surface(f,(0,0),(2*pi,2),32,32,Spline);
draw(s,emissive(white),meshpen=deepblue+.2mm);

label(Label("plot of $x$",Fill(orange+opacity(0.8))),(2,2,1.5));

在此处输入图片描述

编辑

正如链接答案中指出的那样,该解决方案仅适用于render=0

对于光栅图像,我们可以 在图像上绘制标签

首先,制作一个无标签的img.png

//
// scene3d.asy
//
settings.outformat="png";
settings.prc=false;
settings.render=4;
import graph3;
size(200,200,IgnoreAspect);
currentprojection=orthographic(5,5,1);
defaultrender.merge=true;

triple f(pair t) { return (t.y*cos(t.x),2*t.y*sin(t.x),t.y); }

surface s=surface(f,(0,0),(2*pi,2),32,32,Spline);

pen bpen=rgb(0.75, 0.7, 0.1);
material m=material(diffusepen=0.6bpen
  ,ambientpen=bpen
  ,emissivepen=0.4*bpen
  ,specularpen=0.8white
  ,shininess=1.0);
draw(s,m);
shipout("img");

接下来,在光栅图像上绘制标签:

settings.tex="pdflatex";
import graph;
import math; // for grid() function

defaultpen(fontsize(10pt));

real sc=1/4;
unitsize(sc*1bp);

real wd=796*sc;
real ht=808*sc;

label(
  shift(wd/2,ht/2)*
  graphic("img.png"
  ,"width="+string(wd)+"bp"
  +",height="+string(ht)+"bp"
  +",scale="+string(sc)
  ),(0,0)
);
layer();

draw(((0,0)--(wd,ht)/sc),blue+2pt);

int ngrid=100;
int n=(int)(wd/(ngrid-1)/sc);
int m=(int)(ht/(ngrid-1)/sc);
add(scale(ngrid)*grid(n,m,yellow));

xaxis( 0,wd/sc,RightTicks(Step=ngrid));
yaxis(0,ht/sc,LeftTicks(Step=ngrid));


label(Label("plot of $y$"
    ,Fill(1mm,orange+opacity(0.8))),(400,400)); 

在此处输入图片描述

相关内容