private Point2d[] optimizePacking(AreaSet as, int lines, BSProperties bsp){
double lineHeight = (bsp.bed_size[1] - 2*(bsp.extrusion_width + bsp.skirt_distance) - (lines-1)*bsp.gap)/lines;
Geometry shell0 = (Geometry)as.getShell().clone();
Envelope env0 = shell0.getEnvelopeInternal();
AffineTransformation t;
t = AffineTransformation.translationInstance(-env0.getMinX(), -env0.getMinY());
shell0 = t.transform(shell0);
env0 = shell0.getEnvelopeInternal();
Geometry shell1 = (Geometry)shell0.clone();
t = AffineTransformation.translationInstance(env0.getWidth(), lineHeight - env0.getHeight());
shell1 = t.transform(shell1);
double dist = shell0.distance(shell1);
double error = dist-2.5;
while(Math.abs(error) > 0.5){
t = AffineTransformation.translationInstance(-error/2, 0);
shell1 = t.transform(shell1);
dist = shell0.distance(shell1);
System.out.println("shell 1 distance: " + dist);
error = dist-2.5;
}
Envelope env1 = shell1.getEnvelopeInternal();
Geometry shell2 = (Geometry)shell1.clone();
t = AffineTransformation.translationInstance(env1.getWidth(), -env1.getMinY());
shell2 = t.transform(shell2);
dist = shell1.distance(shell2);
error = dist-2.5;
while(Math.abs(error) > 0.5){
t = AffineTransformation.translationInstance(-error/3, 0);
shell2 = t.transform(shell2);
dist = shell1.distance(shell2);
System.out.println("shell 2 distance: " + dist);
error = dist-2.5;
}
Envelope env2 = shell2.getEnvelopeInternal();