如何在 MetaPost 中制作尺寸线?

如何在 MetaPost 中制作尺寸线?

MetaPost 中是否有制作尺寸线的宏?我在 Metafun 手册和其他手册中没有找到任何有用的东西。确切地说,我想绘制类似下图中的“长度”尺寸线:

在此处输入图片描述

答案1

我已经看过了各种贡献的宏可在 CTAN 上使用,但我看不到任何专门用于尺寸箭头的东西,因此这是我的努力。

def drawdimarrow expr p = _apth:=p; _dimdarr enddef;

def _dimdarr text t =
  save dimbar; path dimbar;
  (_x, _y) = dir 1/2 ahangle;
  dimbar = (down--up) scaled (ahlength / _x * _y * 1.2);
  forsuffixes @=0, infinity:
    draw dimbar rotated angle direction @ of _apth shifted point @ of _apth withpen currentpen t; 
  endfor
  drawdblarrow _apth withpen currentpen t
enddef;

要使用此功能,请将上述行粘贴到您的 MP 文件中,或将它们放在本地 TEXMF 路径中某个单独的文件中,然后使用input它来包含它。然后您可以执行以下操作:

beginfig(1);
    ahlength := 6; ahangle := 30;
    drawdimarrow (origin -- 100 right rotated 30);
endfig;

在此处输入图片描述

ahlength您可以使用常用的内部参数和自定义箭头的大小和形状ahangle。这也应该可以很好地与麻雀,这样你就可以得到不同风格的箭头:

input mparrows
beginfig(1);
    setarrows(open);
    drawdimarrow (origin -- 100 right rotated 30);
endfig;

在此处输入图片描述

以下是在更复杂的绘图中使用它们的一种方法:

input mparrows
beginfig(1);
    setarrows(open);

    path a; 
    a = unitsquare xscaled 89 yscaled 55 rotated 10;
    draw a;

    path d[];
    d1 = subpath (1, 2) of a shifted (10 unitvector(direction 3/2 of a rotated -90));
    d2 = subpath (2, 3) of a shifted (10 unitvector(direction 5/2 of a rotated -90));
    drawdimarrow d1;  
    drawdimarrow d2;

    picture p[];
    p1 = thelabel("55", point 1/2 of d1); unfill bbox p1; draw p1;
    label.top("89", point 1/2 of d2);
endfig;

在此处输入图片描述

扩展箭头宏来处理标签可能很诱人,但我认为这是个错误。让每个宏只做一件事更符合普通 MP 的精神。因此,我建议使用普通工具来添加标签,以便沿路径放置标签;上面显示了两种可能性。

答案2

以下是实现此操作的方法:

leaderextension:=0.25cm;
leadergap := 0.15cm;
def _draw_dim(expr A, B, extang, leadang, obliqueang, textang, offset, Text) =
  % Generic function to draw extension lines
  begingroup;
    pair C, D, E, F, G, H;
    pair CA;
    pen cpen;
    cpen := currentpen;
    pickup defaultpen;
    C := A + offset * dir(extang);
    CA := dir(angle(C-A));
    % Project B-A in the direction of leadang
    D := C + (
        ((xpart (B-A)) * (xpart (dir(leadang))))
        + ((ypart (B-A)) * (ypart (dir(leadang)))))
      * dir(leadang);
    % Use C-A as the angle because it's set by offset which is non-zero hopefully
    E := C +  leaderextension * CA;
    F := D +  leaderextension * CA;
    G := A + leadergap * CA;
    H := B + leadergap * CA;
    picture lab;
    picture arr;
    arr := image(drawdblarrow (0,0)--(abs(D-C),0););
    draw ((arr slanted (sind(obliqueang)/cosd(obliqueang))) rotated angle(D-C)) shifted C;
    lab:=(thelabel(Text, (0,0)) slanted (sind(obliqueang)/cosd(obliqueang))) rotated textang shifted 0.5[C,D];
    draw G--E;
    draw H--F;
    unfill bbox lab; draw lab;
    pickup cpen;
  endgroup;
enddef;
def draw_aligned_dim(expr A, B, Text, offset) =
  _draw_dim(A, B, (angle(A-B) + 90), (angle(A-B)), 0, 0, offset, Text);
enddef;
def draw_vertical_dim(expr A, B, Text, offset) =
  _draw_dim(A, B, (0), -90, 0, 0, offset, Text);
enddef;
def draw_horizontal_dim(expr A, B, Text, offset) =
  _draw_dim(A, B, (90), 0, 0, 0, offset, Text);
enddef;
def draw_oblique_dim(expr A, B, Text, offset, measang, extang, alt) =
  if alt:
    _draw_dim(A, B, extang, measang, extang, measang, offset, Text);
  else:
    _draw_dim(A, B, extang, measang, -extang, measang, offset, Text);
  fi;
enddef;
def draw_angle_dim(expr A, B, C, Text, offset) =
  begingroup;
    cpen := currentpen;
    pickup defaultpen;
    pair D, E, F, G, H, I, J;
    numeric ang[];
    ang1 := angle(A-C);
    ang2 := angle(B-C);
    ang3 := (ang1 + ang2) / 2.0;
    D := A + offset * dir(ang1);
    E := C + (abs (D - C)) * dir(ang2);
    ang4 := angle(D-A);
    ang5 := angle(E-B);
    F := D + leaderextension * dir(ang4);
    G := E + leaderextension * dir(ang5);
    H := A + leadergap * dir(ang4);
    I := B + leadergap * dir(ang5);
    J := C + (abs(D - C) * dir(ang3));
    draw H--F;
    draw I--G;
    path p;
    p := D{dir(ang1 + 270)} .. J{dir(ang3 + 270)} .. E{dir(ang2 + 270)};
    drawdblarrow p;
    picture lab;
    lab := thelabel(Text, J);
    unfill bbox lab; draw lab;
    pickup cpen;
  endgroup;
enddef;
def draw_radial_dim(expr C, r, ang, Text, offset) =
  begingroup;
    pair A, B, D;
    A := C + dir(ang) * r;
    B := C + dir(ang) * (r + offset);
    drawarrow (if offset > 0 : B else: C fi) --A;
    picture lab;
    lab := thelabel(Text, B);
    unfill bbox lab; draw lab;
  endgroup;
enddef;

以下是一些用法示例:

beginfig(0)
  begingroup;
    pair v[];
    v[0] := (0,0);
    v[1] := (2cm, 0);
    v[1] := v[1] rotated 30;
    v[2] := v[1] rotated 120 shifted v[1];
    v[3] := v[1] rotated 120;
    v[4] := v[1] rotated 240;
    v[5] := v[1] shifted v[4];
    v[6] := v[3] shifted v[4];
    draw v[0]--v[1]--v[2]--v[3]--cycle;
    draw v[0]--v[4]--v[5]--v[1];
    draw v[4]--v[6]--v[3];
    draw_oblique_dim(v[5], v[1], btex vert etex, 2cm, 90, 30, true);
    draw_oblique_dim(v[5], v[1], btex vert etex, 2cm, 90, -30, true);
    draw_oblique_dim(v[4], v[5], btex flat etex, 2cm, 30, -30, true);
    draw_oblique_dim(v[6], v[4], btex flat etex, -2cm, -30, 30, true);
    draw_oblique_dim(v[4], v[0], btex vert etex, 2cm, 90, -30, false);
    draw_oblique_dim(v[3], v[0], btex vert etex, -2cm, -30, 30, false);
  endgroup;
endfig;

beginfig(1)
  begingroup;
    numeric u;
    u := 2in;
    pair P[];
    P0 = (0,0);
    P1 = (1u, 0);
    P2 = (0.4u, 0.7u);
    draw P0--P1--P2--cycle;
    draw_aligned_dim(P0, P1, btex $a$ etex, .2u);
    draw_aligned_dim(P1, P2, btex $b$ etex, .2u);
    draw_aligned_dim(P2, P0, btex $c$ etex, .2u);
    draw_angle_dim(P0, P2, P1, btex $\theta$ etex, -.5u);
    label(btex $c^2 = a^2 + b^2 - 2 a b \cos{\theta}$ etex, (0.5u, -.4u));
  endgroup  ;
endfig;

beginfig(2)
  begingroup;
    path c;
    numeric radius;
    radius := 0.75in;
    c := fullcircle scaled (2 * radius);
    draw fullcircle scaled .1in;
    draw c;
    draw_radial_dim((0,0), radius, 120, btex $r$ etex, -0.25in);
    pair P[];
    P1 := (point 5 of c);
    P2 := (point 8 of c);
    dotlabel.lft(btex $A$ etex, P1);
    dotlabel.rt(btex $B$ etex, P2);
    path beam;
    beam := P1--P2;
    draw beam withpen pencircle scaled 1bp;
    dotlabel.ulft(btex $dog$ etex, 0.3[P1,P2]);
    draw_aligned_dim(P1, P2, btex $l$ etex, 0.75in);
  endgroup;
endfig;

立方体

余弦定律

半径

相关内容