/*****
* runpicture.in
*
* Runtime functions for picture operations.
*
*****/
pen => primPen()
pair => primPair()
path => primPath()
transform => primTransform()
realarray* => realArray()
realarray2* => realArray2()
patharray* => pathArray()
penarray* => penArray()
#include "path.h"
#include "arrayop.h"
#include "predicates.h"
using namespace camp;
using namespace vm;
typedef array realarray;
typedef array realarray2;
typedef array patharray;
using types::realArray;
using types::realArray2;
using types::pathArray;
Int windingnumber(array *p, camp::pair z)
{
size_t size=checkArray(p);
Int count=0;
for(size_t i=0; i < size; i++)
count += read<path *>(p,i)->windingnumber(z);
return count;
}
// Autogenerated routines:
path :nullPath()
{
return nullpath;
}
bool ==(path a, path b)
{
return a == b;
}
bool !=(path a, path b)
{
return !(a == b);
}
pair point(path p, Int t)
{
return p.point((Int) t);
}
pair point(path p, real t)
{
return p.point(t);
}
pair precontrol(path p, Int t)
{
return p.precontrol((Int) t);
}
pair precontrol(path p, real t)
{
return p.precontrol(t);
}
pair postcontrol(path p, Int t)
{
return p.postcontrol((Int) t);
}
pair postcontrol(path p, real t)
{
return p.postcontrol(t);
}
pair dir(path p, Int t, Int sign=0, bool normalize=true)
{
return p.dir(t,sign,normalize);
}
pair dir(path p, real t, bool normalize=true)
{
return p.dir(t,normalize);
}
pair accel(path p, Int t, Int sign=0)
{
return p.accel(t,sign);
}
pair accel(path p, real t)
{
return p.accel(t);
}
real radius(path p, real t)
{
pair v=p.dir(t,false);
pair a=p.accel(t);
real d=dot(a,v);
real v2=v.abs2();
real a2=a.abs2();
real denom=v2*a2-d*d;
real r=v2*sqrt(v2);
return denom > 0 ? r/sqrt(denom) : 0.0;
}
path reverse(path p)
{
return p.reverse();
}
path subpath(path p, Int a, Int b)
{
return p.subpath((Int) a, (Int) b);
}
path subpath(path p, real a, real b)
{
return p.subpath(a,b);
}
path nurb(pair z0, pair z1, pair z2, pair z3,
real w0, real w1, real w2, real w3, Int m)
{
return nurb(z0,z1,z2,z3,w0,w1,w2,w3,m);
}
Int length(path p)
{
return p.length();
}
bool cyclic(path p)
{
return p.cyclic();
}
bool straight(path p, Int t)
{
return p.straight(t);
}
path unstraighten(path p)
{
return p.unstraighten();
}
bool piecewisestraight(path p)
{
return p.piecewisestraight();
}
real arclength(path p)
{
return p.arclength();
}
real arctime(path p, real L)
{
return p.arctime(L);
}
real dirtime(path p, pair z)
{
return p.directiontime(z);
}
realarray* intersect(path p, path q, real fuzz=-1)
{
bool exact=fuzz <= 0.0;
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
::max(length(q.max()),length(q.min())));
std::vector<real> S,T;
real s,t;
if(intersections(s,t,S,T,p,q,fuzz,true,exact)) {
array *V=new array(2);
(*V)[0]=s;
(*V)[1]=t;
return V;
}
return new array(0);
}
realarray2* intersections(path p, path q, real fuzz=-1)
{
bool exact=fuzz <= 0.0;
if(fuzz < 0.0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
::max(length(q.max()),length(q.min())));
real s,t;
std::vector<real> S,T;
intersections(s,t,S,T,p,q,fuzz,false,true);
size_t n=S.size();
if(n == 0 && !exact) {
if(intersections(s,t,S,T,p,q,fuzz,true,false)) {
array *V=new array(1);
array *Vi=new array(2);
(*V)[0]=Vi;
(*Vi)[0]=s;
(*Vi)[1]=t;
return V;
}
}
array *V=new array(n);
for(size_t i=0; i < n; ++i) {
array *Vi=new array(2);
(*V)[i]=Vi;
(*Vi)[0]=S[i];
(*Vi)[1]=T[i];
}
stable_sort(V->begin(),V->end(),run::compare2<real>());
return V;
}
realarray* intersections(path p, explicit pair a, explicit pair b, real fuzz=-1)
{
if(fuzz < 0)
fuzz=BigFuzz*::max(::max(length(p.max()),length(p.min())),
::max(length(a),length(b)));
std::vector<real> S;
intersections(S,p,a,b,fuzz);
sort(S.begin(),S.end());
size_t n=S.size();
array *V=new array(n);
for(size_t i=0; i < n; ++i)
(*V)[i]=S[i];
return V;
}
// Return the intersection point of the extensions of the line segments
// PQ and pq.
pair extension(pair P, pair Q, pair p, pair q)
{
pair ac=P-Q;
pair bd=q-p;
real det=ac.getx()*bd.gety()-ac.gety()*bd.getx();
if(det == 0) return pair(infinity,infinity);
return P+((p.getx()-P.getx())*bd.gety()-(p.gety()-P.gety())*bd.getx())*ac/det;
}
Int size(path p)
{
return p.size();
}
path &(path p, path q)
{
return camp::concat(p,q);
}
pair min(path p)
{
return p.min();
}
pair max(path p)
{
return p.max();
}
Int size(patharray *p)
{
size_t size=checkArray(p);
Int count=0;
for (size_t i = 0; i < size; i++)
count += read<path *>(p,i)->size();
return count;
}
pair min(patharray *p)
{
size_t size=checkArray(p);
if(size == 0)
error(nopoints);
path *g = p->read<path *>(0);
pair z = g->min();
double minx = z.getx(), miny = z.gety();
for (size_t i = 1; i < size; ++i) {
path *g = p->read<path *>(i);
pair z = g->min();
double x = z.getx(), y = z.gety();
if (x < minx)
minx = x;
if (y < miny)
miny = y;
}
return pair(minx, miny);
}
pair max(patharray *p)
{
size_t size=checkArray(p);
if(size == 0)
error(nopoints);
path *g = p->read<path *>(0);
pair z = g->max();
double maxx = z.getx(), maxy = z.gety();
for (size_t i = 1; i < size; ++i) {
path *g = p->read<path *>(i);
pair z = g->max();
double x = z.getx(), y = z.gety();
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}
return pair(maxx, maxy);
}
pair minAfterTransform(transform t, patharray *p)
{
size_t size=checkArray(p);
if(size == 0)
error(nopoints);
path g = p->read<path *>(0)->transformed(t);
pair z = g.min();
double minx = z.getx(), miny = z.gety();
for (size_t i = 1; i < size; ++i) {
path g = p->read<path *>(i)->transformed(t);
pair z = g.min();
double x = z.getx(), y = z.gety();
if (x < minx)
minx = x;
if (y < miny)
miny = y;
}
return pair(minx, miny);
}
pair maxAfterTransform(transform t, patharray *p)
{
size_t size=checkArray(p);
if(size == 0)
error(nopoints);
path g = p->read<path *>(0)->transformed(t);
pair z = g.max();
double maxx = z.getx(), maxy = z.gety();
for (size_t i = 1; i < size; ++i) {
path g = p->read<path *>(i)->transformed(t);
pair z = g.max();
double x = z.getx(), y = z.gety();
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}
return pair(maxx, maxy);
}
realarray *mintimes(path p)
{
array *V=new array(2);
pair z=p.mintimes();
(*V)[0]=z.getx();
(*V)[1]=z.gety();
return V;
}
realarray *maxtimes(path p)
{
array *V=new array(2);
pair z=p.maxtimes();
(*V)[0]=z.getx();
(*V)[1]=z.gety();
return V;
}
real relativedistance(real theta, real phi, real t, bool atleast)
{
return camp::velocity(theta,phi,tension(t,atleast));
}
Int windingnumber(patharray *p, pair z)
{
return windingnumber(p,z);
}
bool inside(explicit patharray *g, pair z, pen fillrule=CURRENTPEN)
{
return fillrule.inside(windingnumber(g,z));
}
bool inside(path g, pair z, pen fillrule=CURRENTPEN)
{
return fillrule.inside(g.windingnumber(z));
}
// Determine the side of a--b that c lies on
// (negative=left, zero=on line, positive=right).
real side(pair a, pair b, pair c)
{
return orient2d(a,b,c);
}
// Determine the side of the counterclockwise circle through a,b,c that d
// lies on (negative=inside, 0=on circle, positive=right).
real incircle(pair a, pair b, pair c, pair d)
{
return incircle(a.getx(),a.gety(),b.getx(),b.gety(),c.getx(),c.gety(),
d.getx(),d.gety());
}