점근선 표면의 그리드(튜브) 모서리를 닫습니다.

점근선 표면의 그리드(튜브) 모서리를 닫습니다.

다음을 사용하여 안장 표면을 그리는 간단한 그림을 살펴보세요.asymptote

import graph3;

real f (pair p) {
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);
}

surface saddle=surface(f,(-2,-2),(2,2),nx=5,Spline);

draw(saddle,gray,0.1+blue);

출력의 스냅샷을 살펴보세요.

출력의 스냅샷

그리드 선을 형성하는 튜브가 표면 모서리에서 결합되는 불쾌한 방식을 볼 수 있습니다. 해결 방법으로 모서리에 올바른 반경의 공을 수동으로 추가할 수도 있습니다. 예를 들어 다음 줄을 추가합니다.

draw(shift(-2,-2,f((-2,-2)))*scale(0.05,0.05,0.05)*unitsphere,blue);

다음과 같은 개선을 얻습니다. 여기에 이미지 설명을 입력하세요

더 좋은 방법이 있는지 궁금합니다. 그리드 선(더 정확하게 말하면 튜브)의 연결을 어떻게 잘 닫아야 합니까?

답변1

일반적으로 를 사용하지 않는 한 표면을 그릴 때 옵션을 settings.render=0사용하지 않는 것이 좋습니다 . meshpen메시를 직접 그리면 여러 가지 장점이 있습니다. 문제를 해결하는 것은 이러한 이점 중 가장 중요하지 않은 것 중 하나입니다.

settings.outformat="png";
settings.render=8;
unitsize(1cm);

import graph3;

currentprojection=perspective(5,5,5);

pen meshpen = 2pt + 0.7blue + 0.1green;

real f (pair p) {
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);
}

surface saddle=surface(f,(-2,-2),(2,2),nx=5,Spline);

draw(saddle, surfacepen=gray);

for(int x = -2; x <= 2; ++x) {
  draw(graph(new triple(real y) {return (x,y,f((x,y)) );}, -2, 2), meshpen);
}
for (int y = -2; y <= 2; ++y) {
  draw(graph(new triple(real x) {return (x,y,f((x,y)) );}, -2, 2), meshpen);
}

결과가 있음

여기에 이미지 설명을 입력하세요

저는 일반적으로 훨씬 얇은 눈금선을 선호하지만 실제로 문제가 나타나는지 확인할 수 있도록 눈금선을 두껍게 만들었습니다.

반면에 실제로 눈금선을 두껍고 튜브처럼 음영 처리하려는 경우 솔루션은 꽤 좋은 솔루션입니다. 기본적으로 선에 둥근 캡을 추가합니다(튜브 음영 없이 격자선을 그릴 때 자동으로 수행됨). 튜브형 경로를 손으로 그리려면 모듈의 매뉴얼 섹션(Asymptote 2.23 매뉴얼의 p. 134) tube에 설명된 방법을 확인해야 합니다. three이 접근 방식을 사용하는 대안은 그리드 가장자리에 격자선을 그리는 대신 그래프 가장자리에 순환 경로를 그리는 것(튜브)입니다.


업데이트: 메쉬를 손으로 그리는 방법은 다음과 같습니다(튜브와 별도의 윤곽선 포함). 혼란을 피하기 위해 펜 이름을 변경했습니다. 연산자는 &끝점을 공유하는 두 경로를 연결하기 위한 것입니다.

settings.outformat="png";
settings.render=8;
unitsize(1cm);

import graph3;

surface operator cast(tube t) {
  return t.s;
}

currentprojection=perspective(5,5,5);

pen gridpen = blue;

real f (pair p) {
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);
}

int xmin = -2, xmax=2, ymin=-2, ymax=2;

surface saddle=surface(f,(xmin,ymin),(xmax,ymax),nx=5,Spline);

draw(saddle, surfacepen=gray);

int nx=5, ny=5;

path3 x_equals(real x) {
  return graph(new triple(real y) {return (x,y,f((x,y)));}, ymin, ymax);
}
path3 y_equals(real y) {
  return graph(new triple(real x) {return (x,y,f((x,y)));}, xmin, xmax);
}

real tubewidth = 0.1;

for(int i = 1; i < nx; ++i) {
  real x = (xmax-xmin)*(i/nx) + xmin;
  surface todraw = tube(x_equals(x), width=tubewidth);
  draw(todraw, gridpen);
}
for (int i = 1; i < ny; ++i) {
  real y = (ymax-ymin)*(i/ny) + ymin;
  surface todraw = tube(y_equals(y), width=tubewidth);
  draw(todraw, gridpen);
}

path3 outline = x_equals(xmin) & y_equals(ymax) & reverse(x_equals(xmax)) & reverse(y_equals(ymin)) & cycle;
draw(tube(outline,width=tubewidth), gridpen);

결과:

여기에 이미지 설명을 입력하세요

답변2

OP에서 언급한 해결 방법은 다음과 같습니다.

import graph3;

real gridWidth=0.05;
pen  gridPen=blue;

real f (pair p) {
  real x = p.x;
  real y = p.y;
  return 0.5*(x^2-y^2);
}

void fillGap (pair p) {
  real width=0.5*gridWidth;
  draw(shift(p.x,p.y,f(p))*scale(width,width,width)*unitsphere,gridPen);
}

real minVal = -2;
real maxVal = -minVal;

surface saddle=surface(f,(minVal,minVal),(maxVal,maxVal),nx=5,Spline);

draw(saddle,gray+opacity(0.95),gridWidth+gridPen);

fillGap((minVal,minVal));
fillGap((minVal,maxVal));
fillGap((maxVal,minVal));
fillGap((maxVal,maxVal));

올바른 위치에 구를 그리는 데 도움이 될 수 있는 몇 가지 추가 매개변수와 함수를 정의했습니다.

관련 정보