SVG output does not match Sketch visual?

Hi, so I’m working on a generator that creates generated art output to be printed with a DIY pen plotter.

I successfully export my generated artwork through SVG output but somehow the SVG looks all garbled up while in my sketch window it looks all neat and clean.

Here is an example of how it looks in comparison next to each other:

// remake of the mandala v1 drawing to generate circles in a circular fashion for PEN PLOTTER artwork

import processing.svg.*;
boolean record;

void setup() {
  size(1131, 800);
  pixelDensity(displayDensity()); // high-res output on retina screen
}

void draw() {
  if (record) {
    //save to file with same name as the sketch + timestamp
    beginRecord(SVG, getClass().getName()+day()+month()+year()+hour()+minute()+second()+".svg");
  }
  background(255); 
  translate(width/2, height/2); // move sketch to center
  //float radius = floor(mouseY/(height/125)); // between 1 and 125
  float radius = 125; // fixed radius
  int numPoints = floor(mouseX/(width/90)); // between 1 and 90
  float angle = TWO_PI/(float)numPoints;

  // draw the circles in a circular fashion around the points
  for (int i=0; i<numPoints; i++)
  {
    noFill();
    stroke(0);
    strokeWeight(1);
    arc(radius*-sin(angle*i), radius*cos(angle*i), radius*4, radius*4, radians(90)+(radians(360)/numPoints)*i, radians(450)+(radians(360)/numPoints)*i);
  } 

  //draw the outside circle
  ellipse(0, 0, radius*6, radius*6);

  //draw the inside circle
  ellipse(0, 0, radius*2, radius*2);

  //display values of the circle amount and radius
  push();
  translate(-width/2, -height/2);
  fill(0, 102, 153);
  text(radius, 10, 60);
  fill(0, 102, 153, 51);
  text(numPoints, 10, 90);
  pop();

  //enable filesave for svg
  if (record == true) {
    endRecord();
    record = false;
  }
}

//press the 'r' key to save a frame
void keyPressed() {
  if (key == 'r') {
    record = true;
  }
}

At first I ran the sketch by generating ellipses but that would cause issues where the beginpoint of the ellipse would always be on the right side, causing unwanted artifacts in the eventual pen plotted artwork. I wanted to move the startingpoints of the ellipses to the outside to hide these imperfections. I managed to move these to the inside instead with using rotate and translate but it was such sloppy code that I decided to draw arcs instead and have the begin and endpoints on the outside of the big circle which works really well. Except for the SVG output now being completely useless.

I am really trying to write clear and useful code and I thought I am magagning pretty well for a beginner. But clearly there is something wrong here.

ps how do I highlight arcs(), ellipse() etc in my explanation as them being processing functions?

Are there known issues with SVG output, or am I maybe executing the SVG output in the wrong part of the sketch!?

For comparison, here is the sketch working with ellipses, where you can see the SVG export actually does show the same as what the sketch shows (more messy code, because it is redundant):

// remake of the mandala v1 drawing to generate circles in a circular fashion for PEN PLOTTER artwork

import processing.svg.*;
boolean record;

void setup() {
  size(1131, 800);
  pixelDensity(displayDensity()); // high-res output on retina screen
}

void draw() {
  if (record) {
    //save to file with same name as the sketch + timestamp
    beginRecord(SVG, getClass().getName()+day()+month()+year()+hour()+minute()+second()+".svg");
  }
  background(255); 
  translate(width/2, height/2); // move sketch to center
  //float radius = floor(mouseY/(height/125)); // between 1 and 125
  float radius = 125; // fixed radius
  int numPoints = floor(mouseX/(width/90)); // between 1 and 90
  float angle = TWO_PI/(float)numPoints;

  // draw the circles in a circular fashion around the points
  for (int i=0; i<numPoints; i++)
  {
    noFill();
    stroke(0);
    strokeWeight(1);

    push();
    translate(0, -radius);  //move the generated work up to the center
    rotate((radians(360)/numPoints)*i);  //divide rotation into amount of circles generated
    translate(-radius*sin(angle), -radius*cos(angle));  //move the circles to their respective spot  
    ellipse(radius*sin(angle*i), radius*cos(angle*i), radius*4, radius*4);
    pop();
  } 

  //display values of the circle amount and radius
  push();
  translate(-width/2, -height/2);
  fill(0, 102, 153);
  text(radius, 10, 60);
  fill(0, 102, 153, 51);
  text(numPoints, 10, 90);
  pop();

  //draw the outside circle
  ellipse(0, 0, radius*6, radius*6);

  //draw the inside circle
  ellipse(0, 0, radius*2, radius*2);

  //enable filesave for svg
  if (record == true) {
    endRecord();
    record = false;
  }
}

//press the 'r' key to save a frame
void keyPressed() {
  if (key == 'r') {
    record = true;
  }
}
1 Like

when i try to run this here ( win 10 / processing 3.5.3 )
i see same AND a ERROR

textMode(SHAPE) is not supported by this renderer.

you found that too?

1 Like

Yes, I got the same error both with the ellipses and arcs. But it doesn’t seem to produce any errors with the ellipses. I didn’t understand what the textMode error means because I cannot see this being related to anything in my sketch? So I simply ignored it since everything worked as it was supposed to but maybe you’re on to something here.

I’m using Mac OS 10.10.5 and Processing 3.5.3

hm

import processing.svg.*;
boolean record;

void setup() {
  size(400, 400);
}

void draw() {
  if (record)  beginRecord(SVG, "frame-####.svg");
  background(255);
  line(mouseX, mouseY, width/2, height/2);
  arc(width/2, height/2, 100, 100, radians(0), radians(45));
  if (record) {
    endRecord();
    record = false;
  }
}

void mousePressed() {
  record = true;
}


starting from reference example
works for line and arc
and NOT show this ERROR

1 Like

I think the textMode(SHAPE) error has to do with the use of text to display the values. But for me the biggest issue is the failing SVG export. And I really do not see much difference in your example and mine. The SVG-export related values seem to be in the same spots?

Edit:
Yes, it relates to this part, when uncommented out it works well, but the SVG output is still broken:

  //display values of the circle amount and radius
  push();
  translate(-width/2, -height/2);
  fill(0, 102, 153);
  text(radius, 10, 60);
  fill(0, 102, 153, 51);
  text(numPoints, 10, 90);
  pop();

Hey,

seems to be some problem with the arc() implementation of the svg-exporter to me.
Here is a simple testcase, that should produce 4 centered circles.
For some start-end-value combinations this seems to produce wrong results.

import processing.svg.*;

void setup() {
  size(400, 400);
}

void draw() {
  beginRecord(SVG, "test.svg");

  background(255); 
  translate(width/2, height/2); // move sketch to center

  noFill();
  stroke(0);
  strokeWeight(1);
  //reference circles
  ellipse(0, 0, 300, 300);
  ellipse(0, 0, 100, 100);
  // arc around center
  arc(0, 0, 250, 250, 0.4, TWO_PI+0.4);

  stroke(255, 0, 0);
  // arc around center ??
  arc(0, 0, 200, 200, 1.1, TWO_PI+1.1);

  endRecord();
  exit();
}

Since your example code produces only full circles, would it be a workaround to use the ellipse() method? Or just a different combination of start-end points?

Regards.

1 Like

but the point seems to be that the
SVG exporter not likes

-1-
arc angles from ( 90 … 450 ) to ( 450 … 810 ) deg
whatever they will be used for later.

but a clean

    arc(posx,posy, r, r, 0, TWO_PI );

circle works in the SVG.

-2-
the new push pop
is setting a text attribute
so change back to
pushMatrix()
and one manual
noFill()
avoids the ERROR/WARNING

2 Likes

Hi Benja,

The issue was that I couldn’t get the ellipses to have their begin and endpoints on the outside circle. Therefor I decided to go with arcs, where I have full control over where I want them to start and stop.

The ONLY workaround I found for this, was to NOT close the arc:

arc(radius*-sin(angle*i), radius*cos(angle*i), radius*4, radius*4, radians(90.1)+(radians(360)/numPoints)*i, radians(449.9)+(radians(360)/numPoints)*i);

Note the 90.1 and 449.9 begin and endpoints. This leaves a 0.2 degree opening in the arc and this works. But of course it’s not ‘nice’.

I hope someone can explain what is exactly happening.

However, the current solution I found seems to be a temporary fix. I will make a pen plotter drawing right now to see if it really works and if the gap is visible (ink is unforgivable).

2 Likes

Hello, I’m sorry, I missed your reply! I think we replied at the same time somehow.

I didn’t know pushMatrix()/popMatrix() was also usable in the same way as push()/pop(). Initially I used TWO_PI for the arc degrees, I will try it out again in a copy of the sketch to see if it makes any difference. Thanks for your contribution!

1 Like

-a- well, not same way
p…Matrix deals with translate rotate …
p…Style deals with fill stroke …
the new p… does both.

that’s why i said you might need a manual noFill if a popStyle or pop conflicts with SVG lib

-b- you will use float math, so the resulting
stop - start
must be limited to TWO_PI
i try again

    int posx = int( -radius*sin(angle*i) );
    int posy = int( radius*cos(angle*i) );
    int d = int( radius*4 );
    float dang = (radians(360)/numPoints)*i;
    float ang1 = HALF_PI+dang;
//    if ( ang1 >= TWO_PI ) ang1 -= TWO_PI;
    float ang2 = ang1 + TWO_PI-0.001;
    arc(posx,posy, d, d, ang1 , ang2 );

and still needed the substraction of a littlebit like you did

2 Likes