gnuplot中的图案填充图案 [英] Hatch patterns in gnuplot

查看:105
本文介绍了gnuplot中的图案填充图案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道gnuplot是否提供比在键入"test"(例如在wxt终端)中看到的那8种模式更多的阴影图案

I am wondering if gnuplot offers more hatched patterns than those 8 patterns which you see when typing "test" (e.g. in wxt terminal)

也许有8种以上的填充模式? ...显然不是,如下面的代码所示... 我不是在说结合不同颜色的图案,我只是说图案的类型.

Maybe there are more than 8 fill patterns? ...apparently not, as the code below shows... I'm not talking about patterns combined with different colors, I just mean the type of patterns.

我希望您能实现例如水平或垂直阴影图案. 甚至可以设置剖面线之间的距离,甚至可以设置角度. 也许可以吗?

I was hoping that you can realize, for example horizontally or vertically hatched patterns. Maybe even set the distance between the hatch lines or even set the angle. Maybe you can?

### hatched pattern fill
reset session
set colorsequence classic
N = 28
set samples N
set table $Data
   plot [1:N] x
unset table
plot for [i=1:N] $Data u 1:1:(1) every ::i-1::i-1 with boxes fs pattern i not
### end of code

推荐答案

这是一个实现非标准"操作的过程(有些繁琐).图案填充. 该过程很简单,但是在gnuplot中仍然有些冗长.欢迎改进.

Here is a (somehwat cumbersome) procedure to realize "non-standard" hatch patterns. The procedure is straightforward but still somewhat lengthy in gnuplot. Improvements are welcome.

过程:

  1. 确定数据点的边界框
  2. 创建一个数据块$HatchBBox,该数据块用阴影线完全覆盖边框(请参见下面的第一张图片)
  3. 通过查找阴影线与路径的交点来剪切阴影线,并将其写入数据块$Hatch.
  4. 绘制数据块$Data$Hatch.
  1. Determine the bounding box of the datapoints
  2. create a datablock $HatchBBox which fully covers the bounding box with hatch lines (see first image below)
  3. cut the hatch lines by looking for intersections of hatch lines with the path and write it to datablock $Hatch.
  4. plot the datablock $Data and $Hatch.

$HatchBBox的示例,即覆盖封闭路径边界框的剖面线:

Example of $HatchBBox, i.e. hatch lines covering the bounding box of a closed path:

要求,限制和改进:

  • 需要封闭的路径
  • 只要凸线与路径的交点只有2个相交点,就可以用于凸面区域并限于凹面区域
  • 有待改进:填充图案不应取决于边框的大小,而应在像素级别上相等.当然可以,但是实现起来可能更加复杂.
  • requires a closed path
  • works for convex areas and limited to concave areas as long as there are only 2 intersections of hash lines with the path
  • room for improvement: hatch pattern should not depend on bounding box size but should be equal on pixel level. Certainly, somehow possible, but probably even more complicated to realize.

编辑:这是带有新说明性示例的修订版. 具有随机填充图案的随机路径工作网格.

Here is a revised version with a new illustrative example. A random pathwork grid with random hatch patterns.

为了保持概览,将实际的填充图案生成放入外部过程tbHatchArea.gpp中,并从主代码中调用.

In order to keep the overview, the actual hatch generation is put into an external procedure tbHatchArea.gpp and called from the main code.

代码:

子过程:tbHatchArea.gpp

### create hatched areas from a datablock
# input ARG1: input datablock
# input ARG2: hatch parameters
# input ARG3: output datablock

# some necessary functions
# orientation of 3 points a,b,c: -1=clockwise, 0=linear, +1=counterclockwise
Orientation(a,b,c) = sgn((word(b,1)-word(a,1))*(word(c,2)-word(a,2)) - \
                         (word(c,1)-word(a,1))*(word(b,2)-word(a,2)))

# check for intersection of segment a-b with segment c-d,
# 0=no intersection, 1=intersection
IntersectionCheck(a,b,c,d) = \
    (Orientation(a,c,b)==Orientation(a,d,b)) || (Orientation(c,a,d)==Orientation(c,b,d)) ? 0 : 1

# calculate coordinates of intersection point, "" if identical points
M(a,b) = real(word(a,1)*word(b,2) - word(a,2)*word(b,1))
N(a,b,c,d) = (word(a,1)-word(b,1))*(word(c,2)-word(d,2)) - \
             (word(a,2)-word(b,2))*(word(c,1)-word(d,1))
Intersection(a,b,c,d) = N(a,b,c,d) !=0 ? sprintf("%g %g", \
    (M(a,b)*(word(c,1)-word(d,1)) - (word(a,1)-word(b,1))*M(c,d))/N(a,b,c,d), \
    (M(a,b)*(word(c,2)-word(d,2)) - (word(a,2)-word(b,2))*M(c,d))/N(a,b,c,d)) : ""

myHatchAngle(n,m)   = word(@ARG2[n+1],m+1)  # Hatch angle 1,2
myHatchSteps(n)     = word(@ARG2[n+1],4)    # Hatch steps
myHatchLinewidth(n) = word(@ARG2[n+1],5)    # Hatch linewidth
myHatchColor(n)     = word(@ARG2[n+1],6)    # Hatch color

# create datablock hatch pattern
IndexStart = 0
IndexEnd = |@ARG2|-1
set print @ARG3
do for [k=IndexStart:IndexEnd] {    # loop all sub-datablocks if there is a line in $HatchParam
    set table $SingleCurve
        plot @ARG1 u 1:2 index k w table
    unset table
    stats $SingleCurve u 1:2 nooutput
    xmin = STATS_min_x
    ymin = STATS_min_y
    xmax = STATS_max_x
    ymax = STATS_max_y
    xrange = xmax-xmin
    yrange = ymax-ymin
    Diagonal = sqrt(xrange**2 + yrange**2)
    
    # create hatch lines covering the whole bounding box
    set samples myHatchSteps(k)+1
    amax = myHatchAngle(k,2) == myHatchAngle(k,2) ? 2 : 1  # in case there are two hatch angles
    set table $HatchBBox
        do for [a=1:amax] {
            ystart = myHatchAngle(k,a) > 0 ? ymax : ymin
            Pix(i) = xmin + xrange/myHatchSteps(k)*i
            Piy(i) = ystart - sgn(myHatchAngle(k,a))*yrange/myHatchSteps(k)*i
            plot '+' u (Pix($0)-Diagonal*cos(myHatchAngle(k,a))): \
                       (Piy($0)-Diagonal*sin(myHatchAngle(k,a))): \
                       (Pix($0)+Diagonal*cos(myHatchAngle(k,a))): \
                       (Piy($0)+Diagonal*sin(myHatchAngle(k,a))) w table
        }
    unset table 

    # looping data segments for finding intersections
    do for [i=1:|$HatchBBox|] {
        a = sprintf("%s %s", word($HatchBBox[i],1),word($HatchBBox[i],2))
        b = sprintf("%s %s", word($HatchBBox[i],3),word($HatchBBox[i],4))
        Line = ''
        Intersection0 = ""
        do for [j=1:|$SingleCurve|-1] {
            c = $SingleCurve[j]
            d = $SingleCurve[j+1]
            if (IntersectionCheck(a,b,c,d)) {
                Intersection1 = Intersection(a,b,c,d)
                if ((Intersection0 ne Intersection1)) {
                    print sprintf("%s %s",Intersection0, Intersection1)
                }
                Intersection0 = Intersection1
            }
        }
    }
    print ""; print ""
}
set print
### end of code

主要代码:

### random hatched patchwork
reset session

# create some random patchwork grid points
set print $Patchwork
do for [i=0:10] {
    do for [j=0:10] { 
        print sprintf("%g %g %g %g",i,j,i+rand(0)*0.8-0.4, j+rand(0)*0.8-0.4)
    }
}
set print

# create patchwork areas from patchwork points
set print $PatchworkFrames
do for [i=0:9] {
    do for [j=0:9] {
        k = i*11+j
        print sprintf("%s %s",word($Patchwork[i*11+j+1],3),word($Patchwork[i*11+j+1],4))
        print sprintf("%s %s",word($Patchwork[i*11+j+2],3),word($Patchwork[i*11+j+2],4))
        print sprintf("%s %s",word($Patchwork[(i+1)*11+j+2],3),word($Patchwork[(i+1)*11+j+2],4))
        print sprintf("%s %s",word($Patchwork[(i+1)*11+j+1],3),word($Patchwork[(i+1)*11+j+1],4))
        print sprintf("%s %s",word($Patchwork[i*11+j+1],3),word($Patchwork[i*11+j+1],4))
        print "";  print ""
    }
}
set print

# create random angles, linecounts, linewidths and colors
# subdatablockNo, angle1, angle2, linesCount, lineWidth, color
set print $HatchParams
do for [i=1:100] {
    print sprintf("%g %g %s %g %g %s", \
      i, a=rand(0)*180-90, rand(0)>0.5 ? sprintf("%g",-a) : "NaN", \
      int(rand(0)*10)+5, rand(0)+0.5, sprintf("0x%06x",rand(0)*0xffffff))
}
set print

set size ratio -1
set angle degrees
set xrange[-1:11]
set yrange[-1:11]

call "tbHatchArea.gpp" "$PatchworkFrames" "$HatchParams" "$Hatch"

plot $PatchworkFrames u 1:2 w l lc rgb "black" notitle, \
     for [i=0:|$HatchParams|-1] $Hatch u 1:2:($3-$1):($4-$2) index i w vec \
     lc rgb myHatchColor(i) lw myHatchLinewidth(i) nohead notitle
### end of code

结果 :(可能需要一段时间才能生成)

Result: (might take a while to generate)

这篇关于gnuplot中的图案填充图案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆