I use this function to determine the bounding box of an ofPath if it’s not in command mode. Does this make sense? Is there a quicker method?
Also, yeah, getting the arc is possibly mathematically incorrect, potential shame on me. what do you do there? calculate for both radii and then interpolate with … no wait, it should be as simple as knowing which radius belongs to which angle, right?
ofRectangle getBoundingBoxOfPath( ofPath * path ){
ofRectangle rec;
rec.set(FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN);
for(int c = 0; c < path->getCommands().size(); c++){
unsigned int points = 0;
unsigned int k;
switch (path->getCommands()[c].type) {
case ofPath::Command::lineTo:
case ofPath::Command::curveTo:
points = 1;
break;
case ofPath::Command::arc:
points = 2;
break;
case ofPath::Command::bezierTo:
case ofPath::Command::quadBezierTo:
points = 3;
break;
case ofPath::Command::moveTo:
case ofPath::Command::close:
points = 0;
break;
default:
assert(0);
}
if(points == 1 || points == 3){
rec.x = min(rec.x, path->getCommands()[c].to.x);
rec.width = max(rec.width, path->getCommands()[c].to.x);
rec.y = min(rec.y, path->getCommands()[c].to.y);
rec.height = max(rec.height, path->getCommands()[c].to.y);
if(points == 3){
rec.x = min(min(rec.x, path->getCommands()[c].cp1.x),path->getCommands()[c].cp2.x);
rec.width = max(max(rec.width, path->getCommands()[c].cp1.x),path->getCommands()[c].cp2.x);
rec.y = min(min(rec.y, path->getCommands()[c].cp1.y),path->getCommands()[c].cp2.y);
rec.height = max(max(rec.height, path->getCommands()[c].cp1.y),path->getCommands()[c].cp2.y);
}
} else if (points == 2) {
// WARNING: no idea if the following is mathematically correct, since we have two different radii
float h1 = sin(path->getCommands()[c].angleBegin) * path->getCommands()[c].radiusX;
float w1 = sqrt((h1*h1) - (path->getCommands()[c].radiusX*path->getCommands()[c].radiusX));
float h2 = sin(path->getCommands()[c].angleEnd) * path->getCommands()[c].radiusY;
float w2 = sqrt((h2*h2) - (path->getCommands()[c].radiusY*path->getCommands()[c].radiusY));
rec.x = min(min(rec.x, path->getCommands()[c].cp1.x+w1),path->getCommands()[c].cp1.x+w2);
rec.width = max(max(rec.x, path->getCommands()[c].cp1.x+w1),path->getCommands()[c].cp1.x+w2);
rec.y = min(min(rec.x, path->getCommands()[c].cp1.y+h1),path->getCommands()[c].cp1.y+h2);
rec.height = max(max(rec.x, path->getCommands()[c].cp1.y+h1),path->getCommands()[c].cp1.y+h2);
}
}
rec.width -= rec.x;
rec.height -= rec.y;
return rec;
}
btw, i had a small formatting error in this post, and i can’t edit it without adding this sentence here because “Body is too similar to what you recently posted”. Shouldn’t it be possible to change little things? Sometimes the smallest details make the difference