Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file path.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225(**************************************************************************)(* *)(* Copyright (C) Johannes Kanig, Stephane Lescuyer *)(* Jean-Christophe Filliatre, Romain Bardou and Francois Bobot *)(* *)(* This software is free software; you can redistribute it and/or *)(* modify it under the terms of the GNU Library General Public *)(* License version 2.1, with the special exception on linking *)(* described in file LICENSE. *)(* *)(* This software is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)(* *)(**************************************************************************)openMetaPathopenTypesincludeMetaPath.BaseDefslettransformtrp=mkPATransformedptrletstartx=of_metapath(startx)letappend?stylexy=of_metapath(append?style(of_pathx)(of_pathy))typet=Types.pathtypemetapath=Types.metapathletknotp?(l=defaultdir)?(r=defaultdir)p=Types.mkKnotlprletknot?l?r?scalep=knotp?l(S.p?scalep)?rletknotn?l?rp=knotp?l(S.ptp)?rletknotlist=List.map(fun(x,y,z)->Types.mkKnotxyz)letcycle_tmp?(dir=defaultdir)?(style=defaultjoint)p=mkPACycledirstylepletcycle=cycle_tmpletconcat?stylexy=of_metapath(concat?style(of_pathx)y)(* construct a path with a given style from a knot list *)letpathk?style?cyclel=letp=MetaPath.pathk?stylelinmatchcyclewith|None->of_metapathp|Somestyle->metacycledefaultdirstylepletpathp?style?cyclel=pathk?style?cycle(List.mapknotpl)letpathn?style?cyclel=pathp?style?cycle(List.mapPoint.ptl)letpath?style?cycle?scalel=letsc=S.ptlist?scaleinpathp?style?cycle(scl)(* construct a path with knot list and joint list *)letjointpathklplj=of_metapath(MetaPath.jointpathklplj)letjointpathplplj=jointpathk(List.mapknotplp)ljletjointpathnlplj=jointpathk(List.mapknotnlp)ljletjointpath?scalelplj=jointpathk(List.map(knot?scale)lp)ljletscalefp=mkPATransformedp[Transform.scaledf]letrotatefp=mkPATransformedp[Transform.rotatedf]letshiftptp=mkPATransformedp[Transform.shiftedpt]letyscalenp=mkPATransformedp[Transform.yscaledn]letxscalenp=mkPATransformedp[Transform.xscaledn]letpoint(f:float)p=letp=Compute.pathpinSpline_lib.abscissa_to_pointpfletdirection(f:float)p=letp=Compute.pathpinSpline_lib.direction_of_abscissapfletpointn=pointletdirectionn=directionletstripnp=letp0=point0.pinletp1=point(lengthp)pinletc=scalenfullcircleincut_after(shiftp1c)(cut_before(shiftp0c)p)(* directed paths *)typeorientation=|Up|Down|Left|Right|UpnofNum.t|DownnofNum.t|LeftnofNum.t|RightnofNum.tletdivise_dirl=letrecfctleft_downright_uplistn=function|[]->(left_down,right_up,listn)|((Leftn_|Rightn_|Downn_|Upn_)asx)::res->fctleft_downright_up(x::listn)res|((Left|Down)asx)::res->fct(x::left_down)right_uplistnres|((Right|Up)asx)::res->fctleft_down(x::right_up)listnresinfct[][][]lopenNumopenNum.InfixopenPointletdist_horizontaldirlistabsdistance=letleft,right,listn=divise_dirdirlistinletdiff=List.lengthright-List.lengthleftinletdistance=gmeandistancezeroinletd=List.fold_left(funax->matchxwith|Leftnn->a-/n|Rightnn->a+/n|_->failwith"impossible")distancelistninletdist,_=ifdiff=0then(bp10.,false)else(gmean(d/./floatdiff)zero,true)inletrecfctaccabs=function|[]->List.revacc|Left::res->letabs=abs-/distinfct(abs::acc)absres|Leftnn::res->letabs=abs-/ninfct(abs::acc)absres|Right::res->letabs=abs+/distinfct(abs::acc)absres|Rightnn::res->letabs=abs+/ninfct(abs::acc)absres|_->failwith"impossible"infct[]absdirlistletdist_verticaldirlistordodistance=letdown,up,listn=divise_dirdirlistinletdiff=List.lengthup-List.lengthdowninletd=List.fold_left(funax->matchxwith|Downnn->a-/n|Upnn->a+/n|_->failwith"impossible")distancelistninletdist,_=ifdiff=0then(bp10.,false)else(gmean(d/./floatdiff)zero,true)inletrecfctaccordo=function|[]->List.revacc|Down::res->letordo=ordo-/distinfct(ordo::acc)ordores|Downnn::res->letordo=ordo-/ninfct(ordo::acc)ordores|Up::res->letordo=ordo+/distinfct(ordo::acc)ordores|Upnn::res->letordo=ordo+/ninfct(ordo::acc)ordores|_->failwith"impossible"infct[]ordodirlistletsmart_path?styledirlistp1p2=letwidth=xpartp2-/xpartp1inletheight=ypartp2-/ypartp1inletdirhorizontal,dirvertical=List.partition(funx->matchxwithLeft|Right|Leftn_|Rightn_->true|_->false)dirlistinletlesdisth=dist_horizontaldirhorizontal(xpartp1)widthinletlesdistv=dist_verticaldirvertical(ypartp1)heightinletrecfctpcaccdirldvdh=match(dirl,dv,dh)with|(Up|Upn_|Down|Downn_)::dres,dv::dvres,dhlist->letps=pt(xpartpc,dv)infctps(ps::acc)dresdvresdhlist|(Left|Leftn_|Right|Rightn_)::dres,dvlist,dh::dhres->letps=pt(dh,ypartpc)infctps(ps::acc)dresdvlistdhres|[],_,_->List.rev(p2::acc)|_->assertfalseinletpoints=fctp1[p1]dirlistlesdistvlesdisthinpathp?stylepointsletdraw?brush?color?pen?dashedt=(* We don't use a default to avoid the output of
... withcolor (0.00red+0.00green+0.00blue) withpen ....
for each command in the output file *)mkCommand(mkCDrawt(mkBrushOptbrushcolorpendashed))letfill?colort=mkCommand(mkCFilltcolor)