Вы упомянули SVG / JS / Raphael.js и геомеративный.Насколько я могу судить, вас интересует бит интерполяции, а не бит загрузки / обработки вектора (который будет зависеть от того, какую версию вы будете использовать JS / Java).
Пока вы 'Если у вас есть вершины формы, которую вы хотите смешать, и вершины фигуры, с которой вы хотите смешать (количество вершин будет одинаковым для обоих наборов вершин), все, что вам нужно сделать, это интерполировать значения.Это будет что-то вроде: (1-t)*start+t*end;
, где t - это величина наложения, значение от 0 (начальная форма) до 1 (конечная форма).
Вот функция, которая интерполирует два набора точек (сохраненных как PVectorэкземпляры):
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 (сумма смешивания), начальная и конечная позиции, а также вектор для сохранения текущих смешанных позиций.
Вы можете увидеть быстрое и грязное демо здесь (обратите внимание на форму вокруг наложения значка «Стоп»).
Другой способ добиться этого - использовать функцию lerp () , которая предназначена для интерполяции между двумяценности.Вы будете интерполировать каждую координату для своей фигуры, а метод PShapes ' getVertex () возвращает координаты xy в число с плавающей точкой [].Я предполагаю, что зацикливание, хотя один массив и «lerp» более прост и более переносим, чем использование PVector:
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 = количество смеси):
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).Поскольку обработка является открытым исходным кодом, из любопытства я настроил класс PShape, добавив сеттеры для позиций вершин и геттеры / сеттеры для цвета заливки, а затем перекомпилировал библиотеку (core.jar)
Вы можете скачать проект eclipse здесь , который включает в себя перекомпилированный файл core.jar в папке пользователя.Обратите внимание, что это НЕ рекомендуемый способ решения проблем.Для справки здесь используется код:
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, лучше, но решает половину проблемы,Другая половина правильно смешивается.Например, в Illustrator можно смешивать две произвольные формы (количество вершин различается в двух формах).Перед интерполяцией дополнительные вершины необходимо будет сгенерировать, когда фигуры имеют разное количество вершин и размещены правильно.Есть несколько статей , где обсуждается смешивание форм.Я надеюсь, что эта информация предоставит вам нужное вам направление.
Goodluck!