2011-08-22 5 views
1

Adobe Illustrator의 블렌드 도구와 비슷한 기능을 수행하는 소프트웨어를 작성하려고합니다. 목표는 서로 다른 가중치 (즉, 30 % 경로 1 70 % 경로 2)에서 기본 경로로 저장된 경로를 사용하여 새 경로를 만드는 것입니다. 익숙하지 않은 분들을 위해 Adobe Illustrator 예제는 다음과 같습니다. 3 steps between two vector pathsJavaScript 또는 처리의 벡터 패스 블렌딩

문제는 어디서부터 시작해야할지 모르겠습니다. 이상적으로 이것은 브라우저에서 실행될 수 있었을 것이므로 JavaScript로 처리하기를 바랬습니다. SVG를 Raphael.js 및 표준 벡터와 함께 html5 캔버스에서 사용하는 방법을 살펴 보았지만, Illustrator에서 벡터 아트를 가져 오는 것이 중요합니다 (SVG 파일을 수동으로 구문 분석하는 것은 xml이므로 아무런 문제가 없습니다).

그러나 벡터 지원이 매우 두드러지며 geomerative 라이브러리가 매우 강력 해 보이기 때문에 Processing에서도이 작업을 고려했습니다.

나는 올바른 방향으로 향하게해야하므로 시작할 수 있습니다. 너무 감사드립니다!

답변

7

SVG/JS/Raphael.js 및 geomerative에 대해 언급했습니다. 내가 말할 수있는 한 벡터 삽입/처리 비트 (JS/Java 버전을 사용하는 버전에 따라 다름)가 아닌 보간 비트에 관심이 있습니다.

블렌드하려는 도형의 정점과 블렌드하려는 도형의 정점이있는 경우 (정점 수는 두 정점 세트 모두 동일합니다), 필요한 모든 것 할 것은 값들을 보간하는 것입니다. 이 값은 다음과 같습니다. (1-t)*start+t*end; 여기서 t는 블렌드 양이며 0 (시작 모양)과 1 (끝 모양) 사이의 값입니다.

void interpolateVerts(float t,ArrayList<PVector> start,ArrayList<PVector> end,ArrayList<PVector> current){ 
    int numVerts = start.size(); 
    while(numVerts-- > 0) current.get(numVerts).set(PVector.add(PVector.mult(start.get(numVerts),(1-t)),PVector.mult(end.get(numVerts),t))); 
} 

그것은 t (배합량)를 예상 시작 및 종료 위치를 플러스로 현재 블렌딩 된 위치를 저장하는 벡터 : 여기

는 (PVector 인스턴스로 저장) 점의 두 세트를 보간 함수의 .

신속하고 더러운 데모 here (중지 아이콘 혼합 주위의 모양에주의하십시오)을 볼 수 있습니다.

두 가지 값을 보간하도록 만들어진 lerp() 함수를 사용하는 또 다른 방법이 있습니다. 귀하는 귀하의 도형에 대한 각 좌표를 보간 할 것이며, PShapes의 getVertex() 방법은 x y 좌표를 float []로 반환합니다.

: 여기

void lerpArray(float t,float[] start,float[] end, float[] current){ 
    int i = start.length; 
    while(i-- > 0) current[i] = lerp(start[i],end[i],t); 
} 

그리고 아이디어를 설명하는 빠른 스케치 시험 스케치 (mouseX = 혼합 양)입니다 : 하나의 배열과 'lerp'-ING가 PVector를 사용하는 것보다 더 간단하고 휴대가 비록 나는 반복 시작하더라도

float[] start,end,current; 
int len = 8; 
void setup(){ 
    size(200,200); 
    smooth(); 
    start = new float[len]; 
    end = new float[len]; 
    current = new float[len]; 
    setSquare(start,50,50,100,100); 
    setSquare(current,50,50,100,100); 
    setSquare(end,25,20,150,50); 
} 
void draw(){ 
    background(0); 
    lerpArray((float)mouseX/width,start,end,current); 
    beginShape(); 
    for(int i = 0 ; i < len; i+=2) vertex(current[i],current[i+1]); 
    endShape(); 
} 
void lerpArray(float t,float[] start,float[] end, float[] current){ 
    int i = start.length; 
    while(i-- > 0) current[i] = lerp(start[i],end[i],t); 
} 
void setSquare(float[] verts,float x,float y,float width,float height){ 
    verts[0] = x+width; 
    verts[1] = y; 
    verts[2] = x+width; 
    verts[3] = y+height; 
    verts[4] = x; 
    verts[5] = y+height; 
    verts[6] = x; 
    verts[7] = y; 
} 

업데이트

흠 ... 그것은 조금 더 복잡한보다입니다 밝혀졌습니다. 정점을 얻는 것이 문제가되지 않습니다. 모양을 다시 그려야합니다. PShape 정점에는 '유형'(VERTEX, BEZIER_VERTEX 등)이 있으므로 보간 후에 정점을 다시 그려야합니다. 나는 PShape와 PShapeSVG를 확장하려고 시도했지만 (구조와 같은 PShape의 트리 때문에) 신속하게 문제에 부딪혔다. Processing은 opensource이기 때문에 나는 호기심에서 정점 위치에 setter를 추가하고 채우기 색상에 getter/setter를 추가하여 PShape 클래스를 수정 한 다음 라이브러리 (코어)를 다시 컴파일합니다.당신은 사용자 폴더에 컴파일 core.jar를 파일이 포함 된 Eclipse 프로젝트 here을 다운로드 할 수 있습니다

BlendShape1BlendShape2BlendShape3

항아리). 문제 해결을위한 권장 방법은 아닙니다. 여기 포어 참조 코드입니다 : 제외

package svgblend; 

import processing.core.PApplet; 
import processing.core.PShape; 

public class SVGBlend extends PApplet { 
    PShape start,end,current; 

    public void setup(){ 
     size(200,200); 
     smooth(); 
     start = loadShape("start.svg").getChild("start"); 
     end  = loadShape("end.svg").getChild("end"); 
     current = loadShape("start.svg").getChild("start"); 
     println(current.getFamily()); 
    } 
    public void draw(){ 
     background(255); 
     blendShape(start,end,current,(float)mouseX/width); 
     shape(current,0,0); 
    } 
    void blendShape(PShape start,PShape end, PShape current,float amt){ 
     int i = start.getVertexCount(); 
     //verts 
     while(i-- > 0) { 
      float[] s = start.getVertex(i); 
      float[] e = end.getVertex(i); 
      current.setVertexX(i, lerp(s[0],e[0],amt)); 
      current.setVertexY(i, lerp(s[1],e[1],amt)); 
     } 
     //colour 
     int sFill = start.getFillColor(); 
     int eFill = end.getFillColor(); 
     current.setFillColor((int)lerpColor(sFill,eFill,amt)); 
    } 
} 

해키 PShape의 접근이 /가 시작 모양의 꼭지점의 수는 최종 형태의 것과 동일하고, 위치 때문에 만 좋아 보이는 작품 엄청난 양으로 바뀌지 마라. 결론적으로 이것은 더럽고 융통성이없는 일입니다.

Geomerative와 같은 다른 라이브러리를 사용하거나 SVG를 구문 분석하여 생성 된 모양을 수정/업데이트하는 더 깨끗한 방법을 구현하는 것이 더 좋지만 문제의 절반을 해결합니다. 나머지 절반은 올바르게 블렌딩됩니다. 예를 들어 일러스트 레이터에서 두 개의 임의 모양 (두 모양에서 정점 수가 다름)에서 혼합 할 수 있습니다. 보간하기 전에 모양에 정점 수가 다르며 제대로 배치 할 때 여분의 정점을 생성해야합니다. 거기에 몇 가지 papers 밖으로 모양의 블렌딩을 논의하고있다. 이 정보가 귀하에게 필요한 방향을 제공하기를 바랍니다.

Goodluck!