TransWikia.com

tikzpicture: make a foreach draw [yshift=n*u] stop at coordinate 1

TeX - LaTeX Asked on March 20, 2021

Consider the bottom section of this MWE, namely everything below (% Image Ruler y):

documentclass{article}

usepackage{mwe} % Dummy images
usepackage[skins]{tcolorbox}
tcbuselibrary{raster}

usepackage{tikz}
usepackage{tikzpagenodes} % current page text area.center
usetikzlibrary{calc} 
pgfkeys{/tikz/savevalue/.code 2 args={globaledef#1{#2}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

defShowHelps{0} %    1 'yes'        0   'no'

newcommand{UOneCoordinateX}{0.2}
newcommand{UOneCoordinateY}{0.09}
newcommand{UTwoCoordinateX}{0.2}
newcommand{UTwoCoordinateY}{0.284}

newcommand{GridSize}{0.05}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

begin{document}

begin{tikzpicture}[
remember picture, overlay, % page center 1/3
shift={(current page.center)}, % page center 2/3
font=sffamily,
Help/.style={font=Huge, red}
]
node[anchor=center, %south west,
inner sep=0 pt] (myimage) at (0,0) {

begin{tcbitemize}[size=tight, halign=center, colback=gray, raster equal skip=0pt, raster left skip=0mm, raster right skip=0mm, raster width=1textwidth, boxrule = 0pt, frame hidden]
tcbitem includegraphics[width=textwidth]{example-image.jpg}
tcbitem includegraphics[width=textwidth]{example-image.jpg}
end{tcbitemize}  
};
begin{scope}[x={($2*(myimage.east)$)},y={($2*(myimage.north)$)},
shift={(myimage.south west)} % page center 3/3
]

% Restrict the draw area
clip (-0.1,-0.1) rectangle (1.1,1.1);

%%%%%ShowHelps
path[] (UOneCoordinateX,UOneCoordinateY) coordinate(U1) -- (UTwoCoordinateX,UTwoCoordinateY) coordinate(U2);
ifnumShowHelps=1 draw[Help] (U1) circle(2pt) node[label=left:U1]{} -- (U2) circle(2pt) node[label=left:U2]{};fi % show unitlength line

path let p1=($(U2)-(U1)$) in 
pgfextra{  pgfmathsetlengthmacro{unitlength}{veclen(x1,y1)}   }
[savevalue={u}{unitlength}];
ifnumShowHelps=1 node[Help] at (0.725,0.25) {unitlength U1U2 = u}; fi%<--- show unitlength
ifnumShowHelps=1 draw[blue, transform canvas={xshift=2mm}] (U1) -- +(0,u);fi  % Test

% Image Ruler y
draw[very thick] (0,0) coordinate(B) -- (0, 1);
foreach n in {0,1,...,10}{%%
draw[very thick] ([yshift=n*u]B) -- +(-3mm,0) node[left]{
ifnumn=0 else ifnumn=1 n,cm else n fifi}; 
}%%
foreach n in {0.1,0.2,...,10}{%% 
draw[] ([yshift=n*u]B) -- +(-1.5mm,0);
}%%

end{scope}
end{tikzpicture}

end{document}

Namely:

draw[very thick] (0,0) coordinate(B) -- (0, 1);
foreach n in {0,1,...,10}{%%
draw[very thick] ([yshift=n*u]B) -- +(-3mm,0) node[left]{
ifnumn=0 else ifnumn=1 n,cm else n fifi}; 
}%%
foreach n in {0.1,0.2,...,10}{%% 
draw[] ([yshift=n*u]B) -- +(-1.5mm,0);
}%%

The 1 in draw[very thick] (0,0) coordinate(B) -- (0, 1); makes sure that the thick vertical line of the ruler stops at coordinate 1. This is great!

However, how to also make the small lines stop at 1, without changing the clipping (clip (-0.1,-0.1) rectangle (1.1,1.1);)?

It could be done by changing the 10 in foreach n in {0.1,0.2,...,10}{%% to 5, but that is not what I aim for, since I do not know in advance how many numbers I will need. All I know is that I will want to stop at the y-coordinate 1, just in the same way as the thick vertical line stops at 1 using draw[very thick] (0,0) coordinate(B) -- (0, 1);.

Here’s a screenshot:

enter image description here

So, in short:

I need a method to be able to extract the current coordinate of y … I don’t know how many times I will have to loop-increment the centimeters and the milimeters, all I know is that it should stop at 1

2 Answers

Method using decoration enter image description here

documentclass{article}
usepackage{tikz}
usetikzlibrary{decorations}
usepackage{mwe}

newcounttick
newcountmajortick
newififmajortick

pgfdeclaredecoration{ruler}{initial}{
  state{initial}[
    width=0mm, next state=ruler,
    persistent precomputation={
      tick=10
      majortick=0
    }
  ]{
  }
  state{ruler}[width=1mm,
    persistent precomputation={
      ifnum tick=10relax
        majorticktrue
        tick=0
      else
        majortickfalse
      fi
      advancetick by 1
    },
    persistent postcomputation={
      ifnum tick=10relax
        advancemajortick by 1
      fi
    }
  ]{
    ifmajortick
      pgfscope
      pgftransformrotate{-90}
      pgftransformshift{pgfpoint{-4mm}{0pt}}
      pgfnode{rectangle}{east}{themajortick}{}{pgfusepath{}}
      endpgfscope
    fi
    pgfpathmoveto{pgfpointorigin}
    ifmajortick
      pgfsetlinewidth{1pt}
      pgfpathlineto{pgfpoint{0pt}{3mm}}
    else
      pgfsetlinewidth{0.4pt}
      pgfpathlineto{pgfpoint{0pt}{1mm}}
    fi
    pgfusepath{stroke}
  }
  state{final}{}
}

begin{document}
begin{tikzpicture}
node[inner sep=0pt] (a) {includegraphics[width=.5textwidth]{example-image}};
draw[postaction=decorate, decoration=ruler] (a.south west) -- (a.north west);
end{tikzpicture}
end{document}

Correct answer by ZhiyuanLck on March 20, 2021

I don't think, that you will truely need clip (-0.1,-0.1) rectangle (1.1,1.1); due to the work with tcolorbox.

But as an answer to the question "How to clip the y-axis":
You need to know, how many points "1", the image-height, is. And this is measured out in exactly the same way, as the "unitlength" was measured out in the code:

path[draw=none] (0,0) coordinate(LL) -- (0,1) coordinate(UL);
path let p1=($(UL)-(LL)$) in 
pgfextra{  pgfmathsetlengthmacro{ImageHeight}{veclen(x1,y1)}   }
[savevalue={h}{ImageHeight}];

foreach n in {0.1,0.2,...,10}{%%
pgfmathsetmacroYshift{n*u}
pgfmathsetmacroYshiftTest{n*u < h ?  1 : 0}
ifnumYshiftTest=1 draw[] ([yshift=Yshift]B) -- +(-1.5mm,0); elsefi
}%%
ifnumShowHelps=1
draw[red] (LL) circle(2pt) node[below]{LL};
draw[red] (UL) circle(2pt) node[above]{UL};
node[right=3mm, Help] at (UL) {Image Height h=h};    fi 

enter image description here

documentclass{article}

usepackage{mwe} % Dummy images
usepackage[skins]{tcolorbox}
tcbuselibrary{raster}

usepackage{tikz}
usepackage{tikzpagenodes} % current page text area.center
usetikzlibrary{calc} 
pgfkeys{/tikz/savevalue/.code 2 args={globaledef#1{#2}}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

defShowHelps{1} %    1 'yes'        0   'no'

newcommand{UOneCoordinateX}{0.2}
newcommand{UOneCoordinateY}{0.09}
newcommand{UTwoCoordinateX}{0.2}
newcommand{UTwoCoordinateY}{0.284}

newcommand{GridSize}{0.05}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

begin{document}

begin{tikzpicture}[
remember picture, overlay, % page center 1/3
shift={(current page.center)}, % page center 2/3
font=sffamily,
Help/.style={font=large, text=red, fill=yellow}
]
node[anchor=center, %south west,
inner sep=0 pt] (myimage) at (0,0) {

begin{tcbitemize}[size=tight, halign=center, colback=gray, raster equal skip=0pt, raster left skip=0mm, raster right skip=0mm, raster width=1textwidth, boxrule = 0pt, frame hidden]
tcbitem includegraphics[width=textwidth]{example-image.jpg}
tcbitem includegraphics[width=textwidth]{example-image.jpg}
end{tcbitemize}  
};
begin{scope}[x={($2*(myimage.east)$)},y={($2*(myimage.north)$)},
shift={(myimage.south west)} % page center 3/3
]

% Restrict the draw area
clip (-0.1,-0.1) rectangle (1.1,1.1);
ifnumShowHelps=1 draw[red] (-0.1,-0.1) rectangle (1.1,1.1);fi

%%%%%ShowHelps
path[] (UOneCoordinateX,UOneCoordinateY) coordinate(U1) -- (UTwoCoordinateX,UTwoCoordinateY) coordinate(U2);
ifnumShowHelps=1 draw[red] (U1) circle(2pt) node[label=left:U1]{} -- (U2) circle(2pt) node[label=left:U2]{};fi % show unitlength line

path let p1=($(U2)-(U1)$) in 
pgfextra{  pgfmathsetlengthmacro{unitlength}{veclen(x1,y1)}   }
[savevalue={u}{unitlength}];
ifnumShowHelps=1 node[Help] at (0.3,0.5) {unitlength U1U2 = u}; fi%<--- show unitlength
ifnumShowHelps=1 draw[blue, transform canvas={xshift=2mm}] (U1) -- +(0,u);fi  % Test



% Image Ruler y
draw[very thick] (0,0) coordinate(B) -- (0, 1);
foreach n in {0,1,...,10}{%%
draw[very thick] ([yshift=n*u]B) -- +(-3mm,0) node[left]{
ifnumn=0 else ifnumn=1 n,cm else n fifi}; 
}%%

path[draw=none] (0,0) coordinate(LL) -- (0,1) coordinate(UL);
path let p1=($(UL)-(LL)$) in 
pgfextra{  pgfmathsetlengthmacro{ImageHeight}{veclen(x1,y1)}   }
[savevalue={h}{ImageHeight}];

foreach n in {0.1,0.2,...,10}{%%
pgfmathsetmacroYshift{n*u}
pgfmathsetmacroYshiftTest{n*u < h ?  1 : 0}
ifnumYshiftTest=1 draw[] ([yshift=Yshift]B) -- +(-1.5mm,0); elsefi
}%%
ifnumShowHelps=1
draw[red] (LL) circle(2pt) node[below]{LL};
draw[red] (UL) circle(2pt) node[above]{UL};
node[right=3mm, Help] at (UL) {Image Height h=h};    fi 
end{scope}
end{tikzpicture}

end{document}

Answered by cis on March 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP