这里有一个非常朴素的方法:根据需要划分的行数,在按从左到右排序的顶部和底部顶点之间进行插值。
我已经使用Processing进行了快速测试:
PShape svg,shape;
int divisions = 3;
ArrayList<PVector> top = new ArrayList<PVector>();
ArrayList<PVector> bottom = new ArrayList<PVector>();
int numVerts;
int ptSize = 5;
void setup(){
svg = loadShape("shape.svg");
size((int)svg.width,(int)svg.height);
shape = svg.getChild(0);
numVerts = shape.getVertexCount();
float minY = height,maxY = 0;
for(int i = 0 ; i < numVerts; i++){
PVector v = shape.getVertex(i);
if(v.x < minY) minY = v.y;
if(v.y > maxY) maxY = v.y;
}
float yThresh = (maxY-minY) * .25;
for(int i = 0 ; i < numVerts; i++){
PVector v = shape.getVertex(i);
if(v.y <= minY+yThresh) top.add(v);
if(v.y >= maxY-yThresh) bottom.add(v);
}
PVector last = bottom.get(bottom.size()-1);
PVector first = bottom.get(0);
bottom.set(0,last);
bottom.set(bottom.size()-1,first);
}
void draw(){
background(255);
shape(shape,0,0);
stroke(0,192,0);
for(PVector v : top) ellipse(v.x,v.y,ptSize,ptSize);
stroke(192,0,0);
for(PVector v : bottom) ellipse(v.x,v.y,ptSize,ptSize);
stroke(0,0,255);
float lerpStep = 1.0/(divisions+1);
for(int i = 0 ; i < divisions; i++){
for(int j = 0 ; j < top.size(); j++){
PVector vTop = top.get(j);
PVector vBottom = bottom.get(j);
PVector vLerp = PVector.lerp(vTop,vBottom, lerpStep * (i+1));
ellipse(vLerp.x,vLerp.y,ptSize,ptSize);
}
}
}
void keyPressed(){
if(keyCode == UP) divisions++;
if(keyCode == DOWN) divisions--;
}
这里是 shape.svg:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="960px" height="560px" viewBox="0 0 960 560" enable-background="new 0 0 960 560" xml:space="preserve">
<polygon fill="#D8D8D8" points="279,100 479,60 681,100 641,501 480,482 322,501 "/>
</svg>
这里是一个预览,顶部的顶点标记为绿色,底部为红色,插值的顶点为蓝色:
正如@Joseph O'Rourke所提到的,如果底部和底部路径不相似(我猜想是顶点数量和从左到右的顺序不同),那么问题会更具挑战性。在这种情况下,可以实现混合算法(例如
this one)。如果您已经在SVG格式中玩弄各种形状,那么您应该能够通过在
Inkscape或Illustrator中先尝试它来测试混合是否解决了您的问题。
i*w
距离的描边线,然后构建多边形即可。其中,w
为图层厚度,i=0,1,2,3,...
。 - Spektre