diff options
author | Karl Berry <karl@freefriends.org> | 2011-05-28 16:52:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-05-28 16:52:13 +0000 |
commit | dc8edc4b8f4c2f75e5785045925cd7cd6e7df871 (patch) | |
tree | 76149c373d7e59beeea52aef0793bf9189cb7b9b /Master | |
parent | c96567a73dfa159f9672fa2819ce0b3cd198d764 (diff) |
asymptote 2.10
git-svn-id: svn://tug.org/texlive/trunk@22643 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
61 files changed, 3503 insertions, 2161 deletions
diff --git a/Master/bin/i386-cygwin/asy.exe b/Master/bin/i386-cygwin/asy.exe Binary files differindex 01deb9e10d0..4671ff50309 100755 --- a/Master/bin/i386-cygwin/asy.exe +++ b/Master/bin/i386-cygwin/asy.exe diff --git a/Master/texmf/asymptote/GUI/xasyVersion.py b/Master/texmf/asymptote/GUI/xasyVersion.py index 105c268b68a..d90a53ca618 100755 --- a/Master/texmf/asymptote/GUI/xasyVersion.py +++ b/Master/texmf/asymptote/GUI/xasyVersion.py @@ -1,2 +1,2 @@ #!/usr/bin/env python -xasyVersion = "2.02" +xasyVersion = "2.10" diff --git a/Master/texmf/asymptote/asy-keywords.el b/Master/texmf/asymptote/asy-keywords.el deleted file mode 100644 index bce38beaa05..00000000000 --- a/Master/texmf/asymptote/asy-keywords.el +++ /dev/null @@ -1,17 +0,0 @@ -;; -;; This file is automatically generated by asy-list.pl. -;; Changes will be overwritten. -;; -(defvar asy-keywords-version "2.02") - -(defvar asy-keyword-name '( -and controls tension atleast curl if else while for do return break continue struct typedef new access import unravel from include quote static public private restricted this explicit true false null cycle newframe operator )) - -(defvar asy-type-name '( -Braid FitResult Label Legend Segment Solution TreeNode abscissa arc arrowhead binarytree binarytreeNode block bool bool3 bounds bqe circle conic coord coordsys cputime ellipse file filltype frame grid3 guide horner hsv hyperbola indexedTransform int inversion key light line linefit marginT marker mass object pair parabola path path3 pen picture point position projection real revolution scaleT scientific segment side slice solution splitface string surface tensionSpecifier ticklocate ticksgridT tickvalues transform transformation tree triangle trilinear triple vector vertex void )) - -(defvar asy-function-name '( -AND Arc ArcArrow ArcArrows Arrow Arrows Automatic AvantGarde BBox BWRainbow BWRainbow2 Bar Bars BeginArcArrow BeginArrow BeginBar BeginDotMargin BeginMargin BeginPenMargin Blank Bookman Bottom BottomTop Bounds Break Broken BrokenLog CLZ CTZ Ceil Circle CircleBarIntervalMarker Cos Courier CrossIntervalMarker DefaultFormat DefaultLogFormat Degrees Dir DotMargin DotMargins Dotted Draw Drawline Embed EndArcArrow EndArrow EndBar EndDotMargin EndMargin EndPenMargin Fill FillDraw Floor Format Full Gaussian Gaussrand Gaussrandpair Gradient Grayscale Helvetica Hermite HookHead InOutTicks InTicks Jn Label Landscape Left LeftRight LeftTicks Legend Linear Link Log LogFormat Margin Margins Mark MidArcArrow MidArrow NOT NewCenturySchoolBook NoBox NoMargin NoModifier NoTicks NoTicks3 NoZero NoZeroFormat None OR OmitFormat OmitTick OmitTickInterval OmitTickIntervals OutTicks Ox Oy Palatino PaletteTicks Pen PenMargin PenMargins Pentype Portrait RadialShade RadialShadeDraw Rainbow Range Relative Right RightTicks Rotate Round SQR Scale ScaleX ScaleY ScaleZ Seascape Segment Shift Sin Slant Spline StickIntervalMarker Straight Symbol Tan TeXify Ticks Ticks3 TildeIntervalMarker TimesRoman Top TrueMargin UnFill UpsideDown Wheel X XEquals XOR XY XYEquals XYZero XYgrid XZEquals XZZero XZero XZgrid Y YEquals YXgrid YZ YZEquals YZZero YZero YZgrid Yn Z ZX ZXgrid ZYgrid ZapfChancery ZapfDingbats _begingroup3 _cputime _draw _eval _image _labelpath _projection _strokepath _texpath aCos aSin aTan abort abs accel acos acosh acot acsc activatequote add addArrow addMargins addSaveFunction addnode addnodes addpenarc addpenline adjust alias align all altitude angabscissa angle angpoint animate annotate anticomplementary antipedal apply approximate arc arcarrowsize arccircle arcdir arcfromcenter arcfromfocus arclength arcnodesnumber arcpoint arcsubtended arcsubtendedcenter arctime arctopath array arrow arrow2 arrowbase arrowbasepoints arrowsize asec asin asinh ask assert asy asycode asydir asyfigure asyfilecode asyinclude asywrite atan atan2 atanh atbreakpoint atexit atime attach attract atupdate autoformat autoscale autoscale3 axes axes3 axialshade axis axiscoverage azimuth babel background bangles bar barmarksize barsize basealign baseline bbox beep begin beginclip begingroup beginpoint between bevel bezier bezierP bezierPP bezierPPP bezulate bibliography bibliographystyle binarytree binarytreeNode binomial binput bins bisector bisectorpoint bispline blend blockconnector boutput box bqe breakpoint breakpoints brick buildRestoreDefaults buildRestoreThunk buildcycle bulletcolor byte canonical canonicalcartesiansystem cartesiansystem case1 case2 case3 case4 cbrt cd ceil center centerToFocus centroid cevian change2 changecoordsys checkSegment checkconditionlength checker checkincreasing checklengths checkposition checktriangle choose circle circlebarframe circlemarkradius circlenodesnumber circumcenter circumcircle clamped clear clip clipdraw close cmyk code colatitude collect collinear color colorless colors colorspace comma compassmark complement complementary concat concurrent cone conic conicnodesnumber conictype conj connect connected connectedindex containmentTree contains contour contour3 contouredges controlSpecifier convert coordinates coordsys copy cos cosh cot countIntersections cputime crop cropcode cross crossframe crosshatch crossmarksize csc cubicroots curabscissa curlSpecifier curpoint currentarrow currentexitfunction currentmomarrow currentpolarconicroutine curve cut cutafter cutbefore cyclic cylinder deactivatequote debugger deconstruct defaultdir defaultformat defaultpen defined degenerate degrees delete deletepreamble determinant diagonal diamond diffdiv dir dirSpecifier dirtime display distance divisors do_overpaint dot dotframe dotsize downcase draw drawAll drawDoubleLine drawFermion drawGhost drawGluon drawMomArrow drawPRCcylinder drawPRCdisk drawPRCsphere drawPRCtube drawPhoton drawScalar drawVertex drawVertexBox drawVertexBoxO drawVertexBoxX drawVertexO drawVertexOX drawVertexTriangle drawVertexTriangleO drawVertexX drawarrow drawarrow2 drawline drawtick duplicate elle ellipse ellipsenodesnumber embed embed3 empty enclose end endScript endclip endgroup endgroup3 endl endpoint endpoints eof eol equation equations erase erasestep erf erfc error errorbar errorbars eval excenter excircle exit exitXasyMode exitfunction exp expfactors expi expm1 exradius extend extension extouch fabs factorial fermat fft fhorner figure file filecode fill filldraw filloutside fillrule filltype find finite finiteDifferenceJacobian firstcut firstframe fit fit2 fixedscaling floor flush fmdefaults fmod focusToCenter font fontcommand fontsize foot format frac frequency fromCenter fromFocus fspline functionshade gamma generate_random_backtrace generateticks gergonne getc getint getpair getreal getstring gettriple gluon gouraudshade graph graphic gray grestore grid grid3 gsave halfbox hatch hdiffdiv hermite hex histogram history hline hprojection hsv hyperbola hyperbolanodesnumber hyperlink hypot identity image incenter incentral incircle increasing incrementposition indexedTransform indexedfigure initXasyMode initdefaults input inradius insert inside integrate interactive interior interp interpolate intersect intersection intersectionpoint intersectionpoints intersections intouch inverse inversion invisible is3D isCCW isDuplicate isogonal isogonalconjugate isotomic isotomicconjugate isparabola italic item key kurtosis kurtosisexcess label labelaxis labelmargin labelpath labels labeltick labelx labelx3 labely labely3 labelz labelz3 lastcut latex latitude latticeshade layer layout ldexp leastsquares legend legenditem length lexorder lift light limits line linear linecap lineinversion linejoin linemargin lineskip linetype linewidth link list lm_enorm lm_evaluate_default lm_lmdif lm_lmpar lm_minimize lm_print_default lm_print_quiet lm_qrfac lm_qrsolv locale locate locatefile location log log10 log1p logaxiscoverage longitude lookup magnetize makeNode makedraw makepen map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markuniform mass masscenter massformat math max max3 maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minbezier minbound minipage minratio mintimes miterlimit momArrowPath momarrowsize monotonic multifigure nativeformat natural needshipout newl newpage newslide newton newtree nextframe nextnormal nextpage nib nodabscissa none norm normalvideo notaknot nowarn numberpage nurb object offset onpath opacity opposite orientation orig_circlenodesnumber orig_circlenodesnumber1 orig_draw orig_ellipsenodesnumber orig_ellipsenodesnumber1 orig_hyperbolanodesnumber orig_parabolanodesnumber origin orthic orthocentercenter outformat outline outname outprefix output overloadedMessage overwrite pack pad pairs palette parabola parabolanodesnumber parallel parallelogram partialsum path path3 pattern pause pdf pedal periodic perp perpendicular perpendicularmark phantom phi1 phi2 phi3 photon piecewisestraight point polar polarconicroutine polargraph polygon postcontrol postscript pow10 ppoint prc prc0 precision precontrol prepend print_random_addresses project projection purge pwhermite quadrant quadraticroots quantize quarticroots quotient radialshade radians radicalcenter radicalline radius rand randompath rd readline realmult realquarticroots rectangle rectangular rectify reflect relabscissa relative relativedistance reldir relpoint reltime remainder remark removeDuplicates rename replace report resetdefaultpen restore restoredefaults reverse reversevideo rf rfind rgb rgba rgbint rms rotate rotateO rotation round roundbox roundedpath roundrectangle same samecoordsys sameside sample save savedefaults saveline scale scale3 scaleO scaleT scaleless scientific search searchindex searchtree sec secondaryX secondaryY seconds section sector seek seekeof segment sequence setcontour setpens sgn sgnd sharpangle sharpdegrees shift shiftless shipout shipout3 show side simeq simpson sin single sinh size size3 skewness skip slant sleep slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys startScript startTrembling stdev step stickframe stickmarksize stickmarkspace stop straight straightness string stripdirectory stripextension stripfile stripsuffix strokepath subdivide subitem subpath substr sum surface symmedial symmedian system tab tableau tan tangent tangential tangents tanh tell tensionSpecifier tensorshade tex texcolor texify texpath texpreamble texreset texshipout texsize textpath thick thin tick tickMax tickMax3 tickMin tickMin3 ticklabelshift ticklocate tildeframe tildemarksize tile tiling time times title titlepage topbox transform transformation transpose tremble trembleFuzz tremble_circlenodesnumber tremble_circlenodesnumber1 tremble_draw tremble_ellipsenodesnumber tremble_ellipsenodesnumber1 tremble_hyperbolanodesnumber tremble_marknodes tremble_markuniform tremble_parabolanodesnumber triangle triangleAbc triangleabc triangulate tricoef tridiagonal trilinear trim trueMagnetize truepoint tube uncycle unfill uniform unique unit unitrand unitsize unityroot unstraighten upcase updatefunction uperiodic upscale uptodate usepackage usersetting usetypescript usleep value variance variancebiased vbox vector vectorfield verbatim view vline vperiodic vprojection warn warning windingnumber write xaxis xaxis3 xaxis3At xaxisAt xequals xinput xlimits xoutput xpart xscale xscaleO xtick xtick3 xtrans yaxis yaxis3 yaxis3At yaxisAt yequals ylimits ypart yscale yscaleO ytick ytick3 ytrans zaxis3 zaxis3At zero zero3 zlimits zpart ztick ztick3 ztrans )) - -(defvar asy-variable-name '( -AliceBlue Align Allow AntiqueWhite Apricot Aqua Aquamarine Aspect Azure BeginPoint Beige Bisque Bittersweet Black BlanchedAlmond Blue BlueGreen BlueViolet Both Break BrickRed Brown BurlyWood BurntOrange CCW CW CadetBlue CarnationPink Center Centered Cerulean Chartreuse Chocolate Coeff Coral CornflowerBlue Cornsilk Crimson Crop Cyan Dandelion DarkBlue DarkCyan DarkGoldenrod DarkGray DarkGreen DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkTurquoise DarkViolet DeepPink DeepSkyBlue DefaultHead DimGray DodgerBlue Dotted Down Draw E ENE EPS ESE E_Euler E_PC E_RK2 E_RK3BS Emerald EndPoint Euler Fill FillDraw FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite Gold Goldenrod Gray Green GreenYellow Honeydew HookHead Horizontal HotPink I IgnoreAspect IndianRed Indigo Ivory JOIN_IN JOIN_OUT JungleGreen Khaki LM_DWARF LM_MACHEP LM_SQRT_DWARF LM_SQRT_GIANT LM_USERTOL Label Lavender LavenderBlush LawnGreen Left LeftJustified LeftSide LemonChiffon LightBlue LightCoral LightCyan LightGoldenrodYellow LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSteelBlue LightYellow Lime LimeGreen Linear Linen Log Logarithmic Magenta Mahogany Mark MarkFill Maroon Max MediumAquamarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed Melon MidPoint MidnightBlue Min MintCream MistyRose Moccasin Move MoveQuiet Mulberry N NE NNE NNW NW NavajoWhite Navy NavyBlue NoAlign NoCrop NoFill NoSide OldLace Olive OliveDrab OliveGreen Orange OrangeRed Orchid Ox Oy PC PaleGoldenrod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip Peach PeachPuff Periwinkle Peru PineGreen Pink Plum PowderBlue ProcessBlue Purple RK2 RK3 RK3BS RK4 RK5 RK5DP RK5F RawSienna Red RedOrange RedViolet Rhodamine Right RightJustified RightSide RosyBrown RoyalBlue RoyalPurple RubineRed S SE SSE SSW SW SaddleBrown Salmon SandyBrown SeaGreen Seashell Sepia Sienna Silver SimpleHead SkyBlue SlateBlue SlateGray Snow SpringGreen SteelBlue Suppress SuppressQuiet Tan TeXHead Teal TealBlue Thistle Ticksize Tomato Turquoise UnFill Up VERSION Value Vertical Violet VioletRed W WNW WSW Wheat White WhiteSmoke WildStrawberry XYAlign YAlign Yellow YellowGreen YellowOrange addpenarc addpenline align allowstepping angularsystem animationdelay appendsuffix arcarrowangle arcarrowfactor arrow2sizelimit arrowangle arrowbarb arrowdir arrowfactor arrowhookfactor arrowlength arrowsizelimit arrowtexfactor authorpen axis axiscoverage axislabelfactor background backgroundcolor backgroundpen barfactor barmarksizefactor basealign baselinetemplate beveljoin bigvertexpen bigvertexsize black blue bm bottom bp brown bullet byfoci byvertices camerafactor chartreuse circlemarkradiusfactor circlenodesnumberfactor circleprecision circlescale cm codefile codepen codeskip colorPen coloredNodes coloredSegments conditionlength conicnodesfactor count cputimeformat crossmarksizefactor currentcoordsys currentlight currentpatterns currentpen currentpicture currentposition currentprojection curvilinearsystem cuttings cyan darkblue darkbrown darkcyan darkgray darkgreen darkgrey darkmagenta darkolive darkred dashdotted dashed datepen dateskip debuggerlines debugging deepblue deepcyan deepgray deepgreen deepgrey deepmagenta deepred default defaultControl defaultS defaultbackpen defaultcoordsys defaultexcursion defaultfilename defaultformat defaultmassformat defaultpen diagnostics differentlengths dot dotfactor dotframe dotted doublelinepen doublelinespacing down duplicateFuzz edge ellipsenodesnumberfactor eps epsgeo epsilon evenodd extendcap exterior fermionpen figureborder figuremattpen firstnode firststep foregroundcolor fuchsia fuzz gapfactor ghostpen gluonamplitude gluonpen gluonratio gray green grey hatchepsilon havepagenumber heavyblue heavycyan heavygray heavygreen heavygrey heavymagenta heavyred hline hwratio hyperbola hyperbolanodesnumberfactor identity4 ignore inXasyMode inch inches includegraphicscommand inf infinity institutionpen intMax intMin interior invert invisible itempen itemskip itemstep labelmargin landscape lastnode left legendhskip legendlinelength legendmargin legendmarkersize legendmaxrelativewidth legendvskip lightblue lightcyan lightgray lightgreen lightgrey lightmagenta lightolive lightred lightyellow line linemargin lm_infmsg lm_shortmsg longdashdotted longdashed magenta magneticPoints magneticRadius mantissaBits markangleradius markangleradiusfactor markanglespace markanglespacefactor mediumblue mediumcyan mediumgray mediumgreen mediumgrey mediummagenta mediumred mediumyellow middle minDistDefault minblockheight minblockwidth mincirclediameter minipagemargin minipagewidth minvertexangle miterjoin mm momarrowfactor momarrowlength momarrowmargin momarrowoffset momarrowpen monoPen morepoints nCircle newbulletcolor ngraph nil nmesh nobasealign nodeMarginDefault nodesystem nomarker nopoint noprimary nullpath nullpen numarray ocgindex oldbulletcolor olive orange origin overpaint page pageheight pagemargin pagenumberalign pagenumberpen pagenumberposition pagewidth paleblue palecyan palegray palegreen palegrey palemagenta palered paleyellow parabolanodesnumberfactor perpfactor phi photonamplitude photonpen photonratio pi pink plain plus preamblenodes pt purple r3 r4a r4b randMax realDigits realEpsilon realMax realMin red relativesystem reverse right roundcap roundjoin royalblue salmon saveFunctions scalarpen sequencereal settings shipped signedtrailingzero solid springgreen sqrtEpsilon squarecap squarepen startposition stdin stdout stepfactor stepfraction steppagenumberpen stepping stickframe stickmarksizefactor stickmarkspacefactor textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom tremblingMode undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize vline white wye xformStack yellow ylabelwidth zerotickfuzz zerowinding )) diff --git a/Master/texmf/asymptote/bsp.asy b/Master/texmf/asymptote/bsp.asy index a744da522cc..2a4d93daa81 100644 --- a/Master/texmf/asymptote/bsp.asy +++ b/Master/texmf/asymptote/bsp.asy @@ -201,7 +201,9 @@ void add(picture pic=currentpicture, face[] faces, for(int i=0; i < n; ++i) { picture F=Faces[i].pic; - pic.userBox(F.userMin,F.userMax); - pic.append(pic.bounds.point,pic.bounds.min,pic.bounds.max,F.T,F.bounds); + pic.userBox3(F.userMin3(), F.userMax3()); + pic.bounds.append(F.T, F.bounds); + // The above 2 lines should be replaced with a routine in picture which + // copies only sizing data from another picture. } } diff --git a/Master/texmf/asymptote/embed.asy b/Master/texmf/asymptote/embed.asy index dc6c7d4101a..165de0b7534 100644 --- a/Master/texmf/asymptote/embed.asy +++ b/Master/texmf/asymptote/embed.asy @@ -6,7 +6,9 @@ if(latex()) { \usepackage[3D,dvipdfmx]{movie15} \else% \usepackage[3D]{movie15} -\fi%"); +\fi% +\FPmessagesfalse% +"); } // See http://www.ctan.org/tex-archive/macros/latex/contrib/movie15/README diff --git a/Master/texmf/asymptote/flowchart.asy b/Master/texmf/asymptote/flowchart.asy index bb8fe21a4d6..3db66173755 100644 --- a/Master/texmf/asymptote/flowchart.asy +++ b/Master/texmf/asymptote/flowchart.asy @@ -424,20 +424,20 @@ blockconnector blockconnector(picture pic, transform t, pen p=currentpen, if(abs(b1.center.y-b2.center.y) < sqrtEpsilon) { // horizontally aligned b1.dirs[0]=b1.center.x < b2.center.x ? right : left; - blockconnector(pic,t)(b1,b2); + blockconnector(pic,t,p,margin)(b1,b2); } else if(abs(b1.center.x-b2.center.x) < sqrtEpsilon) { // vertically aligned b1.dirs[0]=b1.center.y < b2.center.y ? up : down; - blockconnector(pic,t)(b1,b2); + blockconnector(pic,t,p,margin)(b1,b2); } else { if(abs(b1.center.y-b2.center.y) < abs(b1.center.x-b2.center.x)) { b1.dirs[0]=b1.center.x < b2.center.x ? right : left; b1.dirs[1]=b1.center.y < b2.center.y ? up : down; - blockconnector(pic,t)(b1,b2); + blockconnector(pic,t,p,margin)(b1,b2); } else { b1.dirs[0]=b1.center.y < b2.center.y ? up : down; b1.dirs[1]=b1.center.x < b2.center.x ? right : left; - blockconnector(pic,t)(b1,b2); + blockconnector(pic,t,p,margin)(b1,b2); } } return b2; diff --git a/Master/texmf/asymptote/geometry.asy b/Master/texmf/asymptote/geometry.asy index 41a6397de64..61ff1ba8e8f 100644 --- a/Master/texmf/asymptote/geometry.asy +++ b/Master/texmf/asymptote/geometry.asy @@ -433,10 +433,6 @@ point point(explicit pair p, real m) op.init(currentcoordsys, p, m); return op; } -point point(explicit pair p, int m) -{// Handle ambiguity - return point(p,(real)m); -} /*<asyxml><function type="point" signature="point(coordsys,explicit point,real)"><code></asyxml>*/ point point(coordsys R, explicit point M, real m=M.m) @@ -1150,17 +1146,18 @@ private void Drawline(picture pic=currentpicture, Label L="",pair P, bool dirP=t Label legend="", marker marker=nomarker, pathModifier pathModifier=NoModifier) {/* Add the two parameters 'dirP' and 'dirQ' to the native routine - 'drawline' of the module 'maths'. + 'drawline' of the module 'math'. Segment [PQ] will be prolonged in direction of P if 'dirP=true', in direction of Q if 'dirQ=true'. If 'dirP=dirQ=true', the behavior is that of the native 'drawline'. Add all the other parameters of 'Draw'.*/ - pic.add(new void (frame f, transform t, transform, pair m, pair M) { + pic.add(new void (frame f, transform t, transform T, pair m, pair M) { picture opic; // Reduce the bounds by the size of the pen. m -= min(p)-(linemargin(),linemargin()); M -= max(p)+(linemargin(),linemargin()); // Calculate the points and direction vector in the transformed space. + t=t*T; pair z=t*P; pair q=t*Q; pair v=q-z; @@ -1175,16 +1172,16 @@ private void Drawline(picture pic=currentpicture, Label L="",pair P, bool dirP=t ptp=(z.x,z.y+cp*(m.y-z.y)); ptq=(z.x,q.y+cq*(M.y-q.y)); } else { - ptp=(z.x,q.y+cq*(m.y-q.y)); - ptq=(z.x,z.y+cp*(M.y-z.y)); + ptq=(z.x,q.y+cq*(m.y-q.y)); + ptp=(z.x,z.y+cp*(M.y-z.y)); } } else if(v.y == 0) { if (dot(v,m-z) < 0) { ptp=(z.x+cp*(m.x-z.x),z.y); ptq=(q.x+cq*(M.x-q.x),z.y); } else { - ptp=(q.x+cq*(m.x-q.x),z.y); - ptq=(z.x+cp*(M.x-z.x),z.y); + ptq=(q.x+cq*(m.x-q.x),z.y); + ptp=(z.x+cp*(M.x-z.x),z.y); } } else { // Calculate the maximum and minimum t values allowed for the @@ -1239,12 +1236,12 @@ void clipdraw(picture pic=currentpicture, Label L="", path g, label(tmp,L,g,p); add(pic,tmp); } - pic.add(new void (frame f, transform t, transform, pair m, pair M) { + pic.add(new void (frame f, transform t, transform T, pair m, pair M) { // Reduce the bounds by the size of the pen and the margins. m += min(p)+(xmargin,ymargin); M -= max(p)+(xmargin,ymargin); path bound=box(m,M); picture tmp; - draw(tmp,"",t*g,align,p,arrow,bar,NoMargin,legend,marker); + draw(tmp,"",t*T*g,align,p,arrow,bar,NoMargin,legend,marker); clip(tmp,bound); add(f,tmp.fit()); }); @@ -2963,13 +2960,6 @@ ellipse ellipse(point C, real a, real b, real angle=0) return oe; } -/*<asyxml><function type="ellipse" signature="ellipse(explicit pair,real,real)"><code></asyxml>*/ -ellipse ellipse(explicit pair C, real a, real b)= - new ellipse(explicit pair C, real a, real b) -{/*<asyxml></code><documentation>Overwrite the default routine.</documentation></function></asyxml>*/ - return ellipse((point)C,a,b,0); -}; - /*<asyxml><function type="ellipse" signature="ellipse(bqe)"><code></asyxml>*/ ellipse ellipse(bqe bqe) {/*<asyxml></code><documentation>Return the ellipse a[0]*x^2 + a[1]*xy + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0 @@ -3204,16 +3194,6 @@ circle circle(explicit point C, real r) if(!finite(r)) oc.l=line(C,C+vector(C.coordsys,(1,0))); return oc; } -circle circle(explicit point C, int r) -{ - return circle(C,(real) r); -} - -/*<asyxml><function type="circle" signature="circle(pair,real)"><code></asyxml>*/ -circle circle(pair c, real r)=new circle(pair c, real r) -{/*<asyxml></code><documentation>Overwrite 'circle(pair,real)'</documentation></function></asyxml>*/ - return circle(locate(c),r); -}; /*<asyxml><function type="circle" signature="circle(point,point)"><code></asyxml>*/ circle circle(point A, point B) @@ -3526,18 +3506,30 @@ path arcfromcenter(ellipse el, real angle1, real angle2, The angles are mesured relatively to the axis (C,x-axis) where C is the center of the ellipse.</documentation></function></asyxml>*/ if(degenerate(el)) abort("arcfromcenter: can not convert degenerated ellipse to path."); - guide op; - coordsys Rp=coordsys(el); - if (n < 1) return op; if (angle1 > angle2) return reverse(arcfromcenter(el,angle2,angle1,!direction,n)); + path op; + coordsys Rp=coordsys(el); + if (n < 1) return op; + interpolate join = operator ..; + real stretch = max(el.a/el.b, el.b/el.a); + if (stretch > 10) { + n *= floor(stretch/5); + join=operator --; + } real a1=direction ? radians(angle1) : radians(angle2); real a2=direction ? radians(angle2) : radians(angle1)+2*pi; real step=(a2-a1)/(n != 1 ? n-1 : 1); real a,r; real da=radians(el.angle); + real a3=angle((cos(a1)/el.a,sin(a1)/el.b)); + real a3=(a3>=0) ? a3 : a3+2pi; + real a4=angle((cos(a2)/el.a,sin(a2)/el.b)); + real a4=(a4>=0) ? a4 : a4+2pi; + real step=(a4-a3)/(n != 1 ? n-1 : 1); for (int i=0; i < n; ++i) { - a=a1+i*step; + a=a3+i*step; + a=angle((el.a*cos(a),el.b*sin(a))); r=el.b/sqrt(1-(el.e*cos(a))^2); op=op..Rp*Rp.polar(r,a+da); } @@ -3782,16 +3774,17 @@ void draw(picture pic=currentpicture, Label L="",parabola parabola, margin margin=NoMargin, Label legend="", marker marker=nomarker) {/*<asyxml></code><documentation>Draw the parabola 'p' on 'pic' without (if possible) altering the size of picture pic.</documentation></function></asyxml>*/ - pic.add(new void (frame f, transform t, transform, pair m, pair M) { + pic.add(new void (frame f, transform t, transform T, pair m, pair M) { // Reduce the bounds by the size of the pen and the margins. m -= min(p); M -= max(p); parabola.bmin=inverse(t)*m; parabola.bmax=inverse(t)*M; picture tmp; - draw(tmp,L,t*(path) parabola,align,p,arrow,bar,NoMargin,legend,marker); + draw(tmp,L,t*T*(path) parabola,align,p,arrow,bar,NoMargin,legend,marker); add(f,tmp.fit()); }); - if(pic.userMin.x != pic.userMax.x & pic.userMin.y != pic.userMax.y & - !finite(abs(pic.userMin)) & !finite(abs(pic.userMax))) + pair m=pic.userMin(); + pair M=pic.userMax(); + if(m != M) pic.addBox(truepoint(SW), truepoint(NE)); } @@ -3814,19 +3807,21 @@ void draw(picture pic=currentpicture, Label L="", hyperbola h, margin margin=NoMargin, Label legend="", marker marker=nomarker) {/*<asyxml></code><documentation>Draw the hyperbola 'h' on 'pic' without (if possible) altering the size of the picture pic.</documentation></function></asyxml>*/ - pic.add(new void (frame f, transform t, transform, pair m, pair M) { + pic.add(new void (frame f, transform t, transform T, pair m, pair M) { // Reduce the bounds by the size of the pen and the margins. m -= min(p); M -= max(p); h.bmin=inverse(t)*m; h.bmax=inverse(t)*M; picture tmp; - draw(tmp,L,t*(path) h,align,p,arrow,bar,NoMargin,legend,marker); + transform tT=t*T; + draw(tmp,L,tT*(path) h,align,p,arrow,bar,NoMargin,legend,marker); hyperbola ht=hyperbola(h.F2,h.F1,h.a); ht.bmin=inverse(t)*m; ht.bmax=inverse(t)*M; - draw(tmp,"",t*(path) ht,align,p,arrow,bar,NoMargin,marker); + draw(tmp,"",tT*(path) ht,align,p,arrow,bar,NoMargin,marker); add(f,tmp.fit()); }); - if(pic.userMin.x != pic.userMax.x & pic.userMin.y != pic.userMax.y & - !finite(abs(pic.userMin)) & !finite(abs(pic.userMax))) + pair m=pic.userMin(); + pair M=pic.userMax(); + if(m != M) pic.addBox(truepoint(SW), truepoint(NE)); } @@ -4158,10 +4153,6 @@ abscissa operator +(int x, explicit abscissa a) { return ((real)x)+a; } -abscissa operator +(explicit abscissa a, int x) -{ - return ((real)x)+a; -} /*<asyxml><operator type="abscissa" signature="-(explicit abscissa a)"><code></asyxml>*/ abscissa operator -(explicit abscissa a) @@ -4190,10 +4181,6 @@ abscissa operator -(int x, explicit abscissa a) { return ((real)x)-a; } -abscissa operator -(explicit abscissa a, int x) -{ - return a-((real)x); -} /*<asyxml><operator type="abscissa" signature="*(real,abscissa)"><code></asyxml>*/ abscissa operator *(real x, explicit abscissa a) @@ -4210,15 +4197,6 @@ abscissa operator *(explicit abscissa a, real x) return x*a; } -abscissa operator *(int x, explicit abscissa a) -{ - return ((real)x)*a; -} -abscissa operator *(explicit abscissa a, int x) -{ - return ((real)x)*a; -} - abscissa operator /(real x, explicit abscissa a) { abscissa oa; @@ -4238,10 +4216,6 @@ abscissa operator /(int x, explicit abscissa a) { return ((real)x)/a; } -abscissa operator /(explicit abscissa a, int x) -{ - return a/((real)x); -} /*<asyxml><function type="abscissa" signature="relabscissa(real)"><code></asyxml>*/ abscissa relabscissa(real x) @@ -4832,6 +4806,10 @@ struct arc { /*<asyxml><method type="void" signature="setangles(real,real,real)"><code></asyxml>*/ void setangles(real a0, real a1, real a2) {/*<asyxml></code><documentation>Set the angles.</documentation></method></asyxml>*/ + if (a1 < 0 && a2 < 0) { + a1 += 360; + a2 += 360; + } this.angle0=a0%(sgnd(a0)*360); this.angle1=a1%(sgnd(a1)*360); this.angle2=a2%(sgnd(2)*360); diff --git a/Master/texmf/asymptote/graph.asy b/Master/texmf/asymptote/graph.asy index 9ac9983ddef..a7ffabc6220 100644 --- a/Master/texmf/asymptote/graph.asy +++ b/Master/texmf/asymptote/graph.asy @@ -1203,17 +1203,17 @@ void xaxisAt(picture pic=currentpicture, Label L="", axis axis, void bounds() { if(type == Min) - y=pic.scale.y.automin() ? tickMin(pic).y : pic.userMin.y; + y=pic.scale.y.automin() ? tickMin(pic).y : pic.userMin().y; else if(type == Max) - y=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax.y; + y=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax().y; else if(type == Both) { - y2=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax.y; + y2=pic.scale.y.automax() ? tickMax(pic).y : pic.userMax().y; y=opposite ? y2 : - (pic.scale.y.automin() ? tickMin(pic).y : pic.userMin.y); + (pic.scale.y.automin() ? tickMin(pic).y : pic.userMin().y); } - real Xmin=finite(xmin) ? xmin : pic.userMin.x; - real Xmax=finite(xmax) ? xmax : pic.userMax.x; + real Xmin=finite(xmin) ? xmin : pic.userMin().x; + real Xmax=finite(xmax) ? xmax : pic.userMax().x; pair a=(Xmin,y); pair b=(Xmax,y); @@ -1297,17 +1297,17 @@ void yaxisAt(picture pic=currentpicture, Label L="", axis axis, void bounds() { if(type == Min) - x=pic.scale.x.automin() ? tickMin(pic).x : pic.userMin.x; + x=pic.scale.x.automin() ? tickMin(pic).x : pic.userMin().x; else if(type == Max) - x=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax.x; + x=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax().x; else if(type == Both) { - x2=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax.x; + x2=pic.scale.x.automax() ? tickMax(pic).x : pic.userMax().x; x=opposite ? x2 : - (pic.scale.x.automin() ? tickMin(pic).x : pic.userMin.x); + (pic.scale.x.automin() ? tickMin(pic).x : pic.userMin().x); } - real Ymin=finite(ymin) ? ymin : pic.userMin.y; - real Ymax=finite(ymax) ? ymax : pic.userMax.y; + real Ymin=finite(ymin) ? ymin : pic.userMin().y; + real Ymax=finite(ymax) ? ymax : pic.userMax().y; pair a=(x,Ymin); pair b=(x,Ymax); @@ -1363,21 +1363,22 @@ void xlimits(picture pic=currentpicture, real min=-infinity, real max=infinity, bounds mx; if(pic.scale.x.automin() || pic.scale.x.automax()) - mx=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale); + mx=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale); if(pic.scale.x.automin) { if(pic.scale.x.automin()) pic.userMinx(mx.min); - } else pic.userMinx(pic.scale.x.T(min)); + } else pic.userMinx(min(pic.scale.x.T(min),pic.scale.x.T(max))); if(pic.scale.x.automax) { if(pic.scale.x.automax()) pic.userMaxx(mx.max); - } else pic.userMaxx(pic.scale.x.T(max)); + } else pic.userMaxx(max(pic.scale.x.T(min),pic.scale.x.T(max))); if(crop) { pair userMin=pic.userMin(); pair userMax=pic.userMax(); pic.bounds.xclip(userMin.x,userMax.x); - pic.clip(new void (frame f, transform t, transform T, pair, pair) { + pic.clip(userMin, userMax, + new void (frame f, transform t, transform T, pair, pair) { frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f; clip(f,T*box(((t*userMin).x,(min(Tinvf)).y), ((t*userMax).x,(max(Tinvf)).y))); @@ -1396,21 +1397,22 @@ void ylimits(picture pic=currentpicture, real min=-infinity, real max=infinity, bounds my; if(pic.scale.y.automin() || pic.scale.y.automax()) - my=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale); + my=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale); if(pic.scale.y.automin) { if(pic.scale.y.automin()) pic.userMiny(my.min); - } else pic.userMiny(pic.scale.y.T(min)); + } else pic.userMiny(min(pic.scale.y.T(min),pic.scale.y.T(max))); if(pic.scale.y.automax) { if(pic.scale.y.automax()) pic.userMaxy(my.max); - } else pic.userMaxy(pic.scale.y.T(max)); + } else pic.userMaxy(max(pic.scale.y.T(min),pic.scale.y.T(max))); if(crop) { pair userMin=pic.userMin(); pair userMax=pic.userMax(); pic.bounds.yclip(userMin.y,userMax.y); - pic.clip(new void (frame f, transform t, transform T, pair, pair) { + pic.clip(userMin, userMax, + new void (frame f, transform t, transform T, pair, pair) { frame Tinvf=T == identity() ? f : t*inverse(T)*inverse(t)*f; clip(f,T*box(((min(Tinvf)).x,(t*userMin).y), ((max(Tinvf)).x,(t*userMax).y))); @@ -1423,7 +1425,7 @@ void crop(picture pic=currentpicture) { xlimits(pic,false); ylimits(pic,false); - if(pic.userSetx && pic.userSety) + if(pic.userSetx() && pic.userSety()) clip(pic,box(pic.userMin(),pic.userMax())); } @@ -1432,7 +1434,7 @@ void limits(picture pic=currentpicture, pair min, pair max, bool crop=NoCrop) { xlimits(pic,min.x,max.x); ylimits(pic,min.y,max.y); - if(crop && pic.userSetx && pic.userSety) + if(crop && pic.userSetx() && pic.userSety()) clip(pic,box(pic.userMin(),pic.userMax())); } @@ -1443,25 +1445,25 @@ void autoscale(picture pic=currentpicture, axis axis) bounds mx,my; pic.scale.set=true; - if(pic.userSetx) { - mx=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale); + if(pic.userSetx()) { + mx=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale); if(pic.scale.x.scale.logarithmic && - floor(pic.userMin.x) == floor(pic.userMax.x)) { + floor(pic.userMin().x) == floor(pic.userMax().x)) { if(pic.scale.x.automin()) - pic.userMinx(floor(pic.userMin.x)); + pic.userMinx(floor(pic.userMin().x)); if(pic.scale.x.automax()) - pic.userMaxx(ceil(pic.userMax.x)); + pic.userMaxx(ceil(pic.userMax().x)); } } else {mx.min=mx.max=0; pic.scale.set=false;} - if(pic.userSety) { - my=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale); + if(pic.userSety()) { + my=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale); if(pic.scale.y.scale.logarithmic && - floor(pic.userMin.y) == floor(pic.userMax.y)) { + floor(pic.userMin().y) == floor(pic.userMax().y)) { if(pic.scale.y.automin()) - pic.userMiny(floor(pic.userMin.y)); + pic.userMiny(floor(pic.userMin().y)); if(pic.scale.y.automax()) - pic.userMaxy(ceil(pic.userMax.y)); + pic.userMaxy(ceil(pic.userMax().y)); } } else {my.min=my.max=0; pic.scale.set=false;} @@ -1503,9 +1505,9 @@ void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero, newticks=true; } - if(newticks && pic.userSetx && ticks != NoTicks) { - if(xmin == -infinity) xmin=pic.userMin.x; - if(xmax == infinity) xmax=pic.userMax.x; + if(newticks && pic.userSetx() && ticks != NoTicks) { + if(xmin == -infinity) xmin=pic.userMin().x; + if(xmax == infinity) xmax=pic.userMax().x; bounds mx=autoscale(xmin,xmax,pic.scale.x.scale); pic.scale.x.tickMin=mx.min; pic.scale.x.tickMax=mx.max; @@ -1517,15 +1519,15 @@ void xaxis(picture pic=currentpicture, Label L="", axis axis=YZero, if(xmin == -infinity && !axis.extend) { if(pic.scale.set) xmin=pic.scale.x.automin() ? pic.scale.x.tickMin : - max(pic.scale.x.tickMin,pic.userMin.x); - else xmin=pic.userMin.x; + max(pic.scale.x.tickMin,pic.userMin().x); + else xmin=pic.userMin().x; } if(xmax == infinity && !axis.extend) { if(pic.scale.set) xmax=pic.scale.x.automax() ? pic.scale.x.tickMax : - min(pic.scale.x.tickMax,pic.userMax.x); - else xmax=pic.userMax.x; + min(pic.scale.x.tickMax,pic.userMax().x); + else xmax=pic.userMax().x; } if(L.defaultposition) L.position(axis.position); @@ -1565,9 +1567,9 @@ void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero, newticks=true; } - if(newticks && pic.userSety && ticks != NoTicks) { - if(ymin == -infinity) ymin=pic.userMin.y; - if(ymax == infinity) ymax=pic.userMax.y; + if(newticks && pic.userSety() && ticks != NoTicks) { + if(ymin == -infinity) ymin=pic.userMin().y; + if(ymax == infinity) ymax=pic.userMax().y; bounds my=autoscale(ymin,ymax,pic.scale.y.scale); pic.scale.y.tickMin=my.min; pic.scale.y.tickMax=my.max; @@ -1579,16 +1581,16 @@ void yaxis(picture pic=currentpicture, Label L="", axis axis=XZero, if(ymin == -infinity && !axis.extend) { if(pic.scale.set) ymin=pic.scale.y.automin() ? pic.scale.y.tickMin : - max(pic.scale.y.tickMin,pic.userMin.y); - else ymin=pic.userMin.y; + max(pic.scale.y.tickMin,pic.userMin().y); + else ymin=pic.userMin().y; } if(ymax == infinity && !axis.extend) { if(pic.scale.set) ymax=pic.scale.y.automax() ? pic.scale.y.tickMax : - min(pic.scale.y.tickMax,pic.userMax.y); - else ymax=pic.userMax.y; + min(pic.scale.y.tickMax,pic.userMax().y); + else ymax=pic.userMax().y; } if(L.defaultposition) L.position(axis.position); @@ -1784,23 +1786,23 @@ picture secondaryX(picture primary=currentpicture, void f(picture)) { if(!primary.scale.set) abort(noprimary); picture pic; - if(primary.userMax.x == primary.userMin.x) return pic; + if(primary.userMax().x == primary.userMin().x) return pic; f(pic); - if(!pic.userSetx) return pic; - bounds a=autoscale(pic.userMin.x,pic.userMax.x,pic.scale.x.scale); - real bmin=pic.scale.x.automin() ? a.min : pic.userMin.x; - real bmax=pic.scale.x.automax() ? a.max : pic.userMax.x; + if(!pic.userSetx()) return pic; + bounds a=autoscale(pic.userMin().x,pic.userMax().x,pic.scale.x.scale); + real bmin=pic.scale.x.automin() ? a.min : pic.userMin().x; + real bmax=pic.scale.x.automax() ? a.max : pic.userMax().x; real denom=bmax-bmin; if(denom != 0) { pic.erase(); - real m=(primary.userMax.x-primary.userMin.x)/denom; - pic.scale.x.postscale=Linear(m,bmin-primary.userMin.x/m); + real m=(primary.userMax().x-primary.userMin().x)/denom; + pic.scale.x.postscale=Linear(m,bmin-primary.userMin().x/m); pic.scale.set=true; pic.scale.x.tickMin=pic.scale.x.postscale.T(a.min); pic.scale.x.tickMax=pic.scale.x.postscale.T(a.max); - pic.scale.y.tickMin=primary.userMin.y; - pic.scale.y.tickMax=primary.userMax.y; + pic.scale.y.tickMin=primary.userMin().y; + pic.scale.y.tickMax=primary.userMax().y; axis.xdivisor=a.divisor; f(pic); } @@ -1813,21 +1815,21 @@ picture secondaryY(picture primary=currentpicture, void f(picture)) { if(!primary.scale.set) abort(noprimary); picture pic; - if(primary.userMax.y == primary.userMin.y) return pic; + if(primary.userMax().y == primary.userMin().y) return pic; f(pic); - if(!pic.userSety) return pic; - bounds a=autoscale(pic.userMin.y,pic.userMax.y,pic.scale.y.scale); - real bmin=pic.scale.y.automin() ? a.min : pic.userMin.y; - real bmax=pic.scale.y.automax() ? a.max : pic.userMax.y; + if(!pic.userSety()) return pic; + bounds a=autoscale(pic.userMin().y,pic.userMax().y,pic.scale.y.scale); + real bmin=pic.scale.y.automin() ? a.min : pic.userMin().y; + real bmax=pic.scale.y.automax() ? a.max : pic.userMax().y; real denom=bmax-bmin; if(denom != 0) { pic.erase(); - real m=(primary.userMax.y-primary.userMin.y)/denom; - pic.scale.y.postscale=Linear(m,bmin-primary.userMin.y/m); + real m=(primary.userMax().y-primary.userMin().y)/denom; + pic.scale.y.postscale=Linear(m,bmin-primary.userMin().y/m); pic.scale.set=true; - pic.scale.x.tickMin=primary.userMin.x; - pic.scale.x.tickMax=primary.userMax.x; + pic.scale.x.tickMin=primary.userMin().x; + pic.scale.x.tickMax=primary.userMax().x; pic.scale.y.tickMin=pic.scale.y.postscale.T(a.min); pic.scale.y.tickMax=pic.scale.y.postscale.T(a.max); axis.ydivisor=a.divisor; diff --git a/Master/texmf/asymptote/graph3.asy b/Master/texmf/asymptote/graph3.asy index e588c8aa4d6..391b72ca87a 100644 --- a/Master/texmf/asymptote/graph3.asy +++ b/Master/texmf/asymptote/graph3.asy @@ -363,14 +363,14 @@ InOutTicks=InOutTicks(); triple tickMin3(picture pic) { - return minbound(pic.userMin,(pic.scale.x.tickMin,pic.scale.y.tickMin, - pic.scale.z.tickMin)); + return minbound(pic.userMin(),(pic.scale.x.tickMin,pic.scale.y.tickMin, + pic.scale.z.tickMin)); } triple tickMax3(picture pic) { - return maxbound(pic.userMax,(pic.scale.x.tickMax,pic.scale.y.tickMax, - pic.scale.z.tickMax)); + return maxbound(pic.userMax(),(pic.scale.x.tickMax,pic.scale.y.tickMax, + pic.scale.z.tickMax)); } axis Bounds(int type=Both, int type2=Both, triple align=O, bool extend=false) @@ -570,27 +570,27 @@ void xaxis3At(picture pic=currentpicture, Label L="", axis axis, void bounds() { if(type == Min) - y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y; + y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y; else if(type == Max) - y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y; + y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; else if(type == Both) { - y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y; + y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; y=opposite ? y2 : - (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y); + (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y); } if(type2 == Min) - z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z; + z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z; else if(type2 == Max) - z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z; + z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; else if(type2 == Both) { - z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z; + z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; z=opposite2 ? z2 : - (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z); + (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z); } - real Xmin=finite(xmin) ? xmin : pic.userMin.x; - real Xmax=finite(xmax) ? xmax : pic.userMax.x; + real Xmin=finite(xmin) ? xmin : pic.userMin().x; + real Xmax=finite(xmax) ? xmax : pic.userMax().x; triple a=(Xmin,y,z); triple b=(Xmax,y,z); @@ -692,27 +692,27 @@ void yaxis3At(picture pic=currentpicture, Label L="", axis axis, void bounds() { if(type == Min) - x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x; + x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x; else if(type == Max) - x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x; + x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; else if(type == Both) { - x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x; + x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; x=opposite ? x2 : - (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x); + (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x); } if(type2 == Min) - z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z; + z=pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z; else if(type2 == Max) - z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z; + z=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; else if(type2 == Both) { - z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax.z; + z2=pic.scale.z.automax() ? tickMax3(pic).z : pic.userMax().z; z=opposite2 ? z2 : - (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin.z); + (pic.scale.z.automin() ? tickMin3(pic).z : pic.userMin().z); } - real Ymin=finite(ymin) ? ymin : pic.userMin.y; - real Ymax=finite(ymax) ? ymax : pic.userMax.y; + real Ymin=finite(ymin) ? ymin : pic.userMin().y; + real Ymax=finite(ymax) ? ymax : pic.userMax().y; triple a=(x,Ymin,z); triple b=(x,Ymax,z); @@ -814,27 +814,27 @@ void zaxis3At(picture pic=currentpicture, Label L="", axis axis, void bounds() { if(type == Min) - x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x; + x=pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x; else if(type == Max) - x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x; + x=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; else if(type == Both) { - x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax.x; + x2=pic.scale.x.automax() ? tickMax3(pic).x : pic.userMax().x; x=opposite ? x2 : - (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin.x); + (pic.scale.x.automin() ? tickMin3(pic).x : pic.userMin().x); } if(type2 == Min) - y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y; + y=pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y; else if(type2 == Max) - y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y; + y=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; else if(type2 == Both) { - y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax.y; + y2=pic.scale.y.automax() ? tickMax3(pic).y : pic.userMax().y; y=opposite2 ? y2 : - (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin.y); + (pic.scale.y.automin() ? tickMin3(pic).y : pic.userMin().y); } - real Zmin=finite(zmin) ? zmin : pic.userMin.z; - real Zmax=finite(zmax) ? zmax : pic.userMax.z; + real Zmin=finite(zmin) ? zmin : pic.userMin().z; + real Zmax=finite(zmax) ? zmax : pic.userMax().z; triple a=(x,y,Zmin); triple b=(x,y,Zmax); @@ -893,14 +893,14 @@ void autoscale3(picture pic=currentpicture, axis axis) if(!set) { bounds mz; - if(pic.userSetz) { - mz=autoscale(pic.userMin.z,pic.userMax.z,pic.scale.z.scale); + if(pic.userSetz()) { + mz=autoscale(pic.userMin().z,pic.userMax().z,pic.scale.z.scale); if(pic.scale.z.scale.logarithmic && - floor(pic.userMin.z) == floor(pic.userMax.z)) { + floor(pic.userMin().z) == floor(pic.userMax().z)) { if(pic.scale.z.automin()) - pic.userMinz(floor(pic.userMin.z)); + pic.userMinz(floor(pic.userMin().z)); if(pic.scale.z.automax()) - pic.userMaxz(ceil(pic.userMax.z)); + pic.userMaxz(ceil(pic.userMax().z)); } } else {mz.min=mz.max=0; pic.scale.set=false;} @@ -938,9 +938,9 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, newticks=true; } - if(newticks && pic.userSetx && ticks != NoTicks3) { - if(xmin == -infinity) xmin=pic.userMin.x; - if(xmax == infinity) xmax=pic.userMax.x; + if(newticks && pic.userSetx() && ticks != NoTicks3) { + if(xmin == -infinity) xmin=pic.userMin().x; + if(xmax == infinity) xmax=pic.userMax().x; bounds mx=autoscale(xmin,xmax,pic.scale.x.scale); pic.scale.x.tickMin=mx.min; pic.scale.x.tickMax=mx.max; @@ -952,15 +952,15 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, if(xmin == -infinity && !axis.extend) { if(pic.scale.set) xmin=pic.scale.x.automin() ? pic.scale.x.tickMin : - max(pic.scale.x.tickMin,pic.userMin.x); - else xmin=pic.userMin.x; + max(pic.scale.x.tickMin,pic.userMin().x); + else xmin=pic.userMin().x; } if(xmax == infinity && !axis.extend) { if(pic.scale.set) xmax=pic.scale.x.automax() ? pic.scale.x.tickMax : - min(pic.scale.x.tickMax,pic.userMax.x); - else xmax=pic.userMax.x; + min(pic.scale.x.tickMax,pic.userMax().x); + else xmax=pic.userMax().x; } if(L.defaultposition) { @@ -971,7 +971,7 @@ void xaxis3(picture pic=currentpicture, Label L="", axis axis=YZZero, bool back=false; if(axis.type == Both) { triple v=currentprojection.normal; - back=dot((0,pic.userMax.y-pic.userMin.y,0),v)*sgn(v.z) > 0; + back=dot((0,pic.userMax().y-pic.userMin().y,0),v)*sgn(v.z) > 0; } xaxis3At(pic,L,axis,xmin,xmax,p,ticks,arrow,margin,above,false,false,!back); @@ -1012,9 +1012,9 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, newticks=true; } - if(newticks && pic.userSety && ticks != NoTicks3) { - if(ymin == -infinity) ymin=pic.userMin.y; - if(ymax == infinity) ymax=pic.userMax.y; + if(newticks && pic.userSety() && ticks != NoTicks3) { + if(ymin == -infinity) ymin=pic.userMin().y; + if(ymax == infinity) ymax=pic.userMax().y; bounds my=autoscale(ymin,ymax,pic.scale.y.scale); pic.scale.y.tickMin=my.min; pic.scale.y.tickMax=my.max; @@ -1026,16 +1026,16 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, if(ymin == -infinity && !axis.extend) { if(pic.scale.set) ymin=pic.scale.y.automin() ? pic.scale.y.tickMin : - max(pic.scale.y.tickMin,pic.userMin.y); - else ymin=pic.userMin.y; + max(pic.scale.y.tickMin,pic.userMin().y); + else ymin=pic.userMin().y; } if(ymax == infinity && !axis.extend) { if(pic.scale.set) ymax=pic.scale.y.automax() ? pic.scale.y.tickMax : - min(pic.scale.y.tickMax,pic.userMax.y); - else ymax=pic.userMax.y; + min(pic.scale.y.tickMax,pic.userMax().y); + else ymax=pic.userMax().y; } if(L.defaultposition) { @@ -1046,7 +1046,7 @@ void yaxis3(picture pic=currentpicture, Label L="", axis axis=XZZero, bool back=false; if(axis.type == Both) { triple v=currentprojection.normal; - back=dot((pic.userMax.x-pic.userMin.x,0,0),v)*sgn(v.z) > 0; + back=dot((pic.userMax().x-pic.userMin().x,0,0),v)*sgn(v.z) > 0; } yaxis3At(pic,L,axis,ymin,ymax,p,ticks,arrow,margin,above,false,false,!back); @@ -1087,9 +1087,9 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, newticks=true; } - if(newticks && pic.userSetz && ticks != NoTicks3) { - if(zmin == -infinity) zmin=pic.userMin.z; - if(zmax == infinity) zmax=pic.userMax.z; + if(newticks && pic.userSetz() && ticks != NoTicks3) { + if(zmin == -infinity) zmin=pic.userMin().z; + if(zmax == infinity) zmax=pic.userMax().z; bounds mz=autoscale(zmin,zmax,pic.scale.z.scale); pic.scale.z.tickMin=mz.min; pic.scale.z.tickMax=mz.max; @@ -1101,15 +1101,15 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, if(zmin == -infinity && !axis.extend) { if(pic.scale.set) zmin=pic.scale.z.automin() ? pic.scale.z.tickMin : - max(pic.scale.z.tickMin,pic.userMin.z); - else zmin=pic.userMin.z; + max(pic.scale.z.tickMin,pic.userMin().z); + else zmin=pic.userMin().z; } if(zmax == infinity && !axis.extend) { if(pic.scale.set) zmax=pic.scale.z.automax() ? pic.scale.z.tickMax : - min(pic.scale.z.tickMax,pic.userMax.z); - else zmax=pic.userMax.z; + min(pic.scale.z.tickMax,pic.userMax().z); + else zmax=pic.userMax().z; } if(L.defaultposition) { @@ -1120,7 +1120,7 @@ void zaxis3(picture pic=currentpicture, Label L="", axis axis=XYZero, bool back=false; if(axis.type == Both) { triple v=currentprojection.vector(); - back=dot((pic.userMax.x-pic.userMin.x,0,0),v)*sgn(v.y) > 0; + back=dot((pic.userMax().x-pic.userMin().x,0,0),v)*sgn(v.y) > 0; } zaxis3At(pic,L,axis,zmin,zmax,p,ticks,arrow,margin,above,false,false,!back); @@ -1144,15 +1144,15 @@ void zlimits(picture pic=currentpicture, real min=-infinity, real max=infinity, bounds mz; if(pic.scale.z.automin() || pic.scale.z.automax()) - mz=autoscale(pic.userMin.z,pic.userMax.z,pic.scale.z.scale); + mz=autoscale(pic.userMin().z,pic.userMax().z,pic.scale.z.scale); if(pic.scale.z.automin) { if(pic.scale.z.automin()) pic.userMinz(mz.min); - } else pic.userMinz(pic.scale.z.T(min)); + } else pic.userMinz(min(pic.scale.z.T(min),pic.scale.z.T(max))); if(pic.scale.z.automax) { if(pic.scale.z.automax()) pic.userMaxz(mz.max); - } else pic.userMaxz(pic.scale.z.T(max)); + } else pic.userMaxz(max(pic.scale.z.T(min),pic.scale.z.T(max))); } // Restrict the x, y, and z limits to box(min,max). diff --git a/Master/texmf/asymptote/grid3.asy b/Master/texmf/asymptote/grid3.asy index afd621eb741..98e043a71d7 100644 --- a/Master/texmf/asymptote/grid3.asy +++ b/Master/texmf/asymptote/grid3.asy @@ -33,18 +33,20 @@ struct grid3 { typedef grid3 grid3routine(picture pic); -triple X(picture pic) {return (pic.userMax.x,pic.userMin.y,pic.userMin.z);} -triple XY(picture pic) {return (pic.userMax.x,pic.userMax.y,pic.userMin.z);} -triple Y(picture pic) {return (pic.userMin.x,pic.userMax.y,pic.userMin.z);} -triple YZ(picture pic) {return (pic.userMin.x,pic.userMax.y,pic.userMax.z);} -triple Z(picture pic) {return (pic.userMin.x,pic.userMin.y,pic.userMax.z);} -triple ZX(picture pic) {return (pic.userMax.x,pic.userMin.y,pic.userMax.z);} +triple X(picture pic) {return (pic.userMax().x,pic.userMin().y,pic.userMin().z);} +triple XY(picture pic) {return (pic.userMax().x,pic.userMax().y,pic.userMin().z);} +triple Y(picture pic) {return (pic.userMin().x,pic.userMax().y,pic.userMin().z);} +triple YZ(picture pic) {return (pic.userMin().x,pic.userMax().y,pic.userMax().z);} +triple Z(picture pic) {return (pic.userMin().x,pic.userMin().y,pic.userMax().z);} +triple ZX(picture pic) {return (pic.userMax().x,pic.userMin().y,pic.userMax().z);} grid3routine XYgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--X(pic),Y(pic)--XY(pic),pic.userMin--Z(pic), - pic.userMin.x,pic.userMax.x,pos,pic.scale.x); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--X(pic),Y(pic)--XY(pic),m--Z(pic), + m.x,M.x,pos,pic.scale.x); return og; }; }; @@ -53,8 +55,10 @@ grid3routine XYgrid=XYgrid(); grid3routine YXgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--Y(pic),X(pic)--XY(pic),pic.userMin--Z(pic), - pic.userMin.y,pic.userMax.y,pos,pic.scale.y); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--Y(pic),X(pic)--XY(pic),m--Z(pic), + m.y,M.y,pos,pic.scale.y); return og; }; }; @@ -64,8 +68,10 @@ grid3routine YXgrid=YXgrid(); grid3routine XZgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--X(pic),Z(pic)--ZX(pic),pic.userMin--Y(pic), - pic.userMin.x,pic.userMax.x,pos,pic.scale.x); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--X(pic),Z(pic)--ZX(pic),m--Y(pic), + m.x,M.x,pos,pic.scale.x); return og; }; }; @@ -74,8 +80,10 @@ grid3routine XZgrid=XZgrid(); grid3routine ZXgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--Z(pic),X(pic)--ZX(pic),pic.userMin--Y(pic), - pic.userMin.z,pic.userMax.z,pos,pic.scale.z); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--Z(pic),X(pic)--ZX(pic),m--Y(pic), + m.z,M.z,pos,pic.scale.z); return og; }; }; @@ -84,8 +92,10 @@ grid3routine ZXgrid=ZXgrid(); grid3routine YZgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--Y(pic),Z(pic)--YZ(pic),pic.userMin--X(pic), - pic.userMin.y,pic.userMax.y,pos,pic.scale.y); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--Y(pic),Z(pic)--YZ(pic),m--X(pic), + m.y,M.y,pos,pic.scale.y); return og; }; }; @@ -94,8 +104,10 @@ grid3routine YZgrid=YZgrid(); grid3routine ZYgrid(position pos=Relative(0)) { return new grid3(picture pic) { grid3 og; - og.create(pic,pic.userMin--Z(pic),Y(pic)--YZ(pic),pic.userMin--X(pic), - pic.userMin.z,pic.userMax.z,pos,pic.scale.z); + triple m=pic.userMin(); + triple M=pic.userMax(); + og.create(pic,m--Z(pic),Y(pic)--YZ(pic),m--X(pic), + m.z,M.z,pos,pic.scale.z); return og; }; }; diff --git a/Master/texmf/asymptote/math.asy b/Master/texmf/asymptote/math.asy index 0dfddff7f2f..77c0664895f 100644 --- a/Master/texmf/asymptote/math.asy +++ b/Master/texmf/asymptote/math.asy @@ -113,6 +113,30 @@ real[] partialsum(real[] a, real[] dx) return b; } +// Given an integer array a, return its partial sums. +int[] partialsum(int[] a) +{ + int[] b=new int[a.length]; + int sum=0; + for(int i=0; i < a.length; ++i) { + sum += a[i]; + b[i]=sum; + } + return b; +} + +// Given an integer array a, return its partial dx-weighted sums. +int[] partialsum(int[] a, int[] dx) +{ + int[] b=new int[a.length]; + int sum=0; + for(int i=0; i < a.length; ++i) { + sum += a[i]*dx[i]; + b[i]=sum; + } + return b; +} + // If strict=false, return whether i > j implies a[i] >= a[j] // If strict=true, return whether i > j implies a[i] > a[j] bool increasing(real[] a, bool strict=false) @@ -232,11 +256,12 @@ bool rectangular(triple[][] m) // size of picture pic. void drawline(picture pic=currentpicture, pair P, pair Q, pen p=currentpen) { - pic.add(new void (frame f, transform t, transform, pair m, pair M) { + pic.add(new void (frame f, transform t, transform T, pair m, pair M) { // Reduce the bounds by the size of the pen. m -= min(p); M -= max(p); // Calculate the points and direction vector in the transformed space. + t=t*T; pair z=t*P; pair v=t*Q-z; diff --git a/Master/texmf/asymptote/palette.asy b/Master/texmf/asymptote/palette.asy index 41a40a04a85..88f8ae2c42f 100644 --- a/Master/texmf/asymptote/palette.asy +++ b/Master/texmf/asymptote/palette.asy @@ -138,6 +138,18 @@ void image(picture pic=currentpicture, pen[][] data, pair initial, pair final, pic.addBox(initial,final); } +void image(picture pic=currentpicture, pen f(int, int), int width, int height, + pair initial, pair final, bool antialias=false) +{ + initial=Scale(pic,initial); + final=Scale(pic,final); + + pic.add(new void(frame F, transform t) { + _image(F,f,width,height,initial,final,t,antialias=antialias); + },true); + pic.addBox(initial,final); +} + bounds image(picture pic=currentpicture, pair[] z, real[] f, range range=Full, pen[] palette) { diff --git a/Master/texmf/asymptote/plain_arrows.asy b/Master/texmf/asymptote/plain_arrows.asy index 490f76f777c..59b65aa4126 100644 --- a/Master/texmf/asymptote/plain_arrows.asy +++ b/Master/texmf/asymptote/plain_arrows.asy @@ -469,30 +469,87 @@ void draw(frame f, path g, pen p=currentpen, arrowbar arrow) add(f,pic.fit()); } -void draw(picture pic=currentpicture, Label L="", path g, align align=NoAlign, - pen p=currentpen, arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) -{ - Label L=L.copy(); - L.align(align); - if(marker != nomarker && !marker.above) marker.mark(pic,g); - bool drawpath=arrow(pic,g,p,margin); - if(bar(pic,g,p,margin) && drawpath) _draw(pic,g,p,margin); - if(L.s != "") { - L.p(p); - L.out(pic,g); +void draw(picture pic=currentpicture, Label L=null, path g, + align align=NoAlign, pen p=currentpen, arrowbar arrow=None, + arrowbar bar=None, margin margin=NoMargin, Label legend=null, + marker marker=nomarker) +{ + // These if statements are ordered in such a way that the most common case + // (with just a path and a pen) executes the least bytecode. + if (marker == nomarker) + { + if (arrow == None && bar == None) + { + if (margin == NoMargin && size(nib(p)) == 0) + { + pic.addExactAbove( + new void(frame f, transform t, transform T, pair, pair) { + _draw(f,t*T*g,p); + }); + pic.addPath(g,p); + + // Jumping over else clauses takes time, so test if we can return + // here. + if (L == null && legend == null) + return; + } + else // With margin or polygonal pen. + { + _draw(pic, g, p, margin); + } + } + else /* arrow or bar */ + { + // Note we are using & instead of && as both arrow and bar need to be + // called. + if (arrow(pic, g, p, margin) & bar(pic, g, p, margin)) + _draw(pic, g, p, margin); + } + + if(L != null && L.s != "") { + L=L.copy(); + L.align(align); + L.p(p); + L.out(pic,g); + } + + if(legend != null && legend.s != "") { + legend.p(p); + pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above)); + } } - if(legend.s != "") { - legend.p(p); - pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above)); + else /* marker != nomarker */ + { + if(marker != nomarker && !marker.above) marker.mark(pic,g); + + // Note we are using & instead of && as both arrow and bar need to be + // called. + if ((arrow == None || arrow(pic, g, p, margin)) & + (bar == None || bar(pic, g, p, margin))) + { + _draw(pic, g, p, margin); + } + + if(L != null && L.s != "") { + L=L.copy(); + L.align(align); + L.p(p); + L.out(pic,g); + } + + if(legend != null && legend.s != "") { + legend.p(p); + pic.legend.push(Legend(legend.s,legend.p,p,marker.f,marker.above)); + } + + if(marker != nomarker && marker.above) marker.mark(pic,g); } - if(marker != nomarker && marker.above) marker.mark(pic,g); } // Draw a fixed-size line about the user-coordinate 'origin'. -void draw(pair origin, picture pic=currentpicture, Label L="", path g, +void draw(pair origin, picture pic=currentpicture, Label L=null, path g, align align=NoAlign, pen p=currentpen, arrowbar arrow=None, - arrowbar bar=None, margin margin=NoMargin, Label legend="", + arrowbar bar=None, margin margin=NoMargin, Label legend=null, marker marker=nomarker) { picture opic; @@ -501,21 +558,22 @@ void draw(pair origin, picture pic=currentpicture, Label L="", path g, } void draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen, - Label legend="", marker marker=nomarker) + Label legend=null, marker marker=nomarker) { + // This could be optimized to size and draw the entire array as a batch. for(int i=0; i < g.length-1; ++i) draw(pic,g[i],p,marker); if(g.length > 0) draw(pic,g[g.length-1],p,legend,marker); } void draw(picture pic=currentpicture, guide[] g, pen p=currentpen, - Label legend="", marker marker=nomarker) + Label legend=null, marker marker=nomarker) { draw(pic,(path[]) g,p,legend,marker); } void draw(pair origin, picture pic=currentpicture, explicit path[] g, - pen p=currentpen, Label legend="", marker marker=nomarker) + pen p=currentpen, Label legend=null, marker marker=nomarker) { picture opic; draw(opic,g,p,legend,marker); @@ -523,21 +581,23 @@ void draw(pair origin, picture pic=currentpicture, explicit path[] g, } void draw(pair origin, picture pic=currentpicture, guide[] g, pen p=currentpen, - Label legend="", marker marker=nomarker) + Label legend=null, marker marker=nomarker) { draw(origin,pic,(path[]) g,p,legend,marker); } // Align an arrow pointing to b from the direction dir. The arrow is // 'length' PostScript units long. -void arrow(picture pic=currentpicture, Label L="", pair b, pair dir, +void arrow(picture pic=currentpicture, Label L=null, pair b, pair dir, real length=arrowlength, align align=NoAlign, pen p=currentpen, arrowbar arrow=Arrow, margin margin=EndMargin) { - Label L=L.copy(); - if(L.defaultposition) L.position(0); - L.align(L.align,dir); - L.p(p); + if(L != null && L.s != "") { + L=L.copy(); + if(L.defaultposition) L.position(0); + L.align(L.align,dir); + L.p(p); + } marginT margin=margin(b--b,p); // Extract margin.begin and margin.end pair a=(margin.begin+length+margin.end)*unit(dir); draw(b,pic,L,a--(0,0),align,p,arrow,margin); @@ -562,6 +622,7 @@ frame[] fit2(picture[] pictures, picture all) } // Fit an array of pictures simultaneously using the size of the first picture. +// TODO: Remove unused arguments. frame[] fit(string prefix="", picture[] pictures, string format="", bool view=true, string options="", string script="", projection P=currentprojection) diff --git a/Master/texmf/asymptote/plain_bounds.asy b/Master/texmf/asymptote/plain_bounds.asy new file mode 100644 index 00000000000..71c304da02f --- /dev/null +++ b/Master/texmf/asymptote/plain_bounds.asy @@ -0,0 +1,783 @@ +include plain_scaling; + +// After an transformation, produce new coordinate bounds. For paths that +// have been added, this is only an approximation since it takes the bounds of +// their transformed bounding box. +private void addTransformedCoords(coords2 dest, transform t, + coords2 point, coords2 min, coords2 max) +{ + dest.push(t, point, point); + + // Add in all 4 corner coords, to properly size rectangular pictures. + dest.push(t,min,min); + dest.push(t,min,max); + dest.push(t,max,min); + dest.push(t,max,max); +} + +// Adds another sizing restriction to the coordinates, but only if it is +// maximal, that is, if under some scaling, this coordinate could be the +// largest. +private void addIfMaximal(coord[] coords, real user, real truesize) { + // TODO: Test promoting coordinates for efficiency. + + for (coord c : coords) + if (user <= c.user && truesize <= c.truesize) + // Not maximal. + return; + + // The coordinate is not dominated by any existing extreme, so it is + // maximal and will be added, but first remove any coords it now dominates. + int i = 0; + while (i < coords.length) { + coord c = coords[i]; + if (c.user <= user && c.truesize <= truesize) + coords.delete(i); + else + ++i; + } + + // Add the coordinate to the extremes. + coords.push(coord.build(user, truesize)); +} + +private void addIfMaximal(coord[] dest, coord[] src) +{ + // This may be inefficient, as it rebuilds the coord struct when adding it. + for (coord c : src) + addIfMaximal(dest, c.user, c.truesize); +} + +// Same as addIfMaximal, but testing for minimal coords. +private void addIfMinimal(coord[] coords, real user, real truesize) { + for (coord c : coords) + if (user >= c.user && truesize >= c.truesize) + return; + + int i = 0; + while (i < coords.length) { + coord c = coords[i]; + if (c.user >= user && c.truesize >= truesize) + coords.delete(i); + else + ++i; + } + + coords.push(coord.build(user, truesize)); +} + +private void addIfMinimal(coord[] dest, coord[] src) +{ + for (coord c : src) + addIfMinimal(dest, c.user, c.truesize); +} + +// This stores a list of sizing bounds for picture data. If the object is +// frozen, then it cannot be modified further, and therefore can be safely +// passed by reference and stored in the sizing data for multiple pictures. +private struct freezableBounds { + restricted bool frozen = false; + void freeze() { + frozen = true; + } + + // Optional links to further (frozen) sizing data. + private freezableBounds[] links; + + // Links to (frozen) sizing data that is transformed when added here. + private static struct transformedBounds { + transform t; + freezableBounds link; + }; + private transformedBounds[] tlinks; + + // The sizing data. It cannot be modified once this object is frozen. + private coords2 point, min, max; + + // A bound represented by a path. Using the path instead of the bounding + // box means it will be accurate after a transformation by coordinates. + private path[] pathBounds; + + // A bound represented by a path and a pen. + // As often many paths use the same pen, we store an array of paths. + private static struct pathpen { + path[] g; pen p; + + void operator init(path g, pen p) { + this.g.push(g); + this.p = p; + } + } + private static pathpen operator *(transform t, pathpen pp) { + // Should the pen be transformed? + pathpen newpp; + for (path g : pp.g) + newpp.g.push(t*g); + newpp.p = pp.p; + return newpp; + } + + // WARNING: Due to crazy optimizations, if this array is changed between an + // empty and non-empty state, the assignment of a method to + // addPath(path,pen) must also change. + private pathpen[] pathpenBounds; + + // Once frozen, the sizing is immutable, and therefore we can compute and + // store the extremal coordinates. + public static struct extremes { + coord[] left, bottom, right, top; + + void operator init(coord[] left, coord[] bottom, + coord[] right, coord[] top) { + this.left = left; + this.bottom = bottom; + this.right = right; + this.top = top; + } + + } + private static void addMaxToExtremes(extremes e, pair user, pair truesize) { + addIfMaximal(e.right, user.x, truesize.x); + addIfMaximal(e.top, user.y, truesize.y); + } + private static void addMinToExtremes(extremes e, pair user, pair truesize) { + addIfMinimal(e.left, user.x, truesize.x); + addIfMinimal(e.bottom, user.y, truesize.y); + } + private static void addMaxToExtremes(extremes e, coords2 coords) { + addIfMaximal(e.right, coords.x); + addIfMaximal(e.top, coords.y); + } + private static void addMinToExtremes(extremes e, coords2 coords) { + addIfMinimal(e.left, coords.x); + addIfMinimal(e.bottom, coords.y); + } + + private extremes cachedExtremes = null; + + // Once frozen, getMutable returns a new object based on this one, which can + // be modified. + freezableBounds getMutable() { + assert(frozen); + var f = new freezableBounds; + f.links.push(this); + return f; + } + + freezableBounds transformed(transform t) { + // Freeze these bounds, as we are storing a reference to them. + freeze(); + + var tlink = new transformedBounds; + tlink.t = t; + tlink.link = this; + + var b = new freezableBounds; + b.tlinks.push(tlink); + + return b; + } + + void append(freezableBounds b) { + // Check that we can modify the object. + assert(!frozen); + + //TODO: If b is "small", ie. a single tlink or cliplink, just copy the + //link. + + // As we only reference b, we must freeze it to ensure it does not change. + b.freeze(); + links.push(b); + } + + void addPoint(pair user, pair truesize) { + assert(!frozen); + point.push(user, truesize); + } + + void addBox(pair userMin, pair userMax, pair trueMin, pair trueMax) { + assert(!frozen); + this.min.push(userMin, trueMin); + this.max.push(userMax, trueMax); + } + + void addPath(path g) { + // This, and other asserts have been removed to speed things up slightly. + //assert(!frozen); + this.pathBounds.push(g); + } + + void addPath(path[] g) { + //assert(!frozen); + this.pathBounds.append(g); + } + + // To squeeze out a bit more performance, this method is either assigned + // addPathToNonEmptyArray or addPathToEmptyArray depending on the state of + // the pathpenBounds array. + void addPath(path g, pen p); + + private void addPathToNonEmptyArray(path g, pen p) { + //assert(!frozen); + //assert(!pathpenBounds.empty()); + var pp = pathpenBounds[0]; + + // Test if the pens are equal or have the same bounds. + if (pp.p == p || (min(pp.p) == min(p) && max(pp.p) == max(p))) { + // If this path has the same pen as the last one, just add it to the + // array corresponding to that pen. + pp.g.push(g); + } + else { + // A different pen. Start a new bound and put it on the front. Put + // the old bound at the end of the array. + pathpenBounds[0] = pathpen(g,p); + pathpenBounds.push(pp); + } + } + void addPathToEmptyArray(path g, pen p) { + //assert(!frozen); + //assert(pathpenBounds.empty()); + + pathpenBounds.push(pathpen(g,p)); + addPath = addPathToNonEmptyArray; + } + + // Initial setting for addPath. + addPath = addPathToEmptyArray; + + // Transform the sizing info by t then add the result to the coords + // structure. + private void accumulateCoords(transform t, coords2 coords) { + for (var link : links) + link.accumulateCoords(t, coords); + + for (var tlink : tlinks) + tlink.link.accumulateCoords(t*tlink.t, coords); + + addTransformedCoords(coords, t, this.point, this.min, this.max); + + for (var g : pathBounds) { + g = t*g; + coords.push(min(g), (0,0)); + coords.push(max(g), (0,0)); + } + + for (var pp: pathpenBounds) { + pair pm = min(pp.p), pM = max(pp.p); + for (var g : pp.g) { + g = t*g; + coords.push(min(g), pm); + coords.push(max(g), pM); + } + } + } + + // Add all of the sizing info to the given coords structure. + private void accumulateCoords(coords2 coords) { + for (var link : links) + link.accumulateCoords(coords); + + for (var tlink : tlinks) + tlink.link.accumulateCoords(tlink.t, coords); + + coords.append(this.point); + coords.append(this.min); + coords.append(this.max); + + for (var g : pathBounds) { + coords.push(min(g), (0,0)); + coords.push(max(g), (0,0)); + } + + for (var pp: pathpenBounds) { + pair pm = min(pp.p), pM = max(pp.p); + for (var g : pp.g) { + coords.push(min(g), pm); + coords.push(max(g), pM); + } + } + } + + // Returns all of the coords that this sizing data represents. + private coords2 allCoords() { + coords2 coords; + accumulateCoords(coords); + return coords; + } + + private void addLocalsToExtremes(transform t, extremes e) { + coords2 coords; + addTransformedCoords(coords, t, this.point, this.min, this.max); + addMinToExtremes(e, coords); + addMaxToExtremes(e, coords); + + if (pathBounds.length > 0) { + addMinToExtremes(e, minAfterTransform(t, pathBounds), (0,0)); + addMaxToExtremes(e, maxAfterTransform(t, pathBounds), (0,0)); + } + + for (var pp : pathpenBounds) { + if (pp.g.length > 0) { + addMinToExtremes(e, minAfterTransform(t, pp.g), min(pp.p)); + addMaxToExtremes(e, maxAfterTransform(t, pp.g), max(pp.p)); + } + } + } + + private void addToExtremes(transform t, extremes e) { + for (var link : links) + link.addToExtremes(t, e); + + for (var tlink : tlinks) + tlink.link.addToExtremes(t*tlink.t, e); + + addLocalsToExtremes(t, e); + } + + private void addLocalsToExtremes(extremes e) { + addMinToExtremes(e, point); + addMaxToExtremes(e, point); + addMinToExtremes(e, min); + addMaxToExtremes(e, max); + + if (pathBounds.length > 0) { + addMinToExtremes(e, min(pathBounds), (0,0)); + addMaxToExtremes(e, max(pathBounds), (0,0)); + } + + for (var pp : pathpenBounds) { + if (pp.g.length > 0) { + addMinToExtremes(e, min(pp.g), min(pp.p)); + addMaxToExtremes(e, max(pp.g), max(pp.p)); + } + } + } + + private void addToExtremes(extremes e) { + for (var link : links) + link.addToExtremes(e); + + for (var tlink : tlinks) + tlink.link.addToExtremes(tlink.t, e); + + addLocalsToExtremes(e); + } + + private static void write(extremes e) { + static void write(coord[] coords) { + for (coord c : coords) + write(" " + (string)c.user + " u + " + (string)c.truesize); + } + write("left:"); + write(e.left); + write("bottom:"); + write(e.bottom); + write("right:"); + write(e.right); + write("top:"); + write(e.top); + } + + // Returns the extremal coordinates of the sizing data. + public extremes extremes() { + if (cachedExtremes == null) { + freeze(); + + extremes e; + addToExtremes(e); + cachedExtremes = e; + } + + return cachedExtremes; + } + + // Helper functions for computing the usersize bounds. usermin and usermax + // would be easily computable from extremes, except that the picture + // interface actually allows calls that manually change the usermin and + // usermax values. Therefore, we have to compute these values separately. + private static struct bounds { + bool areSet=false; + pair min; + pair max; + } + private static struct boundsAccumulator { + pair[] mins; + pair[] maxs; + + void push(pair m, pair M) { + mins.push(m); + maxs.push(M); + } + + void push(bounds b) { + if (b.areSet) + push(b.min, b.max); + } + + void push(transform t, bounds b) { + if (b.areSet) { + pair[] box = { t*(b.min.x,b.max.y), t*b.max, + t*b.min.x, t*(b.min.x,b.max.y) }; + for (var z : box) + push(z,z); + } + } + + void pushUserCoords(coords2 min, coords2 max) { + int n = min.x.length; + assert(min.y.length == n); + assert(max.x.length == n); + assert(max.y.length == n); + + for (int i = 0; i < n; ++i) + push((min.x[i].user, min.y[i].user), + (max.x[i].user, max.y[i].user)); + } + + bounds collapse() { + bounds b; + if (mins.length > 0) { + b.areSet = true; + b.min = minbound(mins); + b.max = maxbound(maxs); + } + else { + b.areSet = false; + } + return b; + } + } + + // The user bounds already calculated for this data. + private bounds storedUserBounds = null; + + private void accumulateUserBounds(boundsAccumulator acc) + { + if (storedUserBounds != null) { + assert(frozen); + acc.push(storedUserBounds); + } else { + acc.pushUserCoords(point, point); + acc.pushUserCoords(min, max); + if (pathBounds.length > 0) + acc.push(min(pathBounds), max(pathBounds)); + for (var pp : pathpenBounds) + acc.push(min(pp.g), max(pp.g)); + for (var link : links) + link.accumulateUserBounds(acc); + + // Transforms are handled as they were in the old system. + for (var tlink : tlinks) { + boundsAccumulator tacc; + tlink.link.accumulateUserBounds(tacc); + acc.push(tlink.t, tacc.collapse()); + } + } + } + + private void computeUserBounds() { + freeze(); + boundsAccumulator acc; + accumulateUserBounds(acc); + storedUserBounds = acc.collapse(); + } + + private bounds userBounds() { + if (storedUserBounds == null) + computeUserBounds(); + + assert(storedUserBounds != null); + return storedUserBounds; + } + + // userMin/userMax returns the minimal/maximal userspace coordinate of the + // sizing data. As coordinates for objects such as labels can have + // significant truesize dimensions, this userMin/userMax values may not + // correspond closely to the end of the screen, and are of limited use. + // userSetx and userSety determine if there is sizing data in order to even + // have userMin/userMax defined. + public bool userBoundsAreSet() { + return userBounds().areSet; + } + + public pair userMin() { + return userBounds().min; + } + public pair userMax() { + return userBounds().max; + } + + // To override the true userMin and userMax bounds, first compute the + // userBounds as they should be at this point, then change the values. + public void alterUserBound(string which, real val) { + // We are changing the bounds data, so it cannot be frozen yet. After the + // user bounds are set, however, the sizing data cannot change, so it will + // be frozen. + assert(!frozen); + computeUserBounds(); + assert(frozen); + + var b = storedUserBounds; + if (which == "minx") + b.min = (val, b.min.y); + else if (which == "miny") + b.min = (b.min.x, val); + else if (which == "maxx") + b.max = (val, b.max.y); + else { + assert(which == "maxy"); + b.max = (b.max.x, val); + } + } + + // A temporary measure. Stuffs all of the data from the links and paths + // into the coords. + private void flatten() { + assert(!frozen); + + // First, compute the user bounds, taking into account any manual + // alterations. + computeUserBounds(); + + // Calculate all coordinates. + coords2 coords = allCoords(); + + // Erase all the old data. + point.erase(); + min.erase(); + max.erase(); + pathBounds.delete(); + pathpenBounds.delete(); + addPath = addPathToEmptyArray; + links.delete(); + tlinks.delete(); + + // Put all of the coordinates into point. + point = coords; + } + + void xclip(real Min, real Max) { + assert(!frozen); + flatten(); + point.xclip(Min,Max); + min.xclip(Min,Max); + max.xclip(Min,Max); + + // Cap the userBounds. + bounds b = storedUserBounds; + b.min = (max(Min, b.min.x), b.min.y); + b.max = (min(Max, b.max.x), b.max.y); + } + + void yclip(real Min, real Max) { + assert(!frozen); + flatten(); + point.yclip(Min,Max); + min.yclip(Min,Max); + max.yclip(Min,Max); + + // Cap the userBounds. + bounds b = storedUserBounds; + b.min = (b.min.x, max(Min, b.min.y)); + b.max = (b.max.x, min(Max, b.max.y)); + } + + // Calculate the min for the final frame, given the coordinate transform. + pair min(transform t) { + extremes e = extremes(); + if (e.left.length == 0) + return 0; + + pair a=t*(1,1)-t*(0,0), b=t*(0,0); + scaling xs=scaling.build(a.x,b.x); + scaling ys=scaling.build(a.y,b.y); + + return (min(infinity, xs, e.left), min(infinity, ys, e.bottom)); + } + + // Calculate the max for the final frame, given the coordinate transform. + pair max(transform t) { + extremes e = extremes(); + if (e.right.length == 0) + return 0; + + pair a=t*(1,1)-t*(0,0), b=t*(0,0); + scaling xs=scaling.build(a.x,b.x); + scaling ys=scaling.build(a.y,b.y); + + return (max(-infinity, xs, e.right), max(-infinity, ys, e.top)); + } + + // Returns the transform for turning user-space pairs into true-space pairs. + transform scaling(real xsize, real ysize, + real xunitsize, real yunitsize, + bool keepAspect, bool warn) { + if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0) + return identity(); + + // Get the extremal coordinates. + extremes e = extremes(); + + real sx; + if(xunitsize == 0) { + if(xsize != 0) sx=calculateScaling("x",e.left,e.right,xsize,warn); + } else sx=xunitsize; + + /* Possible alternative code : + real sx = xunitsize != 0 ? xunitsize : + xsize != 0 ? calculateScaling("x", Coords.x, xsize, warn) : + 0; */ + + real sy; + if(yunitsize == 0) { + if(ysize != 0) sy=calculateScaling("y",e.bottom,e.top,ysize,warn); + } else sy=yunitsize; + + if(sx == 0) { + sx=sy; + if(sx == 0) + return identity(); + } else if(sy == 0) sy=sx; + + + if(keepAspect && (xunitsize == 0 || yunitsize == 0)) + return scale(min(sx,sy)); + else + return scale(sx,sy); + } +} + +struct bounds { + private var base = new freezableBounds; + + // We should probably put this back into picture. + bool exact = true; + + // Called just before modifying the sizing data. It ensures base is + // non-frozen. + // Note that this is manually inlined for speed reasons in a couple often + // called methods below. + private void makeMutable() { + if (base.frozen) + base = base.getMutable(); + //assert(!base.frozen); // Disabled for speed reasons. + } + + void erase() { + // Just discard the old bounds. + base = new freezableBounds; + + // We don't reset the 'exact' field, for backward compatibility. + } + + bounds copy() { + // Freeze the underlying bounds and make a shallow copy. + base.freeze(); + + var b = new bounds; + b.base = this.base; + b.exact = this.exact; + return b; + } + + bounds transformed(transform t) { + var b = new bounds; + b.base = base.transformed(t); + b.exact = this.exact; + return b; + } + + void append(bounds b) { + makeMutable(); + base.append(b.base); + } + + void append(transform t, bounds b) { + // makeMutable will be called by append. + if (t == identity()) + append(b); + else + append(b.transformed(t)); + } + + void addPoint(pair user, pair truesize) { + makeMutable(); + base.addPoint(user, truesize); + } + + void addBox(pair userMin, pair userMax, pair trueMin, pair trueMax) { + makeMutable(); + base.addBox(userMin, userMax, trueMin, trueMax); + } + + void addPath(path g) { + //makeMutable(); // Manually inlined here for speed reasons. + if (base.frozen) + base = base.getMutable(); + base.addPath(g); + } + + void addPath(path[] g) { + //makeMutable(); // Manually inlined here for speed reasons. + if (base.frozen) + base = base.getMutable(); + base.addPath(g); + } + + void addPath(path g, pen p) { + //makeMutable(); // Manually inlined here for speed reasons. + if (base.frozen) + base = base.getMutable(); + base.addPath(g, p); + } + + public bool userBoundsAreSet() { + return base.userBoundsAreSet(); + } + public pair userMin() { + return base.userMin(); + } + public pair userMax() { + return base.userMax(); + } + public void alterUserBound(string which, real val) { + makeMutable(); + base.alterUserBound(which, val); + } + + void xclip(real Min, real Max) { + makeMutable(); + base.xclip(Min,Max); + } + + void yclip(real Min, real Max) { + makeMutable(); + base.yclip(Min,Max); + } + + void clip(pair Min, pair Max) { + // TODO: If the user bounds have been manually altered, they may be + // incorrect after the clip. + xclip(Min.x,Max.x); + yclip(Min.y,Max.y); + } + + pair min(transform t) { + return base.min(t); + } + + pair max(transform t) { + return base.max(t); + } + + transform scaling(real xsize, real ysize, + real xunitsize, real yunitsize, + bool keepAspect, bool warn) { + return base.scaling(xsize, ysize, xunitsize, yunitsize, keepAspect, warn); + } +} + +bounds operator *(transform t, bounds b) { + return b.transformed(t); +} diff --git a/Master/texmf/asymptote/plain_constants.asy b/Master/texmf/asymptote/plain_constants.asy index d1d11b1b1c5..d41cfb770b8 100644 --- a/Master/texmf/asymptote/plain_constants.asy +++ b/Master/texmf/asymptote/plain_constants.asy @@ -63,6 +63,8 @@ restricted file stdout=output(""); void none(file file) {} void endl(file file) {write(file,'\n',flush);} void newl(file file) {write(file,'\n');} +void DOSendl(file file) {write(file,'\r\n',flush);} +void DOSnewl(file file) {write(file,'\r\n');} void tab(file file) {write(file,'\t');} void comma(file file) {write(file,',');} typedef void suffix(file); diff --git a/Master/texmf/asymptote/plain_pens.asy b/Master/texmf/asymptote/plain_pens.asy index 5b0bdbd5879..fcf9d31e638 100644 --- a/Master/texmf/asymptote/plain_pens.asy +++ b/Master/texmf/asymptote/plain_pens.asy @@ -17,8 +17,8 @@ void defaultpen(real w) {defaultpen(linewidth(w));} pen operator +(pen p, real w) {return p+linewidth(w);} pen operator +(real w, pen p) {return linewidth(w)+p;} -pen Dotted=dotted+1.0; -pen Dotted(pen p=currentpen) {return dotted+2*linewidth(p);} +pen Dotted(pen p=currentpen) {return linetype(new real[] {0,3})+2*linewidth(p);} +pen Dotted=Dotted(); restricted pen squarecap=linecap(0); restricted pen roundcap=linecap(1); @@ -129,7 +129,7 @@ pen palegrey=palegray; pen lightgrey=lightgray; pen mediumgrey=mediumgray; pen grey=gray; -pen heavygrey=gray; +pen heavygrey=heavygray; pen deepgrey=deepgray; pen darkgrey=darkgray; diff --git a/Master/texmf/asymptote/plain_picture.asy b/Master/texmf/asymptote/plain_picture.asy index 6764d885380..5b06b7f737c 100644 --- a/Master/texmf/asymptote/plain_picture.asy +++ b/Master/texmf/asymptote/plain_picture.asy @@ -1,114 +1,15 @@ -real camerafactor=2; // Factor used for camera adjustment. +// Pre picture <<<1 +import plain_scaling; +import plain_bounds; + +include plain_prethree; + +// This variable is required by asymptote.sty. pair viewportsize=0; // Horizontal and vertical viewport limits. restricted bool Aspect=true; restricted bool IgnoreAspect=false; -typedef real[][] transform3; -restricted transform3 identity4=identity(4); - -// A uniform 3D scaling. -transform3 scale3(real s) -{ - transform3 t=identity(4); - t[0][0]=t[1][1]=t[2][2]=s; - return t; -} - -// Simultaneous 3D scalings in the x, y, and z directions. -transform3 scale(real x, real y, real z) -{ - transform3 t=identity(4); - t[0][0]=x; - t[1][1]=y; - t[2][2]=z; - return t; -} - -transform3 shiftless(transform3 t) -{ - transform3 T=copy(t); - T[0][3]=T[1][3]=T[2][3]=0; - return T; -} - -// A coordinate in "flex space." A linear combination of user and true-size -// coordinates. -struct coord { - real user,truesize; - - // Build a coord. - static coord build(real user, real truesize) { - coord c=new coord; - c.user=user; - c.truesize=truesize; - return c; - } - - // Deep copy of coordinate. Users may add coords to the picture, but then - // modify the struct. To prevent this from yielding unexpected results, deep - // copying is used. - coord copy() { - return build(user, truesize); - } - - void clip(real min, real max) { - user=min(max(user,min),max); - truesize=0; - } -} - -struct coords2 { - coord[] x,y; - void erase() { - x.delete(); - y.delete(); - } - // Only a shallow copy of the individual elements of x and y - // is needed since, once entered, they are never modified. - coords2 copy() { - coords2 c=new coords2; - c.x=copy(x); - c.y=copy(y); - return c; - } - void append(coords2 c) { - x.append(c.x); - y.append(c.y); - } - void push(pair user, pair truesize) { - x.push(coord.build(user.x,truesize.x)); - y.push(coord.build(user.y,truesize.y)); - } - void push(coord cx, coord cy) { - x.push(cx); - y.push(cy); - } - void push(transform t, coords2 c1, coords2 c2) { - for(int i=0; i < c1.x.length; ++i) { - coord cx=c1.x[i], cy=c2.y[i]; - pair tinf=shiftless(t)*(0,0); - pair z=t*(cx.user,cy.user); - pair w=(cx.truesize,cy.truesize); - w=length(w)*unit(shiftless(t)*w); - coord Cx,Cy; - Cx.user=z.x; - Cy.user=z.y; - Cx.truesize=w.x; - Cy.truesize=w.y; - push(Cx,Cy); - } - } - void xclip(real min, real max) { - for(int i=0; i < x.length; ++i) - x[i].clip(min,max); - } - void yclip(real min, real max) { - for(int i=0; i < y.length; ++i) - y[i].clip(min,max); - } -} - struct coords3 { coord[] x,y,z; void erase() { @@ -159,89 +60,7 @@ struct coords3 { } } -bool operator <= (coord a, coord b) -{ - return a.user <= b.user && a.truesize <= b.truesize; -} - -bool operator >= (coord a, coord b) -{ - return a.user >= b.user && a.truesize >= b.truesize; -} - -// Find the maximal elements of the input array, using the partial ordering -// given. -coord[] maxcoords(coord[] in, bool operator <= (coord,coord)) -{ - // As operator <= is defined in the parameter list, it has a special - // meaning in the body of the function. - - coord best; - coord[] c; - - int n=in.length; - - if(n == 0) - return c; - - int first=0; - // Add the first coord without checking restrictions (as there are none). - best=in[first]; - c.push(best); - - static int NONE=-1; - - int dominator(coord x) - { - // This assumes it has already been checked against the best. - for(int i=1; i < c.length; ++i) - if(x <= c[i]) - return i; - return NONE; - } - - void promote(int i) - { - // Swap with the top - coord x=c[i]; - c[i]=best; - best=c[0]=x; - } - - void addmaximal(coord x) - { - coord[] newc; - - // Check if it beats any others. - for(int i=0; i < c.length; ++i) { - coord y=c[i]; - if(!(y <= x)) - newc.push(y); - } - newc.push(x); - c=newc; - best=c[0]; - } - - void add(coord x) - { - if(x <= best) - return; - else { - int i=dominator(x); - if(i == NONE) - addmaximal(x); - else - promote(i); - } - } - - for(int i=1; i < n; ++i) - add(in[i]); - - return c; -} - +// scaleT and Legend <<< typedef real scalefcn(real x); struct scaleT { @@ -328,233 +147,9 @@ struct Legend { } } -pair rectify(pair dir) -{ - real scale=max(abs(dir.x),abs(dir.y)); - if(scale != 0) dir *= 0.5/scale; - dir += (0.5,0.5); - return dir; -} - -pair point(frame f, pair dir) -{ - pair m=min(f); - pair M=max(f); - return m+realmult(rectify(dir),M-m); -} - -path[] align(path[] g, transform t=identity(), pair position, - pair align, pen p=currentpen) -{ - if(g.length == 0) return g; - pair m=min(g); - pair M=max(g); - pair dir=rectify(inverse(t)*-align); - if(basealign(p) == 1) - dir -= (0,m.y/(M.y-m.y)); - pair a=m+realmult(dir,M-m); - return shift(position+align*labelmargin(p))*t*shift(-a)*g; -} - -// Returns a transform for aligning frame f in the direction align -transform shift(frame f, pair align) -{ - return shift(align-point(f,-align)); -} - -// Returns a copy of frame f aligned in the direction align -frame align(frame f, pair align) -{ - return shift(f,align)*f; -} - -struct transformation { - transform3 modelview; // For orientation and positioning - transform3 projection; // For 3D to 2D projection - bool infinity; - void operator init(transform3 modelview) { - this.modelview=modelview; - this.projection=identity4; - infinity=true; - } - void operator init(transform3 modelview, transform3 projection) { - this.modelview=modelview; - this.projection=projection; - infinity=false; - } - transform3 compute() { - return infinity ? modelview : projection*modelview; - } - transformation copy() { - transformation T=new transformation; - T.modelview=copy(modelview); - T.projection=copy(projection); - T.infinity=infinity; - return T; - } -} - -struct projection { - transform3 t; // projection*modelview (cached) - bool infinity; - bool absolute=false; - triple camera; // Position of camera. - triple up; // A vector that should be projected to direction (0,1). - triple target; // Point where camera is looking at. - triple normal; // Normal vector from target to projection plane. - pair viewportshift; // Fractional viewport shift. - real zoom=1; // Zoom factor. - real angle; // Lens angle (for perspective projection). - bool showtarget=true; // Expand bounding volume to include target? - typedef transformation projector(triple camera, triple up, triple target); - projector projector; - bool autoadjust=true; // Adjust camera to lie outside bounding volume? - bool center=false; // Center target within bounding volume? - int ninterpolate; // Used for projecting nurbs to 2D Bezier curves. - bool bboxonly=true; // Typeset label bounding box only. - - transformation T; - - void calculate() { - T=projector(camera,up,target); - t=T.compute(); - infinity=T.infinity; - ninterpolate=infinity ? 1 : 16; - } - - triple vector() { - return camera-target; - } - - void operator init(triple camera, triple up=(0,0,1), triple target=(0,0,0), - triple normal=camera-target, - real zoom=1, real angle=0, pair viewportshift=0, - bool showtarget=true, bool autoadjust=true, - bool center=false, projector projector) { - this.camera=camera; - this.up=up; - this.target=target; - this.normal=normal; - this.zoom=zoom; - this.angle=angle; - this.viewportshift=viewportshift; - this.showtarget=showtarget; - this.autoadjust=autoadjust; - this.center=center; - this.projector=projector; - calculate(); - } - - projection copy() { - projection P=new projection; - P.t=t; - P.infinity=infinity; - P.absolute=absolute; - P.camera=camera; - P.up=up; - P.target=target; - P.normal=normal; - P.zoom=zoom; - P.angle=angle; - P.viewportshift=viewportshift; - P.showtarget=showtarget; - P.autoadjust=autoadjust; - P.center=center; - P.projector=projector; - P.ninterpolate=ninterpolate; - P.bboxonly=bboxonly; - P.T=T.copy(); - return P; - } - - // Return the maximum distance of box(m,M) from target. - real distance(triple m, triple M) { - triple[] c={m,(m.x,m.y,M.z),(m.x,M.y,m.z),(m.x,M.y,M.z), - (M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M}; - return max(abs(c-target)); - } - - // Move the camera so that the box(m,M) rotated about target will always - // lie in front of the clipping plane. - bool adjust(triple m, triple M) { - triple v=camera-target; - real d=distance(m,M); - static real lambda=camerafactor*(1-sqrtEpsilon); - if(lambda*d >= abs(v)) { - camera=target+camerafactor*d*unit(v); - calculate(); - return true; - } - return false; - } -} - -projection currentprojection; - -struct light { - real[][] diffuse; - real[][] ambient; - real[][] specular; - pen background=nullpen; // Background color of the 3D canvas. - real specularfactor; - bool viewport; // Are the lights specified (and fixed) in the viewport frame? - triple[] position; // Only directional lights are currently implemented. - - transform3 T=identity(4); // Transform to apply to normal vectors. +// >>> - bool on() {return position.length > 0;} - - void operator init(pen[] diffuse, - pen[] ambient=array(diffuse.length,black), - pen[] specular=diffuse, pen background=nullpen, - real specularfactor=1, - bool viewport=false, triple[] position) { - int n=diffuse.length; - assert(ambient.length == n && specular.length == n && position.length == n); - - this.diffuse=new real[n][]; - this.ambient=new real[n][]; - this.specular=new real[n][]; - this.background=background; - this.position=new triple[n]; - for(int i=0; i < position.length; ++i) { - this.diffuse[i]=rgba(diffuse[i]); - this.ambient[i]=rgba(ambient[i]); - this.specular[i]=rgba(specular[i]); - this.position[i]=unit(position[i]); - } - this.specularfactor=specularfactor; - this.viewport=viewport; - } - - void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, - pen background=nullpen, real specularfactor=1, - bool viewport=false...triple[] position) { - int n=position.length; - operator init(array(n,diffuse),array(n,ambient),array(n,specular), - background,specularfactor,viewport,position); - } - - void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, - pen background=nullpen, bool viewport=false, - real x, real y, real z) { - operator init(diffuse,ambient,specular,background,viewport,(x,y,z)); - } - - void operator init(explicit light light) { - diffuse=copy(light.diffuse); - ambient=copy(light.ambient); - specular=copy(light.specular); - background=light.background; - specularfactor=light.specularfactor; - viewport=light.viewport; - position=copy(light.position); - } - - real[] background() {return rgba(background == nullpen ? white : background);} -} - -light currentlight; +// Frame Alignment was here triple min3(pen p) { @@ -571,9 +166,34 @@ triple max3(pen p) typedef void drawer(frame f, transform t); // A generalization of drawer that includes the final frame's bounds. +// TODO: Add documentation as to what T is. typedef void drawerBound(frame f, transform t, transform T, pair lb, pair rt); -struct picture { +// PairOrTriple <<<1 +// This struct is used to represent a userMin/userMax which serves as both a +// pair and a triple depending on the context. +struct pairOrTriple { + real x,y,z; + void init() { x = y = z = 0; } +}; +void copyPairOrTriple(pairOrTriple dest, pairOrTriple src) +{ + dest.x = src.x; + dest.y = src.y; + dest.z = src.z; +} +pair operator cast (pairOrTriple a) { + return (a.x, a.y); +}; +triple operator cast (pairOrTriple a) { + return (a.x, a.y, a.z); +} +void write(pairOrTriple a) { + write((triple) a); +} + +struct picture { // <<<1 + // Nodes <<<2 // Three-dimensional version of drawer and drawerBound: typedef void drawer3(frame f, transform3 t, picture pic, projection P); typedef void drawerBound3(frame f, transform3 t, transform3 T, @@ -585,39 +205,6 @@ struct picture { bool uptodate=true; - // The coordinates in flex space to be used in sizing the picture. - struct bounds { - coords2 point,min,max; - bool exact=true; // An accurate picture bounds is provided by the user. - void erase() { - point.erase(); - min.erase(); - max.erase(); - } - bounds copy() { - bounds b=new bounds; - b.point=point.copy(); - b.min=min.copy(); - b.max=max.copy(); - b.exact=exact; - return b; - } - void xclip(real Min, real Max) { - point.xclip(Min,Max); - min.xclip(Min,Max); - max.xclip(Min,Max); - } - void yclip(real Min, real Max) { - point.yclip(Min,Max); - min.yclip(Min,Max); - max.yclip(Min,Max); - } - void clip(triple Min, triple Max) { - xclip(Min.x,Max.x); - yclip(Min.y,Max.y); - } - } - struct bounds3 { coords3 point,min,max; bool exact=true; // An accurate picture bounds is provided by the user. @@ -639,14 +226,15 @@ struct picture { bounds bounds; bounds3 bounds3; + // Other Fields <<<2 // Transform to be applied to this picture. transform T; transform3 T3; - // Cached user-space bounding box - triple userMin,userMax; - bool userSetx,userSety,userSetz; - + // The internal representation of the 3D user bounds. + private pairOrTriple umin, umax; + private bool usetx, usety, usetz; + ScaleT scale; // Needed by graph Legend[] legend; @@ -669,9 +257,11 @@ struct picture { bool fixed; transform fixedscaling; + // Init and erase <<<2 void init() { - userMin=userMax=(0,0,0); - userSetx=userSety=userSetz=false; + umin.init(); + umax.init(); + usetx=usety=usetz=false; T3=identity(4); } init(); @@ -688,6 +278,7 @@ struct picture { init(); } + // Empty <<<2 bool empty2() { return nodes.length == 0; } @@ -700,133 +291,175 @@ struct picture { return empty2() && empty3(); } - pair userMin() {return (userMin.x,userMin.y);} - pair userMax() {return (userMax.x,userMax.y);} + // User min/max <<<2 + pair userMin2() {return bounds.userMin(); } + pair userMax2() {return bounds.userMax(); } - void userMinx(real x) { - userMin=(x,userMin.y,userMin.z); - userSetx=true; + bool userSetx2() { return bounds.userBoundsAreSet(); } + bool userSety2() { return bounds.userBoundsAreSet(); } + + triple userMin3() { return umin; } + triple userMax3() { return umax; } + + bool userSetx3() { return usetx; } + bool userSety3() { return usety; } + bool userSetz3() { return usetz; } + + private typedef real binop(real, real); + + // Helper functions for finding the minimum/maximum of two data, one of + // which may not be defined. + private static real merge(real x1, bool set1, real x2, bool set2, binop m) + { + return set1 ? (set2 ? m(x1,x2) : x1) : x2; } - - void userMiny(real y) { - userMin=(userMin.x,y,userMin.z); - userSety=true; + private pairOrTriple userExtreme(pair u2(), triple u3(), binop m) + { + bool setx2 = userSetx2(); + bool sety2 = userSety2(); + bool setx3 = userSetx3(); + bool sety3 = userSety3(); + + pair p; + if (setx2 || sety2) + p = u2(); + triple t = u3(); + + pairOrTriple r; + r.x = merge(p.x, setx2, t.x, setx3, m); + r.y = merge(p.y, sety2, t.y, sety3, m); + r.z = t.z; + + return r; } - - void userMinz(real z) { - userMin=(userMin.x,userMin.y,z); - userSetz=true; + + // The combination of 2D and 3D data. + pairOrTriple userMin() { + return userExtreme(userMin2, userMin3, min); } - - void userMaxx(real x) { - userMax=(x,userMax.y,userMax.z); - userSetx=true; + pairOrTriple userMax() { + return userExtreme(userMax2, userMax3, max); + } + + bool userSetx() { return userSetx2() || userSetx3(); } + bool userSety() { return userSety2() || userSety3(); } + bool userSetz() = userSetz3; + + // Functions for setting the user bounds. + void userMinx3(real x) { + umin.x=x; + usetx=true; } - void userMaxy(real y) { - userMax=(userMax.x,y,userMax.z); - userSety=true; + void userMiny3(real y) { + umin.y=y; + usety=true; } - void userMaxz(real z) { - userMax=(userMax.x,userMax.y,z); - userSetz=true; + void userMinz3(real z) { + umin.z=z; + usetz=true; } - void userCorners(pair c00, pair c01, pair c10, pair c11) { - userMin=(min(c00.x,c01.x,c10.x,c11.x),min(c00.y,c01.y,c10.y,c11.y), - userMin.z); - userMax=(max(c00.x,c01.x,c10.x,c11.x),max(c00.y,c01.y,c10.y,c11.y), - userMax.z); + void userMaxx3(real x) { + umax.x=x; + usetx=true; } - void userCorners(triple c000, triple c001, triple c010, triple c011, - triple c100, triple c101, triple c110, triple c111) { - userMin=(min(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x), - min(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y), - min(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z)); - userMax=(max(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x), - max(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y), - max(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z)); + void userMaxy3(real y) { + umax.y=y; + usety=true; } - void userCopy(picture pic) { - userMin=(triple) pic.userMin; - userMax=(triple) pic.userMax; - userSetx=pic.userSetx; - userSety=pic.userSety; - userSetz=pic.userSetz; + void userMaxz3(real z) { + umax.z=z; + usetz=true; + } + + void userMinx2(real x) { bounds.alterUserBound("minx", x); } + void userMinx(real x) { userMinx2(x); userMinx3(x); } + void userMiny2(real y) { bounds.alterUserBound("miny", y); } + void userMiny(real y) { userMiny2(y); userMiny3(y); } + void userMaxx2(real x) { bounds.alterUserBound("maxx", x); } + void userMaxx(real x) { userMaxx2(x); userMaxx3(x); } + void userMaxy2(real y) { bounds.alterUserBound("maxy", y); } + void userMaxy(real y) { userMaxy2(y); userMaxy3(y); } + void userMinz(real z) = userMinz3; + void userMaxz(real z) = userMaxz3; + + void userCorners3(triple c000, triple c001, triple c010, triple c011, + triple c100, triple c101, triple c110, triple c111) { + umin.x = min(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x); + umin.y = min(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y); + umin.z = min(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z); + umax.x = max(c000.x,c001.x,c010.x,c011.x,c100.x,c101.x,c110.x,c111.x); + umax.y = max(c000.y,c001.y,c010.y,c011.y,c100.y,c101.y,c110.y,c111.y); + umax.z = max(c000.z,c001.z,c010.z,c011.z,c100.z,c101.z,c110.z,c111.z); } - typedef real binop(real, real); - // Cache the current user-space bounding box x coodinates - void userBoxX(real min, real max, binop m=min, binop M=max) { - if(userSetx) { - userMin=(m(userMin.x,min),userMin.y,userMin.z); - userMax=(M(userMax.x,max),userMax.y,userMax.z); + void userBoxX3(real min, real max, binop m=min, binop M=max) { + if (usetx) { + umin.x=m(umin.x,min); + umax.x=M(umax.x,max); } else { - userMin=(min,userMin.y,userMin.z); - userMax=(max,userMax.y,userMax.z); - userSetx=true; + umin.x=min; + umax.x=max; + usetx=true; } } - + // Cache the current user-space bounding box y coodinates - void userBoxY(real min, real max, binop m=min, binop M=max) { - if(userSety) { - userMin=(userMin.x,m(userMin.y,min),userMin.z); - userMax=(userMax.x,M(userMax.y,max),userMax.z); + void userBoxY3(real min, real max, binop m=min, binop M=max) { + if (usety) { + umin.y=m(umin.y,min); + umax.y=M(umax.y,max); } else { - userMin=(userMin.x,min,userMin.z); - userMax=(userMax.x,max,userMax.z); - userSety=true; + umin.y=min; + umax.y=max; + usety=true; } } - + // Cache the current user-space bounding box z coodinates - void userBoxZ(real min, real max, binop m=min, binop M=max) { - if(userSetz) { - userMin=(userMin.x,userMin.y,m(userMin.z,min)); - userMax=(userMax.x,userMax.y,M(userMax.z,max)); + void userBoxZ3(real min, real max, binop m=min, binop M=max) { + if (usetz) { + umin.z=m(umin.z,min); + umax.z=M(umax.z,max); } else { - userMin=(userMin.x,userMin.y,min); - userMax=(userMax.x,userMax.y,max); - userSetz=true; + umin.z=min; + umax.z=max; + usetz=true; } } - - // Cache the current user-space bounding box - void userBox(pair min, pair max) { - userBoxX(min.x,max.x); - userBoxY(min.y,max.y); - } - + // Cache the current user-space bounding box - void userBox(triple min, triple max) { - userBoxX(min.x,max.x); - userBoxY(min.y,max.y); - userBoxZ(min.z,max.z); + void userBox3(triple min, triple max) { + userBoxX3(min.x,max.x); + userBoxY3(min.y,max.y); + userBoxZ3(min.z,max.z); } - // Clip the current user-space bounding box - void userClip(pair min, pair max) { - userBoxX(min.x,max.x,max,min); - userBoxY(min.y,max.y,max,min); + // Add drawer <<<2 + void add(drawerBound d, bool exact=false, bool above=true) { + uptodate=false; + if(!exact) bounds.exact=false; + if(above) + nodes.push(d); + else + nodes.insert(0,d); } - void add(drawerBound d, bool exact=false) { + // Faster implementation of most common case. + void addExactAbove(drawerBound d) { uptodate=false; - if(!exact) bounds.exact=false; nodes.push(d); } void add(drawer d, bool exact=false, bool above=true) { - uptodate=false; - if(!exact) bounds.exact=false; - nodes.push(new void(frame f, transform t, transform T, pair, pair) { + add(new void(frame f, transform t, transform T, pair, pair) { d(f,t*T); - }); + },exact,above); } void add(drawerBound3 d, bool exact=false, bool above=true) { @@ -845,20 +478,22 @@ struct picture { },exact,above); } - void clip(drawer d, bool exact=false) { - bounds.clip(userMin,userMax); + // Clip <<<2 + void clip(pair min, pair max, drawer d, bool exact=false) { + bounds.clip(min, max); this.add(d,exact); } - void clip(drawerBound d, bool exact=false) { - bounds.clip(userMin,userMax); + void clip(pair min, pair max, drawerBound d, bool exact=false) { + bounds.clip(min, max); this.add(d,exact); } + // Add sizing <<<2 // Add a point to the sizing. void addPoint(pair user, pair truesize=0) { - bounds.point.push(user,truesize); - userBox(user,user); + bounds.addPoint(user,truesize); + //userBox(user,user); } // Add a point to the sizing, accounting also for the size of the pen. @@ -869,7 +504,7 @@ struct picture { void addPoint(triple user, triple truesize=(0,0,0)) { bounds3.point.push(user,truesize); - userBox(user,user); + userBox3(user,user); } void addPoint(triple user, triple truesize=(0,0,0), pen p) { @@ -879,34 +514,21 @@ struct picture { // Add a box to the sizing. void addBox(pair userMin, pair userMax, pair trueMin=0, pair trueMax=0) { - bounds.min.push(userMin,trueMin); - bounds.max.push(userMax,trueMax); - userBox(userMin,userMax); + bounds.addBox(userMin, userMax, trueMin, trueMax); } void addBox(triple userMin, triple userMax, triple trueMin=(0,0,0), triple trueMax=(0,0,0)) { bounds3.min.push(userMin,trueMin); bounds3.max.push(userMax,trueMax); - userBox(userMin,userMax); - } - - // Add a (user space) path to the sizing. - void addPath(path g) { - if(size(g) > 0) - addBox(min(g),max(g)); - } - void addPath(path[] g) { - for(int i=0; i < g.length; ++i) - addPath(g[i]); + userBox3(userMin,userMax); } - // Add a path to the sizing with the additional padding of a pen. - void addPath(path g, pen p) { - if(size(g) > 0) - addBox(min(g),max(g),min(p),max(p)); - } + // For speed reason, we unravel the addPath routines from bounds. This + // avoids an extra function call. + from bounds unravel addPath; + // Size commands <<<2 void size(real x, real y=x, bool keepAspect=this.keepAspect) { if(!empty()) uptodate=false; xsize=x; @@ -929,62 +551,15 @@ struct picture { zunitsize=z; } - // The scaling in one dimension: x --> a*x + b - struct scaling { - real a,b; - static scaling build(real a, real b) { - scaling s=new scaling; - s.a=a; s.b=b; - return s; - } - real scale(real x) { - return a*x+b; - } - real scale(coord c) { - return scale(c.user) + c.truesize; - } - } - - // Calculate the minimum point in scaling the coords. - real min(real m, scaling s, coord[] c) { - for(int i=0; i < c.length; ++i) - if(s.scale(c[i]) < m) - m=s.scale(c[i]); - return m; - } - - // Calculate the maximum point in scaling the coords. - real max(real M, scaling s, coord[] c) { - for(int i=0; i < c.length; ++i) - if(s.scale(c[i]) > M) - M=s.scale(c[i]); - return M; - } - + // min/max of picture <<<2 // Calculate the min for the final frame, given the coordinate transform. pair min(transform t) { - if(bounds.min.x.length == 0 && bounds.point.x.length == 0 && - bounds.max.x.length == 0) return 0; - pair a=t*(1,1)-t*(0,0), b=t*(0,0); - scaling xs=scaling.build(a.x,b.x); - scaling ys=scaling.build(a.y,b.y); - return (min(min(min(infinity,xs,bounds.point.x),xs,bounds.min.x), - xs,bounds.max.x), - min(min(min(infinity,ys,bounds.point.y),ys,bounds.min.y), - ys,bounds.max.y)); + return bounds.min(t); } // Calculate the max for the final frame, given the coordinate transform. pair max(transform t) { - if(bounds.min.x.length == 0 && bounds.point.x.length == 0 && - bounds.max.x.length == 0) return 0; - pair a=t*(1,1)-t*(0,0), b=t*(0,0); - scaling xs=scaling.build(a.x,b.x); - scaling ys=scaling.build(a.y,b.y); - return (max(max(max(-infinity,xs,bounds.point.x),xs,bounds.min.x), - xs,bounds.max.x), - max(max(max(-infinity,ys,bounds.point.y),ys,bounds.min.y), - ys,bounds.max.y)); + return bounds.max(t); } // Calculate the min for the final frame, given the coordinate transform. @@ -1019,66 +594,6 @@ struct picture { zs,bounds3.max.z)); } - // Calculate the sizing constants for the given array and maximum size. - real calculateScaling(string dir, coord[] coords, real size, - bool warn=true) { - access simplex; - simplex.problem p=new simplex.problem; - - void addMinCoord(coord c) { - // (a*user + b) + truesize >= 0: - p.addRestriction(c.user,1,c.truesize); - } - void addMaxCoord(coord c) { - // (a*user + b) + truesize <= size: - p.addRestriction(-c.user,-1,size-c.truesize); - } - - coord[] m=maxcoords(coords,operator >=); - coord[] M=maxcoords(coords,operator <=); - - for(int i=0; i < m.length; ++i) - addMinCoord(m[i]); - for(int i=0; i < M.length; ++i) - addMaxCoord(M[i]); - - int status=p.optimize(); - if(status == simplex.problem.OPTIMAL) { - return scaling.build(p.a(),p.b()).a; - } else if(status == simplex.problem.UNBOUNDED) { - if(warn) warning("unbounded",dir+" scaling in picture unbounded"); - return 0; - } else { - if(!warn) return 1; - bool userzero=true; - for(int i=0; i < coords.length; ++i) { - if(coords[i].user != 0) userzero=false; - } - if(userzero) return 1; - warning("cannotfit","cannot fit picture to "+dir+"size "+(string) size - +"...enlarging..."); - return calculateScaling(dir,coords,sqrt(2)*size,warn); - } - } - - void append(coords2 point, coords2 min, coords2 max, transform t, - bounds bounds) - { - // Add the coord info to this picture. - if(t == identity()) { - point.append(bounds.point); - min.append(bounds.min); - max.append(bounds.max); - } else { - point.push(t,bounds.point,bounds.point); - // Add in all 4 corner points, to properly size rectangular pictures. - point.push(t,bounds.min,bounds.min); - point.push(t,bounds.min,bounds.max); - point.push(t,bounds.max,bounds.min); - point.push(t,bounds.max,bounds.max); - } - } - void append(coords3 point, coords3 min, coords3 max, transform3 t, bounds3 bounds) { @@ -1101,37 +616,13 @@ struct picture { } } + // Scaling and Fit <<<2 // Returns the transform for turning user-space pairs into true-space pairs. transform scaling(real xsize, real ysize, bool keepAspect=true, bool warn=true) { - if(xsize == 0 && xunitsize == 0 && ysize == 0 && yunitsize == 0) - return identity(); - - coords2 Coords; - - append(Coords,Coords,Coords,T,bounds); - - real sx; - if(xunitsize == 0) { - if(xsize != 0) sx=calculateScaling("x",Coords.x,xsize,warn); - } else sx=xunitsize; - - real sy; - if(yunitsize == 0) { - if(ysize != 0) sy=calculateScaling("y",Coords.y,ysize,warn); - } else sy=yunitsize; - - if(sx == 0) { - sx=sy; - if(sx == 0) - return identity(); - } else if(sy == 0) sy=sx; + bounds b = (T == identity()) ? this.bounds : T * this.bounds; - - if(keepAspect && (xunitsize == 0 || yunitsize == 0)) - return scale(min(sx,sy)); - else - return scale(sx,sy); + return b.scaling(xsize, ysize, xunitsize, yunitsize, keepAspect, warn); } transform scaling(bool warn=true) { @@ -1184,7 +675,8 @@ struct picture { frame fit(transform t, transform T0=T, pair m, pair M) { frame f; - for(int i=0; i < nodes.length; ++i) + int n = nodes.length; + for(int i=0; i < n; ++i) nodes[i](f,t,T0,m,M); return f; } @@ -1207,6 +699,7 @@ struct picture { return fit3(t,pic,P,min(t),max(t)); } + // Add drawer wrappers <<<2 void add(void d(picture, transform), bool exact=false) { add(new void(frame f, transform t) { picture opic=new picture; @@ -1233,6 +726,7 @@ struct picture { },exact,above); } + // More scaling <<<2 frame scaled() { frame f=fit(fixedscaling); pair d=size(f); @@ -1289,6 +783,7 @@ struct picture { } else return scale(xgrow,ygrow,zgrow); } + // calculateTransform with scaling <<<2 // Return the transform that would be used to fit the picture to a frame transform calculateTransform(real xsize, real ysize, bool keepAspect=true, bool warn=true) { @@ -1309,6 +804,8 @@ struct picture { return scale3(fit3(t,null,P),keepAspect)*t; } + // min/max with xsize and ysize <<<2 + // NOTE: These are probably very slow as implemented. pair min(real xsize=this.xsize, real ysize=this.ysize, bool keepAspect=this.keepAspect, bool warn=true) { return min(calculateTransform(xsize,ysize,keepAspect,warn)); @@ -1331,11 +828,14 @@ struct picture { return max(calculateTransform3(xsize,ysize,zsize,keepAspect,warn,P)); } + // More Fitting <<<2 // Returns the 2D picture fit to the requested size. frame fit2(real xsize=this.xsize, real ysize=this.ysize, bool keepAspect=this.keepAspect) { if(fixed) return scaled(); - if(empty2()) return newframe; + if(empty2()) + return newframe; + transform t=scaling(xsize,ysize,keepAspect); frame f=fit(t); transform s=scale(f,xsize,ysize,keepAspect); @@ -1378,15 +878,42 @@ struct picture { return s*f; } + // Copying <<<2 + + // Copies enough information to yield the same userMin/userMax. + void userCopy2(picture pic) { + userMinx2(pic.userMin2().x); + userMiny2(pic.userMin2().y); + userMaxx2(pic.userMax2().x); + userMaxy2(pic.userMax2().y); + } + + void userCopy3(picture pic) { + copyPairOrTriple(umin, pic.umin); + copyPairOrTriple(umax, pic.umax); + usetx=pic.usetx; + usety=pic.usety; + usetz=pic.usetz; + } + + void userCopy(picture pic) { + userCopy2(pic); + userCopy3(pic); + } + // Copies the drawing information, but not the sizing information into a new // picture. Fitting this picture will not scale as the original picture would. picture drawcopy() { picture dest=new picture; - dest.nodes=copy(nodes); + dest.nodes = copy(nodes); dest.nodes3=copy(nodes3); dest.T=T; dest.T3=T3; - dest.userCopy(this); + + // TODO: User bounds are sizing info, which probably shouldn't be part of + // a draw copy. Should we move this down to copy()? + dest.userCopy3(this); + dest.scale=scale.copy(); dest.legend=copy(legend); @@ -1412,6 +939,37 @@ struct picture { return dest; } + // Helper function for defining transformed pictures. Do not call it + // directly. + picture transformed(transform t) { + picture dest=drawcopy(); + + // Replace nodes with a single drawer that realizes the transform. + drawerBound[] oldnodes = dest.nodes; + void drawAll(frame f, transform tt, transform T, pair lb, pair rt) { + transform Tt = T*t; + for (var node : oldnodes) + node(f, tt, Tt, lb, rt); + } + dest.nodes = new drawerBound[] { drawAll }; + + dest.uptodate=uptodate; + dest.bounds=bounds.transformed(t); + dest.bounds3=bounds3.copy(); + + dest.bounds.exact=false; + + dest.xsize=xsize; dest.ysize=ysize; + dest.xsize3=xsize; dest.ysize3=ysize3; dest.zsize3=zsize3; + dest.keepAspect=keepAspect; + dest.xunitsize=xunitsize; dest.yunitsize=yunitsize; + dest.zunitsize=zunitsize; + dest.fixed=fixed; dest.fixedscaling=fixedscaling; + + return dest; + } + + // Add Picture <<<2 // Add a picture to this picture, such that the user coordinates will be // scaled identically when fitted void add(picture src, bool group=true, filltype filltype=NoFill, @@ -1440,42 +998,38 @@ struct picture { legend.append(src.legend); - if(src.userSetx) userBoxX(src.userMin.x,src.userMax.x); - if(src.userSety) userBoxY(src.userMin.y,src.userMax.y); - if(src.userSetz) userBoxZ(src.userMin.z,src.userMax.z); + if(src.usetx) userBoxX3(src.umin.x,src.umax.x); + if(src.usety) userBoxY3(src.umin.y,src.umax.y); + if(src.usetz) userBoxZ3(src.umin.z,src.umax.z); - append(bounds.point,bounds.min,bounds.max,srcCopy.T,src.bounds); + bounds.append(srcCopy.T, src.bounds); + //append(bounds.point,bounds.min,bounds.max,srcCopy.T,src.bounds); append(bounds3.point,bounds3.min,bounds3.max,srcCopy.T3,src.bounds3); - if(!src.bounds.exact) bounds.exact=false; + //if(!src.bounds.exact) bounds.exact=false; if(!src.bounds3.exact) bounds3.exact=false; } } +// Post Struct <<<1 picture operator * (transform t, picture orig) { - picture pic=orig.copy(); - pic.T=t*pic.T; - pic.userCorners(t*(pic.userMin.x,pic.userMin.y), - t*(pic.userMin.x,pic.userMax.y), - t*(pic.userMax.x,pic.userMin.y), - t*(pic.userMax.x,pic.userMax.y)); - pic.bounds.exact=false; - return pic; + return orig.transformed(t); } picture operator * (transform3 t, picture orig) { picture pic=orig.copy(); pic.T3=t*pic.T3; - pic.userCorners(t*pic.userMin, - t*(pic.userMin.x,pic.userMin.y,pic.userMax.z), - t*(pic.userMin.x,pic.userMax.y,pic.userMin.z), - t*(pic.userMin.x,pic.userMax.y,pic.userMax.z), - t*(pic.userMax.x,pic.userMin.y,pic.userMin.z), - t*(pic.userMax.x,pic.userMin.y,pic.userMax.z), - t*(pic.userMax.x,pic.userMax.y,pic.userMin.z), - t*pic.userMax); + triple umin=pic.userMin3(), umax=pic.userMax3(); + pic.userCorners3(t*umin, + t*(umin.x,umin.y,umax.z), + t*(umin.x,umax.y,umin.z), + t*(umin.x,umax.y,umax.z), + t*(umax.x,umin.y,umin.z), + t*(umax.x,umin.y,umax.z), + t*(umax.x,umax.y,umin.z), + t*umax); pic.bounds3.exact=false; return pic; } @@ -1538,9 +1092,54 @@ pair size(picture pic, bool user=false) return t*M-t*m; } +// Frame Alignment <<< +pair rectify(pair dir) +{ + real scale=max(abs(dir.x),abs(dir.y)); + if(scale != 0) dir *= 0.5/scale; + dir += (0.5,0.5); + return dir; +} + +pair point(frame f, pair dir) +{ + pair m=min(f); + pair M=max(f); + return m+realmult(rectify(dir),M-m); +} + +path[] align(path[] g, transform t=identity(), pair position, + pair align, pen p=currentpen) +{ + if(g.length == 0) return g; + pair m=min(g); + pair M=max(g); + pair dir=rectify(inverse(t)*-align); + if(basealign(p) == 1) + dir -= (0,m.y/(M.y-m.y)); + pair a=m+realmult(dir,M-m); + return shift(position+align*labelmargin(p))*t*shift(-a)*g; +} + +// Returns a transform for aligning frame f in the direction align +transform shift(frame f, pair align) +{ + return shift(align-point(f,-align)); +} + +// Returns a copy of frame f aligned in the direction align +frame align(frame f, pair align) +{ + return shift(f,align)*f; +} +// >>> + pair point(picture pic=currentpicture, pair dir, bool user=true) { - pair z=pic.userMin()+realmult(rectify(dir),pic.userMax()-pic.userMin()); + pair umin = pic.userMin2(); + pair umax = pic.userMax2(); + + pair z=umin+realmult(rectify(dir),umax-umin); return user ? z : pic.calculateTransform()*z; } @@ -1556,7 +1155,7 @@ pair truepoint(picture pic=currentpicture, pair dir, bool user=true) // Transform coordinate in [0,1]x[0,1] to current user coordinates. pair relative(picture pic=currentpicture, pair z) { - return pic.userMin()+realmult(z,pic.userMax()-pic.userMin()); + return pic.userMin2()+realmult(z,pic.userMax2()-pic.userMin2()); } void add(picture pic=currentpicture, drawer d, bool exact=false) @@ -1604,17 +1203,25 @@ void Draw(picture pic=currentpicture, path g, pen p=currentpen) pic.addPath(g,p); } -void _draw(picture pic=currentpicture, path g, pen p=currentpen, - margin margin=NoMargin) +// Default arguments have been removed to increase speed. +void _draw(picture pic, path g, pen p, margin margin) { - pic.add(new void(frame f, transform t) { - draw(f,margin(t*g,p).g,p); - },true); + if (size(nib(p)) == 0 && margin==NoMargin) { + // Inline the drawerBound wrapper for speed. + pic.addExactAbove(new void(frame f, transform t, transform T, pair, pair) { + _draw(f,t*T*g,p); + }); + } else { + pic.add(new void(frame f, transform t) { + draw(f,margin(t*g,p).g,p); + },true); + } pic.addPath(g,p); } void Draw(picture pic=currentpicture, explicit path[] g, pen p=currentpen) { + // Could optimize this by adding one drawer. for(int i=0; i < g.length; ++i) Draw(pic,g[i],p); } @@ -1791,10 +1398,12 @@ void clip(picture pic=currentpicture, path[] g, bool stroke=false, { if(copy) g=copy(g); - pic.userClip(min(g),max(g)); - pic.clip(new void(frame f, transform t) { - clip(f,t*g,stroke,fillrule,false); - },true); + //pic.userClip(min(g),max(g)); + pic.clip(min(g), max(g), + new void(frame f, transform t) { + clip(f,t*g,stroke,fillrule,false); + }, + true); } void beginclip(picture pic=currentpicture, path[] g, bool stroke=false, @@ -1813,11 +1422,26 @@ void beginclip(picture pic=currentpicture, path[] g, bool stroke=false, void endclip(picture pic=currentpicture) { - if(pic.clipmin.length > 0 && pic.clipmax.length > 0) - pic.userClip(pic.clipmin.pop(),pic.clipmax.pop()); - pic.clip(new void(frame f, transform) { - endclip(f); - },true); + pair min,max; + if (pic.clipmin.length > 0 && pic.clipmax.length > 0) + { + min = pic.clipmin.pop(); + max = pic.clipmax.pop(); + } + else + { + // We should probably abort here, since the PostScript output will be + // garbage. + warning("endclip", "endclip without beginclip"); + min = pic.userMin2(); + max = pic.userMax2(); + } + + pic.clip(min, max, + new void(frame f, transform) { + endclip(f); + }, + true); } void unfill(picture pic=currentpicture, path[] g, bool copy=true) diff --git a/Master/texmf/asymptote/plain_prethree.asy b/Master/texmf/asymptote/plain_prethree.asy new file mode 100644 index 00000000000..595bac2fad4 --- /dev/null +++ b/Master/texmf/asymptote/plain_prethree.asy @@ -0,0 +1,224 @@ +// Critical definitions for transform3 needed by projection and picture. + +typedef real[][] transform3; +restricted transform3 identity4=identity(4); + +// A uniform 3D scaling. +transform3 scale3(real s) +{ + transform3 t=identity(4); + t[0][0]=t[1][1]=t[2][2]=s; + return t; +} + +// Simultaneous 3D scalings in the x, y, and z directions. +transform3 scale(real x, real y, real z) +{ + transform3 t=identity(4); + t[0][0]=x; + t[1][1]=y; + t[2][2]=z; + return t; +} + +transform3 shiftless(transform3 t) +{ + transform3 T=copy(t); + T[0][3]=T[1][3]=T[2][3]=0; + return T; +} + +real camerafactor=2; // Factor used for camera adjustment. + +struct transformation { + transform3 modelview; // For orientation and positioning + transform3 projection; // For 3D to 2D projection + bool infinity; + void operator init(transform3 modelview) { + this.modelview=modelview; + this.projection=identity4; + infinity=true; + } + void operator init(transform3 modelview, transform3 projection) { + this.modelview=modelview; + this.projection=projection; + infinity=false; + } + transform3 compute() { + return infinity ? modelview : projection*modelview; + } + transformation copy() { + transformation T=new transformation; + T.modelview=copy(modelview); + T.projection=copy(projection); + T.infinity=infinity; + return T; + } +} + +struct projection { + transform3 t; // projection*modelview (cached) + bool infinity; + bool absolute=false; + triple camera; // Position of camera. + triple up; // A vector that should be projected to direction (0,1). + triple target; // Point where camera is looking at. + triple normal; // Normal vector from target to projection plane. + pair viewportshift; // Fractional viewport shift. + real zoom=1; // Zoom factor. + real angle; // Lens angle (for perspective projection). + bool showtarget=true; // Expand bounding volume to include target? + typedef transformation projector(triple camera, triple up, triple target); + projector projector; + bool autoadjust=true; // Adjust camera to lie outside bounding volume? + bool center=false; // Center target within bounding volume? + int ninterpolate; // Used for projecting nurbs to 2D Bezier curves. + bool bboxonly=true; // Typeset label bounding box only. + + transformation T; + + void calculate() { + T=projector(camera,up,target); + t=T.compute(); + infinity=T.infinity; + ninterpolate=infinity ? 1 : 16; + } + + triple vector() { + return camera-target; + } + + void operator init(triple camera, triple up=(0,0,1), triple target=(0,0,0), + triple normal=camera-target, + real zoom=1, real angle=0, pair viewportshift=0, + bool showtarget=true, bool autoadjust=true, + bool center=false, projector projector) { + this.camera=camera; + this.up=up; + this.target=target; + this.normal=normal; + this.zoom=zoom; + this.angle=angle; + this.viewportshift=viewportshift; + this.showtarget=showtarget; + this.autoadjust=autoadjust; + this.center=center; + this.projector=projector; + calculate(); + } + + projection copy() { + projection P=new projection; + P.t=t; + P.infinity=infinity; + P.absolute=absolute; + P.camera=camera; + P.up=up; + P.target=target; + P.normal=normal; + P.zoom=zoom; + P.angle=angle; + P.viewportshift=viewportshift; + P.showtarget=showtarget; + P.autoadjust=autoadjust; + P.center=center; + P.projector=projector; + P.ninterpolate=ninterpolate; + P.bboxonly=bboxonly; + P.T=T.copy(); + return P; + } + + // Return the maximum distance of box(m,M) from target. + real distance(triple m, triple M) { + triple[] c={m,(m.x,m.y,M.z),(m.x,M.y,m.z),(m.x,M.y,M.z), + (M.x,m.y,m.z),(M.x,m.y,M.z),(M.x,M.y,m.z),M}; + return max(abs(c-target)); + } + + + // This is redefined here to make projection as self-contained as possible. + static private real sqrtEpsilon = sqrt(realEpsilon); + + // Move the camera so that the box(m,M) rotated about target will always + // lie in front of the clipping plane. + bool adjust(triple m, triple M) { + triple v=camera-target; + real d=distance(m,M); + static real lambda=camerafactor*(1-sqrtEpsilon); + if(lambda*d >= abs(v)) { + camera=target+camerafactor*d*unit(v); + calculate(); + return true; + } + return false; + } +} + +projection currentprojection; + +struct light { + real[][] diffuse; + real[][] ambient; + real[][] specular; + pen background=nullpen; // Background color of the 3D canvas. + real specularfactor; + bool viewport; // Are the lights specified (and fixed) in the viewport frame? + triple[] position; // Only directional lights are currently implemented. + + transform3 T=identity(4); // Transform to apply to normal vectors. + + bool on() {return position.length > 0;} + + void operator init(pen[] diffuse, + pen[] ambient=array(diffuse.length,black), + pen[] specular=diffuse, pen background=nullpen, + real specularfactor=1, + bool viewport=false, triple[] position) { + int n=diffuse.length; + assert(ambient.length == n && specular.length == n && position.length == n); + + this.diffuse=new real[n][]; + this.ambient=new real[n][]; + this.specular=new real[n][]; + this.background=background; + this.position=new triple[n]; + for(int i=0; i < position.length; ++i) { + this.diffuse[i]=rgba(diffuse[i]); + this.ambient[i]=rgba(ambient[i]); + this.specular[i]=rgba(specular[i]); + this.position[i]=unit(position[i]); + } + this.specularfactor=specularfactor; + this.viewport=viewport; + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, real specularfactor=1, + bool viewport=false...triple[] position) { + int n=position.length; + operator init(array(n,diffuse),array(n,ambient),array(n,specular), + background,specularfactor,viewport,position); + } + + void operator init(pen diffuse=white, pen ambient=black, pen specular=diffuse, + pen background=nullpen, bool viewport=false, + real x, real y, real z) { + operator init(diffuse,ambient,specular,background,viewport,(x,y,z)); + } + + void operator init(explicit light light) { + diffuse=copy(light.diffuse); + ambient=copy(light.ambient); + specular=copy(light.specular); + background=light.background; + specularfactor=light.specularfactor; + viewport=light.viewport; + position=copy(light.position); + } + + real[] background() {return rgba(background == nullpen ? white : background);} +} + +light currentlight; + diff --git a/Master/texmf/asymptote/plain_scaling.asy b/Master/texmf/asymptote/plain_scaling.asy new file mode 100644 index 00000000000..fd2dbae07c0 --- /dev/null +++ b/Master/texmf/asymptote/plain_scaling.asy @@ -0,0 +1,246 @@ +real expansionfactor=sqrt(2); + +// A coordinate in "flex space." A linear combination of user and true-size +// coordinates. +struct coord { + real user,truesize; + + // Build a coord. + static coord build(real user, real truesize) { + coord c=new coord; + c.user=user; + c.truesize=truesize; + return c; + } + + // Deep copy of coordinate. Users may add coords to the picture, but then + // modify the struct. To prevent this from yielding unexpected results, deep + // copying is used. + coord copy() { + return build(user, truesize); + } + + void clip(real min, real max) { + user=min(max(user,min),max); + truesize=0; + } +} + +bool operator <= (coord a, coord b) +{ + return a.user <= b.user && a.truesize <= b.truesize; +} + +bool operator >= (coord a, coord b) +{ + return a.user >= b.user && a.truesize >= b.truesize; +} + +// Find the maximal elements of the input array, using the partial ordering +// given. +coord[] maxcoords(coord[] in, bool operator <= (coord,coord)) +{ + // As operator <= is defined in the parameter list, it has a special + // meaning in the body of the function. + + coord best; + coord[] c; + + int n=in.length; + + if(n == 0) + return c; + + int first=0; + // Add the first coord without checking restrictions (as there are none). + best=in[first]; + c.push(best); + + static int NONE=-1; + + int dominator(coord x) + { + // This assumes it has already been checked against the best. + for(int i=1; i < c.length; ++i) + if(x <= c[i]) + return i; + return NONE; + } + + void promote(int i) + { + // Swap with the top + coord x=c[i]; + c[i]=best; + best=c[0]=x; + } + + void addmaximal(coord x) + { + coord[] newc; + + // Check if it beats any others. + for(int i=0; i < c.length; ++i) { + coord y=c[i]; + if(!(y <= x)) + newc.push(y); + } + newc.push(x); + c=newc; + best=c[0]; + } + + void add(coord x) + { + if(x <= best) + return; + else { + int i=dominator(x); + if(i == NONE) + addmaximal(x); + else + promote(i); + } + } + + for(int i=1; i < n; ++i) + add(in[i]); + + return c; +} + +struct coords2 { + coord[] x,y; + void erase() { + x.delete(); + y.delete(); + } + // Only a shallow copy of the individual elements of x and y + // is needed since, once entered, they are never modified. + coords2 copy() { + coords2 c=new coords2; + c.x=copy(x); + c.y=copy(y); + return c; + } + void append(coords2 c) { + x.append(c.x); + y.append(c.y); + } + void push(pair user, pair truesize) { + x.push(coord.build(user.x,truesize.x)); + y.push(coord.build(user.y,truesize.y)); + } + void push(coord cx, coord cy) { + x.push(cx); + y.push(cy); + } + void push(transform t, coords2 c1, coords2 c2) { + for(int i=0; i < c1.x.length; ++i) { + coord cx=c1.x[i], cy=c2.y[i]; + pair tinf=shiftless(t)*(0,0); + pair z=t*(cx.user,cy.user); + pair w=(cx.truesize,cy.truesize); + w=length(w)*unit(shiftless(t)*w); + coord Cx,Cy; + Cx.user=z.x; + Cy.user=z.y; + Cx.truesize=w.x; + Cy.truesize=w.y; + push(Cx,Cy); + } + } + void xclip(real min, real max) { + for(int i=0; i < x.length; ++i) + x[i].clip(min,max); + } + void yclip(real min, real max) { + for(int i=0; i < y.length; ++i) + y[i].clip(min,max); + } +} + +// The scaling in one dimension: x --> a*x + b +struct scaling { + real a,b; + static scaling build(real a, real b) { + scaling s=new scaling; + s.a=a; s.b=b; + return s; + } + real scale(real x) { + return a*x+b; + } + real scale(coord c) { + return scale(c.user) + c.truesize; + } +} + +// Calculate the minimum point in scaling the coords. +real min(real m, scaling s, coord[] c) { + for(int i=0; i < c.length; ++i) + if(s.scale(c[i]) < m) + m=s.scale(c[i]); + return m; +} + +// Calculate the maximum point in scaling the coords. +real max(real M, scaling s, coord[] c) { + for(int i=0; i < c.length; ++i) + if(s.scale(c[i]) > M) + M=s.scale(c[i]); + return M; +} + +// Calculate the sizing constants for the given array and maximum size. +real calculateScaling(string dir, coord[] m, coord[] M, real size, + bool warn=true) { + access simplex; + simplex.problem p=new simplex.problem; + + void addMinCoord(coord c) { + // (a*user + b) + truesize >= 0: + p.addRestriction(c.user,1,c.truesize); + } + void addMaxCoord(coord c) { + // (a*user + b) + truesize <= size: + p.addRestriction(-c.user,-1,size-c.truesize); + } + + for (int i=0; i < m.length; ++i) + addMinCoord(m[i]); + for (int i=0; i < M.length; ++i) + addMaxCoord(M[i]); + + int status=p.optimize(); + if(status == simplex.problem.OPTIMAL) { + // TODO: Could just be return a; + return scaling.build(p.a(),p.b()).a; + } else if(status == simplex.problem.UNBOUNDED) { + if(warn) warning("unbounded",dir+" scaling in picture unbounded"); + return 0; + } else { + if(!warn) return 1; + + bool userzero(coord[] coords) { + for(var coord : coords) + if(coord.user != 0) return false; + return true; + } + + if((userzero(m) && userzero(M)) || size >= infinity) return 1; + + warning("cannotfit","cannot fit picture to "+dir+"size "+(string) size + +"...enlarging..."); + + return calculateScaling(dir,m,M,expansionfactor*size,warn); + } +} + +real calculateScaling(string dir, coord[] coords, real size, bool warn=true) +{ + coord[] m=maxcoords(coords,operator >=); + coord[] M=maxcoords(coords,operator <=); + + return calculateScaling(dir, m, M, size, warn); +} diff --git a/Master/texmf/asymptote/plain_shipout.asy b/Master/texmf/asymptote/plain_shipout.asy index e96a3a8acb1..ccf94e6c9fd 100644 --- a/Master/texmf/asymptote/plain_shipout.asy +++ b/Master/texmf/asymptote/plain_shipout.asy @@ -1,6 +1,8 @@ // Default file prefix used for inline LaTeX mode string defaultfilename; +string[] file3; + string outprefix(string prefix=defaultfilename) { return stripextension(prefix != "" ? prefix : outname()); } @@ -77,7 +79,8 @@ void shipout(string prefix=defaultfilename, frame f, int limit=2000; if(abs(m.x) > limit || abs(m.y) > limit) f=shift(-m)*f; - shipout(prefix,f,currentpatterns,format,wait,view,xformStack.pop0); + shipout(prefix,f,currentpatterns,format,wait,view, + xformStack.empty() ? null : xformStack.pop0); shipped=true; } @@ -91,8 +94,17 @@ void shipout(string prefix=defaultfilename, picture pic=currentpicture, bool inlinetex=settings.inlinetex; bool prc=prc(format); bool empty3=pic.empty3(); - if(prc && !empty3) + if(prc && !empty3) { + if(settings.render == 0) { + string image=outprefix(prefix)+"+"+(string) file3.length; + if(settings.inlineimage) image += "_0"; + settings.inlinetex=false; + settings.prc=false; + shipout(image,pic,orientation,nativeformat(),view=false,light,P); + settings.prc=true; + } settings.inlinetex=settings.inlineimage; + } frame f=pic.fit(prefix,format,view=view,options,script,light,P); if(!pic.empty2() || settings.render == 0 || prc || empty3) shipout(prefix,orientation(f),format,wait,view); diff --git a/Master/texmf/asymptote/plain_strings.asy b/Master/texmf/asymptote/plain_strings.asy index 138ab05ca05..98f72f460aa 100644 --- a/Master/texmf/asymptote/plain_strings.asy +++ b/Master/texmf/asymptote/plain_strings.asy @@ -155,16 +155,24 @@ private void notimplemented(string text) abort(text+" is not implemented for the '"+settings.tex+"' TeX engine"); } +string jobname(string name) +{ + int pos=rfind(name,"-"); + return pos >= 0 ? "\ASYprefix\jobname"+substr(name,pos) : name; +} + string graphic(string name, string options="") { if(latex()) { if(options != "") options="["+options+"]"; - if(find(name," ") < 0) - return "\includegraphics"+options+"{"+name+"}"; - else { - return "\includegraphics"+options+ - (pdf() ? "{\""+stripextension(name)+"\".pdf}" : "{\""+name+"\"}"); - } + bool pdf=pdf(); + string includegraphics="\includegraphics"+options; + if(settings.inlinetex) + return includegraphics+"{"+jobname(name)+"}"; + else + return includegraphics+ + (find(name," ") < 0 ? "{"+name+"}" : + (pdf ? "{\""+stripextension(name)+"\".pdf}" : "{\""+name+"\"}")); } if(settings.tex != "context") notimplemented("graphic"); diff --git a/Master/texmf/asymptote/plain_xasy.asy b/Master/texmf/asymptote/plain_xasy.asy index 162cbfb35ad..efc739d8385 100644 --- a/Master/texmf/asymptote/plain_xasy.asy +++ b/Master/texmf/asymptote/plain_xasy.asy @@ -113,11 +113,15 @@ struct framedTransformStack { toPush[tList[a].index]=transact(tList[a]); for(int a=0; a < toPush.length; ++a) if(!toPush.initialized(a)) - toPush[a]=transact(); + toPush[a]=transact(); report("Added"); report(toPush.length); stack.append(toPush); } + + bool empty() { + return stack.length == 0; + } } framedTransformStack xformStack; diff --git a/Master/texmf/asymptote/simplex.asy b/Master/texmf/asymptote/simplex.asy index bd9f69c9324..43920109ff4 100644 --- a/Master/texmf/asymptote/simplex.asy +++ b/Master/texmf/asymptote/simplex.asy @@ -184,8 +184,10 @@ struct problem { // Checks that constants are valid. bool validConstants() { for (int i = 0; i < rows.length; ++i) - if (rows[i].c < 0) - return false; + // Do not test the row for b, as it does not have a non-negativity + // condition. + if (i != VAR_B && rows[i].c < 0) + return false; return true; } diff --git a/Master/texmf/asymptote/slide.asy b/Master/texmf/asymptote/slide.asy index 092c3429145..0a3e0f65fab 100644 --- a/Master/texmf/asymptote/slide.asy +++ b/Master/texmf/asymptote/slide.asy @@ -401,27 +401,27 @@ void figure(string[] s, string options="", real margin=0, S[i]=graphic(s[i],options); } - display(S,margin,captions,caption,align,itempen,figuremattpen, final); + display(S,margin,captions,caption,align,itempen,figuremattpen,final); } void figure(string s, string options="", string caption="", pair align=S, pen p=itempen, pen figuremattpen=figuremattpen, bool final=true) { - figure(new string[] {s},options,caption,align,p,figuremattpen, final); + figure(new string[] {s},options,caption,align,p,figuremattpen,final); } void multifigure(string[] slist, string options="", string caption="", - pair align=S, pen p=itempen, pen figuremattpen=figuremattpen) + pair align=S, pen p=itempen, pen figuremattpen=figuremattpen, + bool step=itemstep) { - if (stepping) { - int lastnode = currentpicture.nodes.length-1; + if(step) { + int lastnode=currentpicture.nodes.length-1; for (int i=0; i<slist.length-1; ++i) { - figure(slist[i], options, caption, align, p, figuremattpen, final=false); + figure(slist[i],options,caption,align,p,figuremattpen,final=false); erasestep(lastnode); } } - figure(slist[slist.length-1], options, caption, align, p, figuremattpen, - final=true); + figure(slist[slist.length-1],options,caption,align,p,figuremattpen,final=true); if(!firststep) step(); firststep=false; @@ -429,12 +429,13 @@ void multifigure(string[] slist, string options="", string caption="", void indexedfigure(string prefix, int first, int last, string options="", string caption="", - pair align=S, pen p=itempen, pen figuremattpen=figuremattpen) + pair align=S, pen p=itempen, pen figuremattpen=figuremattpen, + bool step=itemstep) { string[] s; for(int i=first; i <= last; ++i) s.push(prefix+string(i)); - multifigure(s, options, caption, align, p, figuremattpen); + multifigure(s,options,caption,align,p,figuremattpen,step=step); } string[] codefile; diff --git a/Master/texmf/asymptote/solids.asy b/Master/texmf/asymptote/solids.asy index c9be44552c9..239bce4b9a0 100644 --- a/Master/texmf/asymptote/solids.asy +++ b/Master/texmf/asymptote/solids.asy @@ -1,4 +1,3 @@ -import three; import graph3; pen defaultbackpen=linetype(new real[] {4,4},4,scale=false); diff --git a/Master/texmf/asymptote/three.asy b/Master/texmf/asymptote/three.asy index 4221646f632..033461263eb 100644 --- a/Master/texmf/asymptote/three.asy +++ b/Master/texmf/asymptote/three.asy @@ -28,9 +28,11 @@ struct render bool closed; // use one-sided rendering? bool tessellate; // use tessellated mesh to store straight patches? - bool3 merge; // merge nodes before rendering, for lower quality - // but faster PRC rendering? - // (default=merge only transparent patches) + + bool3 merge; // merge nodes before rendering, for faster but + // lower quality PRC rendering (the value default means + // merge opaque patches only). + int sphere; // PRC sphere type (PRCsphere or NURBSsphere). // General parameters: @@ -2408,7 +2410,8 @@ triple point(frame f, triple dir) triple point(picture pic=currentpicture, triple dir, bool user=true, projection P=currentprojection) { - triple v=pic.userMin+realmult(rectify(dir),pic.userMax-pic.userMin); + triple min = pic.userMin(), max = pic.userMax(); + triple v=min+realmult(rectify(dir),max-min); return user ? v : pic.calculateTransform3(P)*v; } @@ -2509,8 +2512,6 @@ private string format(triple v, string sep=" ") return string(v.x)+sep+string(v.y)+sep+string(v.z); } -private string[] file3; - private string projection(bool infinity, real viewplanesize) { return "activeCamera=scene.cameras.getByIndex(0); @@ -2696,9 +2697,8 @@ string embed3D(string label="", string text=label, string prefix, writeJavaScript(name,lightscript+projection(P.infinity,viewplanesize)+ billboard(index,center),script); - prefix += ".prc"; if(!settings.inlinetex) - file3.push(prefix); + file3.push(prefix+".prc"); triple target=P.target; if(P.viewportshift != 0) { @@ -2730,9 +2730,11 @@ string embed3D(string label="", string text=label, string prefix, ",3Droo="+Format(abs(v))+ ",3Dbg="+Format(light.background()); if(options != "") options3 += ","+options; - if(name != "") options3 += ",3Djscript="+stripdirectory(name); + if(settings.inlinetex) + prefix=jobname(prefix); + options3 += ",3Djscript="+prefix+".js"; - return Embed(stripdirectory(prefix),options3,width,height); + return Embed(prefix+".prc",options3,width,height); } struct scene @@ -2983,7 +2985,7 @@ object embed(string label="", string text=label, string prefix=defaultfilename, } string image; - if(preview && settings.embed) { + if((preview || (prc && settings.render == 0)) && settings.embed) { image=prefix; if(settings.inlinetex) image += "_0"; image += "."+nativeformat(); diff --git a/Master/texmf/asymptote/three_surface.asy b/Master/texmf/asymptote/three_surface.asy index 8e48b0606a3..88e42cf6640 100644 --- a/Master/texmf/asymptote/three_surface.asy +++ b/Master/texmf/asymptote/three_surface.asy @@ -1435,7 +1435,8 @@ void label(frame f, Label L, triple position, align align=NoAlign, bool lighton=light.on(); for(patch S : surface(L,position,bbox=P.bboxonly).s) { draw3D(f,S,position,L.p,light,interaction); - if(render.labelfill && !lighton) // Fill subdivision cracks + // Fill subdivision cracks + if(render.labelfill && opacity(L.p) == 1 && !lighton) _draw(f,S.external(),position,L.p,interaction.type); } } else { @@ -1485,7 +1486,8 @@ void label(picture pic=currentpicture, Label L, triple position, if(is3D()) { for(patch S : surface(L,v,bbox=P.bboxonly).s) { draw3D(f,S,v,L.p,light,interaction); - if(render.labelfill && !lighton) // Fill subdivision cracks + // Fill subdivision cracks + if(render.labelfill && opacity(L.p) == 1 && !lighton) _draw(f,S.external(),v,L.p,interaction.type); } } @@ -1819,6 +1821,26 @@ void dot(picture pic=currentpicture, Label L, triple v, align align=NoAlign, label(pic,L,v,render); } +void pixel(picture pic=currentpicture, triple v, pen p=currentpen, + real width=1) +{ + real h=0.5*width; + pic.add(new void(frame f, transform3 t, picture pic, projection P) { + triple V=t*v; + if(is3D()) + drawpixel(f,V,p,width); + if(pic != null) { + triple R=h*unit(cross(unit(P.vector()),P.up)); + pair z=project(V,P.t); + real h=0.5*abs(project(V+R,P.t)-project(V-R,P.t)); + pair r=h*(1,1)/mm; + fill(pic,box(z-r,z+r),p,false); + } + },true); + triple R=h*(1,1,1); + pic.addBox(v,v,-R,R); +} + pair minbound(triple[] A, projection P) { pair b=project(A[0],P); diff --git a/Master/texmf/asymptote/trembling.asy b/Master/texmf/asymptote/trembling.asy index 61e78a4fca3..6f6f5973332 100644 --- a/Master/texmf/asymptote/trembling.asy +++ b/Master/texmf/asymptote/trembling.asy @@ -1,246 +1,209 @@ -// Copyright (c) 2008, Philippe Ivaldi. -// http://www.piprime.fr/ +// Copyright(c) 2008, Philippe Ivaldi. +// Simplified by John Bowman 02Feb2011 +// http: //www.piprime.fr/ // trembling.asy: handwriting package for the software Asymptote. -// This program is free software ; you can redistribute it and/or modify +// This program is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation ; either version 3 of the License, or -// (at your option) any later version. +// the Free Software Foundation; either version 3 of the License, or +//(at your option) any later version. // This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY ; without even the implied warranty of +// WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // You should have received a copy of the GNU Lesser General Public License -// along with this program ; if not, write to the Free Software +// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// COMMENTARY: +// COMMENTARY: -// THANKS: +// THANKS: -// BUGS: +// BUGS: // magnetic points are experimental... -// CODE: +// CODE: -import geometry; -import stats; - -/*<asyxml><variable type="pair[]" signature="magneticPoints"><code></asyxml>*/ -pair[] magneticPoints; -/*<asyxml></code><documentation>Array of magnetic points. - When a point is magnetized, a trembled path will pass though P if the original path passes through P. - When trembling is enabled with the routine 'startTrembling' all the drawn points is added to this array. - For convenience, one can magnetize an arbitrary number of points with the routine 'magnetize'.<look href="#magnetize(...point[])"><look href="#startTrembling(real,real,real,real,bool"> - </documentation></variable></asyxml>*/ real magneticRadius=1; // unit is bp in postscript coordinates. real trembleFuzz(){return min(1e-3,magneticRadius/10);} -// real trembleFuzz(){return min(1e-1,1);} -pair[] single(pair[] P) +/* <asyxml> <variable type="real" signature="trembleAngle"> <code> </asyxml> */ +real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2; +/* <asyxml> </code> <documentation> Variables used by the routine 'tremble'. + </documentation> </variable> </asyxml> */ + +struct tremble { - pair[] op; - bool allow; - for (int i=0; i < P.length-1; ++i) { - allow=true; - for (int j=i+1; j < P.length; ++j) { - if(abs(P[i]-P[j]) < magneticRadius) { - allow=false; - break; + static real test=5; + + real angle,frequency,random,fuzz; + + pair[] single(pair[] P) + { + pair[] op; + bool allow; + for(int i=0; i < P.length-1; ++i) { + allow=true; + for(int j=i+1; j < P.length; ++j) { + if(abs(P[i]-P[j]) < magneticRadius) { + allow=false; + break; + } } + if(allow) op.push(P[i]); } - if(allow) op.push(P[i]); + if(P.length > 0) op.push(P[P.length-1]); + return op; } - if(P.length > 0) op.push(P[P.length-1]); - return op; -} -/*<asyxml><function type="pair" signature="attract(pair,path,real)"><code></asyxml>*/ -real atime(pair m, path g, real fuzz=trembleFuzz()) -{/*<asyxml></code><documentation>Return the time of the nearest point of 'm' which is on the path g. - 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/ - if(length(g) == 0) return 0.0; - real[] t=intersect(m,g,fuzz); - if(t.length > 0) return t[1]; - real ot; - static real eps=sqrt(realEpsilon); - real abmax=abs(max(g)-m), abmin=abs(min(g)-m); - real initr=abs(m-midpoint(g)); - real maxR=2*max(abmax,abmin), step=eps, r=initr; - real shx=1e-4; - transform T=shift(m); - path ig; - // do { - // do {// Find a radius for intersection - // r += step; - // ig=T*scale(r)*unitcircle; - // if(ig == g) { - // T *= shift(shx,0); - // ig=T*scale(r)*unitcircle; - // } - // t=intersect(ig,g); - // } while(t.length <= 0 && r <= maxR && inside(g,ig) != 1);// - // if(t.length <= 0) { // degenerated case - // r=initr; - // T *= shift(shx,0); - // warning("atime","atime needs numerical adjustment.",position=true); - // } - // } while(t.length <= 0); - if(t.length > 0) ot=t[1]; - real rm=0, rM=r; - while(rM-rm > eps) { - r=(rm+rM)/2; - t=intersect(T*scale(r)*unitcircle,g,fuzz); - if(t.length <= 0) { - rm=r; - } else { - rM=r; - ot=t[1]; + /* <asyxml> <function type="pair" signature="attract(pair,path,real)"> <code> + </asyxml> */ + real atime(pair m, path g, real fuzz=trembleFuzz()) + {/* <asyxml> </code> <documentation> Return the time of the point on path g + nearest to 'm'. + 'fuzz' is the argument 'fuzz' of 'intersect'. </documentation> </function> + </asyxml> */ + if(length(g) == 0) return 0.0; + real[] t=intersect(m,g,fuzz); + if(t.length > 0) return t[1]; + real ot; + static real eps=sqrt(realEpsilon); + real abmax=abs(max(g)-m), abmin=abs(min(g)-m); + real initr=abs(m-midpoint(g)); + real maxR=2*max(abmax,abmin), step=eps, r=initr; + real shx=1e-4; + transform T=shift(m); + path ig; + if(t.length > 0) ot=t[1]; + real rm=0, rM=r; + while(rM-rm > eps) { + r=(rm+rM)/2; + t=intersect(T*scale(r)*unitcircle,g,fuzz); + if(t.length <= 0) { + rm=r; + } else { + rM=r; + ot=t[1]; + } } + return ot; } - return ot; -} - -/*<asyxml><function type="void" signature="magnetize(...pair[])"><code></asyxml>*/ -void magnetize(...pair[] P) -{/*<asyxml></code><documentation>Magnetize the points P. - When a point is magnetized, a trembled path will pass though P if the original path passes through P.</documentation></function></asyxml>*/ - if(magneticRadius <= 0) return; - currentpicture.uptodate=false; - currentpicture.nodes.insert(0, - new void(frame f, transform t, transform T, pair lb, pair rt) - { - for (pair PT:P) { - magneticPoints.push(t*PT); - } - }); -} -/*<asyxml><function type="void" signature="magnetize(...triangle[])"><code></asyxml>*/ -void magnetize(...triangle[] t) -{/*<asyxml></code><documentation>Magnetize the vertices of the triangles t.<look href="#magnetize(...pair[])"/></documentation></function></asyxml>*/ - for(int i=0; i < t.length; ++i) - magnetize(...new point[] {t[i].A, t[i].B, t[i].C}); -} - -void trueMagnetize(pair p) -{ - if(magneticRadius <= 0) return; - magneticPoints.push(p); -} - -/*<asyxml><function type="path" signature="addnode(path,real)"><code></asyxml>*/ -path addnode(path g, real t) -{/*<asyxml></code><documentation>Add a node to 'g' at point(g,t).</documentation></function></asyxml>*/ - real l=length(g); - real rt=t%1; - if (l==0 || (t > l && !cyclic(g)) || rt == 0) return g; - if(cyclic(g)) t=t%l; - int t0=floor(t); - int t1=t0+1; - pair z0=point(g,t0), z1=point(g,t1), - c0=postcontrol(g,t0), c1=precontrol(g,t1), - m0=(1-rt)*z0+rt*c0, m1=(1-rt)*c0+rt*c1, - m2=(1-rt)*c1+rt*z1, m3=(1-rt)*m0+rt*m1, - m4=(1-rt)*m1+rt*m2; - guide og=subpath(g,0,t0); - og=og..controls m0 and m3..point(g,t); - if(cyclic(g)) - if(t1 < l) { - og=og..controls m4 and m2..subpath(g,t1,l)&cycle; - } else og=og..controls m4 and m2..cycle; - else og=og..controls m4 and m2..subpath(g,t1,l); - return og; -} - -path addnodes(path g, real fuzz=trembleFuzz() ...pair[] P) -{ - pair[] P=single(P); - if(length(g) == 0 || P.length == 0 || magneticRadius <= 0) return g; - path og=g; - for(pair tp:P) { - real t=atime(tp,og,fuzz); - real d=abs(tp-point(og,t)); - if(d < magneticRadius) og=addnode(og,t); + /* <asyxml> <function type="path" signature="addnode(path,real)"> <code> + </asyxml> */ + path addnode(path g, real t) + {/* <asyxml> </code> <documentation> Add a node to 'g' at point(g,t). + </documentation> </function> </asyxml> */ + real l=length(g); + real rt=t % 1; + if(l == 0 || (t > l && !cyclic(g)) || rt == 0) return g; + if(cyclic(g)) t=t % l; + int t0=floor(t); + int t1=t0+1; + pair z0=point(g,t0), z1=point(g,t1), + c0=postcontrol(g,t0), c1=precontrol(g,t1), + m0=(1-rt)*z0+rt*c0, m1=(1-rt)*c0+rt*c1, + m2=(1-rt)*c1+rt*z1, m3=(1-rt)*m0+rt*m1, + m4=(1-rt)*m1+rt*m2; + guide og=subpath(g,0,t0)..controls m0 and m3..point(g,t); + if(cyclic(g)) { + if(t1 < l) + og=og..controls m4 and m2..subpath(g,t1,l)&cycle; + else og=og..controls m4 and m2..cycle; + } else og=og..controls m4 and m2..subpath(g,t1,l); + return og; } - return og; -} -/*<asyxml><function type="path" signature="addnodes(path,int)"><code></asyxml>*/ -path addnodes(path g, int n) -{/*<asyxml></code><documentation>Add 'n' nodes between each node of 'g'.</documentation></function></asyxml>*/ - real l=length(g); - if(n == 0 || l == 0) return g; - path og=g; - int np=0; - for (int i=0; i < l; ++i) { - real step=1/(n+1); - for (int j=0; j < n; ++j) { - og=addnode(og,i*(n+1)+j+step); - step=1/(n-j); + path addnodes(path g, real fuzz=trembleFuzz()...pair[] P) + { + pair[] P=single(P); + if(length(g) == 0 || P.length == 0 || magneticRadius <= 0) return g; + path og=g; + for(pair tp: P) { + real t=atime(tp,og,fuzz); + real d=abs(tp-point(og,t)); + if(d < magneticRadius) og=addnode(og,t); } + return og; } - return og; -} - - -/*<asyxml><variable type="real" signature="trembleAngle"><code></asyxml>*/ -real trembleAngle=4, trembleFrequency=0.5, trembleRandom=2;/*<asyxml></code><documentation>Variables used by the routine 'tremble'.</documentation></variable></asyxml>*/ - -/*<asyxml><function type="path" signature="tremble(path,real,real,real,real)"><code></asyxml>*/ -path tremble(path g, - real angle=trembleAngle, - real frequency=trembleFrequency, - real random=trembleRandom, - real fuzz=trembleFuzz()) -{/*<asyxml></code><documentation>Return g as it was handwriting. - The postcontrols and precontrols of the nodes of g will be rotated - by an angle proportional to 'angle' (in degrees). - If frequency < 1, floor(1/frequency) nodes will be added to g to increase the - control points. - If frequency >= 1, one point for floor(frequency) will be used to deform the path. - 'random' controls the randomized coefficient which will be multiplied 'angle'. - random is 0 means don't use randomized coefficient; - More 'random' is hight more the coefficient is hight and the trembling seems randomized.</documentation></function></asyxml>*/ - if(length(g) == 0) return g; - path tg=g; - frequency=abs(frequency); - int f=abs(floor(1/frequency)-1); - tg=addnodes(tg,f); - int frequency=floor(frequency); - int tf=(frequency == 0) ? 1 : frequency; - int l=length(tg); - guide og=point(tg,0); - random=abs(random); - int rsgn(real x){ - int d2=floor(100*x)-10*floor(10*x); - if(d2 == 0) return 1; - return 2%d2 == 0 ? 1 : -1; - } - real randf() - { - real or; - if(random != 0) - if(1%tf != 0) or=0; else { - real ur=unitrand(); - or=rsgn(ur)*angle*(1+ur^(1/random)); + /* <asyxml> <function type="path" signature="addnodes(path,int)"> <code> + </asyxml> */ + path addnodes(path g, int n) + {/* <asyxml> </code> <documentation> Add 'n' nodes between each node of 'g'. + </documentation> </function> </asyxml> */ + real l=length(g); + if(n == 0 || l == 0) return g; + path og=g; + int np=0; + for(int i=0; i < l; ++i) { + real step=1/(n+1); + for(int j=0; j < n; ++j) { + og=addnode(og,i*(n+1)+j+step); + step=1/(n-j); } - else or=rsgn(unitrand())*1.5*angle; - return or; + } + return og; } - real first=randf(), a=first; - real gle; - for(int i=1; i <= l; ++i) + /* <asyxml> <function type="path" + signature="tremble(path,real,real,real,real,pair[] )"> <code> </asyxml> */ + void operator init(real angle=trembleAngle, real frequency=trembleFrequency, + real random=trembleRandom, real fuzz=trembleFuzz()) { + this.angle=angle; + this.frequency=frequency; + this.random=random; + this.fuzz=fuzz; + } + + path deform(path g...pair[] magneticPoints) { + /* <asyxml> </code> <documentation> Return g as it was handwriting. + The postcontrols and precontrols of the nodes of g will be rotated + by an angle proportional to 'angle'(in degrees). + If frequency < 1, floor(1/frequency) nodes will be added to g to + increase the control points. + If frequency>= 1, one point for floor(frequency) will be used to deform + the path. + 'random' controls the randomized coefficient which will be multiplied + by 'angle'. + random is 0 means don't use randomized coefficient; + The higher 'random' is, the more the trembling is randomized. + </documentation> </function> </asyxml> */ + if(length(g) == 0) return g; + g=addnodes(g,fuzz*abs(max(g)-min(g))...magneticPoints); + path tg=g; + frequency=abs(frequency); + int f=abs(floor(1/frequency)-1); + tg=addnodes(tg,f); + int frequency=floor(frequency); + int tf=(frequency == 0) ? 1 : frequency; + int l=length(tg); + guide og=point(tg,0); + random=abs(random); + int rsgn(real x){ + int d2=floor(100*x)-10*floor(10*x); + if(d2 == 0) return 1; + return 2 % d2 == 0 ? 1 : -1; + } + real randf() { + real or; + if(random != 0) { + if(1 % tf != 0) or=0; + else { + real ur=unitrand(); + or=rsgn(ur)*angle*(1+ur^(1/random)); + } + } else or=rsgn(unitrand())*1.5*angle; + return or; + } + + real first=randf(); + for(int i=1; i <= l; ++i) { pair P=point(tg,i); - // gle=(i == l && (cyclic(tg))) ? first : a; - // pair post=rotate(gle,point(tg,i-1))*postcontrol(tg,i-1); - // pair pre=rotate(gle,P)*precontrol(tg,i); - a=randf(); + real a=randf(); pair post=rotate(a,point(tg,i-1))*postcontrol(tg,i-1); pair pre=rotate((a+randf())/2,P)*precontrol(tg,i); if(i == l && (cyclic(tg))) @@ -248,121 +211,6 @@ path tremble(path g, else og=og..controls post and pre..P; } - return og; -} - -typedef path pathModifier(path); -pathModifier NoModifier=new path(path g){return g;}; -pathModifier tremble(real angle=trembleAngle, - real frequency=trembleFrequency, - real random=trembleRandom, - real fuzz=trembleFuzz()) -{ - return new path(path g){return tremble(g,angle,frequency,random,fuzz);}; -} - -void orig_draw(frame f, path g, pen p=currentpen)=draw; -void tremble_draw(frame f, path g, pen p=currentpen){} - -void tremble_marknodes(picture pic=currentpicture, frame f, path g) {} -void tremble_markuniform(bool centered=false, int n, bool rotated=false) {} - -int tremble_circlenodesnumber(real r){return 5;} -int orig_circlenodesnumber(real r)=circlenodesnumber; - -int tremble_circlenodesnumber1(real r, real angle1, real angle2){return 4;} -int orig_circlenodesnumber1(real r, real angle1, real angle2)=circlenodesnumber; - -int tremble_ellipsenodesnumber(real a, real b){return 50;} -int orig_ellipsenodesnumber(real a, real b)=ellipsenodesnumber; - -int tremble_ellipsenodesnumber1(real a, real b, real angle1, real angle2, bool dir){return 20;} -int orig_ellipsenodesnumber1(real a, real b, real angle1, real angle2, bool dir)=ellipsenodesnumber; - -int tremble_parabolanodesnumber(parabola p, real angle1, real angle2){return 20;} -int orig_parabolanodesnumber(parabola p, real angle1, real angle2)=parabolanodesnumber; - -int tremble_hyperbolanodesnumber(hyperbola h, real angle1, real angle2){return 20;} -int orig_hyperbolanodesnumber(hyperbola h, real angle1, real angle2)=hyperbolanodesnumber; - -restricted bool tremblingMode=false; -/*<asyxml><function type="void" signature="startTrembling(real,real,real,real,bool"><code></asyxml>*/ -void startTrembling(real angle=trembleAngle, - real frequency=trembleFrequency, - real random=trembleRandom, - real fuzz=trembleFuzz(), - bool magnetizePoints=true) -{/*<asyxml></code><documentation>Calling this routine all drawn paths will be trembled with the givens parameters.<look href="#tremble(path,real,real,real,real)"/> - If 'magnetizePoints' is true, most dotted points are automatically magnetized.<look href="magnetize(...pair[])"/></documentation></function></asyxml>*/ - if(!tremblingMode) { - tremblingMode=true; - tremble_draw=new void(frame f, path g, pen p=currentpen) - { - if(length(g) == 0 && magnetizePoints) { - trueMagnetize(point(g,0)); - } - g=addnodes(g,fuzz*abs(max(g)-min(g)) ...magneticPoints); - orig_draw(f,tremble(g,angle,frequency,random,fuzz),p); - }; - - plain.draw=tremble_draw; - - if(magnetizePoints) { - marknodes=new void(picture pic=currentpicture, frame f, path g) - { - for(int i=0; i <= length(g); ++i) { - add(pic,f,point(g,i)); - magnetize(point(g,i)); - } - }; - dot=dot(); - - markuniform=new markroutine(bool centered=false, int n, bool rotated=false) - { - return new void(picture pic=currentpicture, frame f, path g) { - if(n <= 0) return; - void add(real x) { - real t=reltime(g,x); - add(pic,rotated ? rotate(degrees(dir(g,t)))*f : f,point(g,t)); - magnetize(point(g,t)); - } - if(centered) { - real width=1/n; - for(int i=0; i < n; ++i) add((i+0.5)*width); - } else { - if(n == 1) add(0.5); - else { - real width=1/(n-1); - for(int i=0; i < n; ++i) - add(i*width); - } - } - }; - }; - } - - circlenodesnumber=tremble_circlenodesnumber; - circlenodesnumber=tremble_circlenodesnumber1; - - ellipsenodesnumber=tremble_ellipsenodesnumber; - ellipsenodesnumber=tremble_ellipsenodesnumber1; - - parabolanodesnumber=tremble_parabolanodesnumber; - hyperbolanodesnumber=tremble_hyperbolanodesnumber; + return og; } } - -// void stopTrembling() -// { -// if(tremblingMode) { -// tremblingMode=false; -// plain.draw=orig_draw; -// // draw=orig_draw1; -// circlenodesnumber=orig_circlenodesnumber; -// circlenodesnumber=orig_circlenodesnumber1; -// ellipsenodesnumber=orig_ellipsenodesnumber; -// ellipsenodesnumber=orig_ellipsenodesnumber1; -// parabolanodesnumber=orig_parabolanodesnumber; -// hyperbolanodesnumber=orig_hyperbolanodesnumber; -// } -// } diff --git a/Master/texmf/asymptote/version.asy b/Master/texmf/asymptote/version.asy index 4a0037a691b..458d00e534a 100644 --- a/Master/texmf/asymptote/version.asy +++ b/Master/texmf/asymptote/version.asy @@ -1 +1 @@ -string VERSION="2.02"; +string VERSION="2.10"; diff --git a/Master/texmf/doc/asymptote/CAD.pdf b/Master/texmf/doc/asymptote/CAD.pdf Binary files differindex 59b899d3388..afaad32261c 100644 --- a/Master/texmf/doc/asymptote/CAD.pdf +++ b/Master/texmf/doc/asymptote/CAD.pdf diff --git a/Master/texmf/doc/asymptote/TeXShopAndAsymptote.pdf b/Master/texmf/doc/asymptote/TeXShopAndAsymptote.pdf Binary files differnew file mode 100644 index 00000000000..5ae18cf90b3 --- /dev/null +++ b/Master/texmf/doc/asymptote/TeXShopAndAsymptote.pdf diff --git a/Master/texmf/doc/asymptote/asy-latex.pdf b/Master/texmf/doc/asymptote/asy-latex.pdf Binary files differnew file mode 100644 index 00000000000..c2be030ad3c --- /dev/null +++ b/Master/texmf/doc/asymptote/asy-latex.pdf diff --git a/Master/texmf/doc/asymptote/asymptote.pdf b/Master/texmf/doc/asymptote/asymptote.pdf Binary files differindex d480d1c6d84..7cf4418bdc4 100644 --- a/Master/texmf/doc/asymptote/asymptote.pdf +++ b/Master/texmf/doc/asymptote/asymptote.pdf diff --git a/Master/texmf/doc/asymptote/examples/NURBScurve.asy b/Master/texmf/doc/asymptote/examples/NURBScurve.asy index b3b8c393b9e..c4da5c2ff5f 100644 --- a/Master/texmf/doc/asymptote/examples/NURBScurve.asy +++ b/Master/texmf/doc/asymptote/examples/NURBScurve.asy @@ -14,7 +14,7 @@ triple[] P={ (-31.5909,21.277,6.70051), (-31.4284,25.4933,6.76745), (-31.5413,30.3485,6.68777), - (-31.4896,32.2839,6.58385), + (-31.4896,32.2839,6.58385) }; draw(P,knot,green); diff --git a/Master/texmf/doc/asymptote/examples/NURBSsurface.asy b/Master/texmf/doc/asymptote/examples/NURBSsurface.asy index 878fd956393..32df6ff98ea 100644 --- a/Master/texmf/doc/asymptote/examples/NURBSsurface.asy +++ b/Master/texmf/doc/asymptote/examples/NURBSsurface.asy @@ -15,28 +15,28 @@ triple[][] P={{ (-31.5909,21.277,6.70051), (-31.4284,25.4933,6.76745), (-31.5413,30.3485,6.68777), - (-31.4896,32.2839,6.58385), + (-31.4896,32.2839,6.58385) },{ (-28.279,12.001,7.89625), (-28.4187,14.7353,8.00954), (-28.5633,21.277,8.22422), (-28.4433,25.4933,8.31214), (-28.5266,30.3485,8.20749), - (-28.4885,32.2839,8.07099), + (-28.4885,32.2839,8.07099) },{ (-20,12.001,10.0379), (-20,14.7353,10.2001), (-20,21.277,10.5076), (-20,25.4933,10.6335), (-20,30.3485,10.4836), - (-20,32.2839,10.2881), + (-20,32.2839,10.2881) },{ (-11.721,12.001,7.84024), (-11.5813,14.7353,7.95269), (-11.4367,21.277,8.16575), (-11.5567,25.4933,8.25302), (-11.4734,30.3485,8.14915), - (-11.5115,32.2839,8.01367), + (-11.5115,32.2839,8.01367) },{ (-8.79391,12.001,6.39481), (-8.60483,14.7353,6.48022), @@ -44,7 +44,8 @@ triple[][] P={{ (-8.57158,25.4933,6.70832), (-8.45874,30.3485,6.62943), (-8.51041,32.2839,6.52653) - }}; + } +}; draw(P,uknot,vknot,new pen[] {red,green,blue,magenta}); diff --git a/Master/texmf/doc/asymptote/examples/SierpinskiSponge.asy b/Master/texmf/doc/asymptote/examples/SierpinskiSponge.asy index 328447d4ac4..c398aa511c6 100644 --- a/Master/texmf/doc/asymptote/examples/SierpinskiSponge.asy +++ b/Master/texmf/doc/asymptote/examples/SierpinskiSponge.asy @@ -1,42 +1,99 @@ size(200); import palette; import three; - + +currentprojection=orthographic(1,1,1); + triple[] M={ (-1,-1,-1),(0,-1,-1),(1,-1,-1),(1,0,-1), (1,1,-1),(0,1,-1),(-1,1,-1),(-1,0,-1), (-1,-1,0),(1,-1,0),(1,1,0),(-1,1,0), - (-1,-1,1),(0,-1,1),(1,-1,1),(1,0,1), - (1,1,1),(0,1,1),(-1,1,1),(-1,0,1) + (-1,-1,1),(0,-1,1),(1,-1,1),(1,0,1),(1,1,1),(0,1,1),(-1,1,1),(-1,0,1) }; - -triple[] K={ - (1,-1,-1),(1,0,-1),(1,1,-1),(1,1,0), - (1,1,1),(1,0,1),(1,-1,1),(1,-1,0), - (0,0,-1),(0,0,1),(0,-1,0),(0,1,0) + +surface[] Squares={ + surface((1,-1,-1)--(1,1,-1)--(1,1,1)--(1,-1,1)--cycle), + surface((-1,-1,-1)--(-1,1,-1)--(-1,1,1)--(-1,-1,1)--cycle), + surface((1,1,-1)--(-1,1,-1)--(-1,1,1)--(1,1,1)--cycle), + surface((1,-1,-1)--(-1,-1,-1)--(-1,-1,1)--(1,-1,1)--cycle), + surface((1,-1,1)--(1,1,1)--(-1,1,1)--(-1,-1,1)--cycle), + surface((1,-1,-1)--(1,1,-1)--(-1,1,-1)--(-1,-1,-1)--cycle), }; - -surface s; - -void recur(triple p, real u, int level) { - if(level > 1 ) - for(triple V : M) - recur(p+u*V,u/3,level-1); - else - for(triple V : K) { - transform3 T=shift(p)*scale3(u)*shift(V)*scale3(0.5); - surface t=T*surface((1,-1,-1)--(1,1,-1)--(1,1,1)--(1,-1,1)--cycle); - s.append(t); - s.append(scale3(-1)*t); + +int[][] SquaresPoints={ + {2,3,4,10,16,15,14,9}, + {0,7,6,11,18,19,12,8}, + {4,5,6,11,18,17,16,10}, + {2,1,0,8,12,13,14,9}, + {12,13,14,15,16,17,18,19}, + {0,1,2,3,4,5,6,7} +}; + +int[][] index={ + {0,2,4},{0,1},{1,2,4},{2,3},{1,3,4},{0,1},{0,3,4},{2,3}, + {4,5},{4,5},{4,5},{4,5}, + {0,2,5},{0,1},{1,2,5},{2,3},{1,3,5},{0,1},{0,3,5},{2,3} +}; + +int[] Sponge0=array(n=6,value=1); + +int[] eraseFaces(int n, int[] Sponge0) { + int[] temp=copy(Sponge0); + for(int k : index[n]) { + temp[k]=0; + } + return temp; +} + +int[][] Sponge1=new int[20][]; +for(int n=0; n < 20; ++n) { + Sponge1[n]=eraseFaces(n,Sponge0); +} + +int[][] eraseFaces(int n, int[][] Sponge1) { + int[][] temp=copy(Sponge1); + for(int k : index[n]) + for(int n1 : SquaresPoints[k]) + temp[n1][k]=0; + return temp; +} + +int[][][] Sponge2=new int[20][][]; +for(int n=0; n < 20; ++n) + Sponge2[n]=eraseFaces(n,Sponge1); + +int[][][] eraseFaces(int n, int[][][] Sponge2) { + int[][][] temp=copy(Sponge2); + for(int k : index[n]) + for(int n2: SquaresPoints[k]) + for(int n1: SquaresPoints[k]) + temp[n2][n1][k]=0; + return temp; +} + +int[][][][] Sponge3=new int[20][][][]; +for(int n=0; n < 20; ++n) + Sponge3[n]=eraseFaces(n,Sponge2); + +surface s3; +real u=2/3; +for(int n3=0; n3 < 20; ++n3) { + surface s2; + for(int n2=0; n2 < 20; ++n2) { + surface s1; + for(int n1=0; n1 < 20; ++n1) { + for(int k=0; k < 6; ++k){ + transform3 T=scale3(u)*shift(M[n1])*scale3(0.5); + if(Sponge3[n3][n2][n1][k] > 0) { + s1.append(T*Squares[k]); + } + } } + transform3 T=scale3(u)*shift(M[n2])*scale3(0.5); + s2.append(T*s1); + } + transform3 T=scale3(u)*shift(M[n3])*scale3(0.5); + s3.append(T*s2); } - -recur((0,0,0),1/3,3); - -surface sf; -sf.append(s); -sf.append(rotate(90,Y)*s); -sf.append(rotate(90,Z)*s); -sf.colors(palette(sf.map(abs),Rainbow())); - -draw(sf,render(compression=Low,merge=true)); +s3.colors(palette(s3.map(abs),Rainbow())); +draw(s3); diff --git a/Master/texmf/doc/asymptote/examples/diatom.asy b/Master/texmf/doc/asymptote/examples/diatom.asy index 2ded75bf0ea..23673dcadf5 100644 --- a/Master/texmf/doc/asymptote/examples/diatom.asy +++ b/Master/texmf/doc/asymptote/examples/diatom.asy @@ -115,7 +115,7 @@ for(int taxon=0; taxon < n; ++taxon) { if(taxon == final) yaxis(pic,Right,LeftTicks("%",0,10),above=true); add(shift(location,0)*pic); - location += pic.userMax.x; + location += pic.userMax().x; } add(new void(frame f, transform) { diff --git a/Master/texmf/doc/asymptote/examples/extrudedcontour.asy b/Master/texmf/doc/asymptote/examples/extrudedcontour.asy index 7b2f67459ce..dabd56b9298 100644 --- a/Master/texmf/doc/asymptote/examples/extrudedcontour.asy +++ b/Master/texmf/doc/asymptote/examples/extrudedcontour.asy @@ -1,6 +1,9 @@ import contour; import palette; import graph3; + +defaultrender.merge=true; + currentprojection=orthographic(25,10,10); size(0,12cm); real a=3; diff --git a/Master/texmf/doc/asymptote/examples/filesurface.asy b/Master/texmf/doc/asymptote/examples/filesurface.asy index 2a93c96ec19..eef9d37f494 100644 --- a/Master/texmf/doc/asymptote/examples/filesurface.asy +++ b/Master/texmf/doc/asymptote/examples/filesurface.asy @@ -23,8 +23,8 @@ s.colors(palette(s.map(new real(triple v) {return find(level >= v.z);}), draw(s,meshpen=thick(),render(merge=true)); -triple m=currentpicture.userMin; -triple M=currentpicture.userMax; +triple m=currentpicture.userMin(); +triple M=currentpicture.userMax(); triple target=0.5*(m+M); xaxis3("$x$",Bounds,InTicks); diff --git a/Master/texmf/doc/asymptote/examples/floatingdisk.asy b/Master/texmf/doc/asymptote/examples/floatingdisk.asy index 2e99ec9c2c1..be8b339767d 100644 --- a/Master/texmf/doc/asymptote/examples/floatingdisk.asy +++ b/Master/texmf/doc/asymptote/examples/floatingdisk.asy @@ -9,9 +9,11 @@ real l=.7; pair pA=(-l,0); pair pB=(l,0); - -path waterline=tremble(addnodes(pA..pB,1),angle=10,frequency=0.1,random=50); -path disk=shift(0,-d)*(scale(R)*unitcircle); + +tremble tr=tremble(angle=10,frequency=0.1,random=50,fuzz=1); +path waterline=tr.deform(pA..pB); + +path disk=shift(0,-d)*scale(R)*unitcircle; path water=waterline--(l,-h)--(-l,-h)--(-l,0)--cycle; path container=(l,1/7)--(l,-h)--(-l,-h)--(-l,1/7); @@ -21,4 +23,4 @@ draw(waterline); draw(container,linewidth(1.5)); -shipout(bbox(2mm,Fill(white))); +shipout(bbox(2mm)); diff --git a/Master/texmf/doc/asymptote/examples/interpolate1.asy b/Master/texmf/doc/asymptote/examples/interpolate1.asy index 9f8367a52a4..8845c8dd2f8 100644 --- a/Master/texmf/doc/asymptote/examples/interpolate1.asy +++ b/Master/texmf/doc/asymptote/examples/interpolate1.asy @@ -7,8 +7,6 @@ import graph; // Test 1: The Runge effect in the Lagrange interpolation of 1/(x^2+1). unitsize(2cm); -xlimits(-5,5); -ylimits(-1,1,Crop); real f(real x) {return(1/(x^2+1));} real df(real x) {return(-2*x/(x^2+1)^2);} @@ -26,9 +24,14 @@ fhorner p=fhorner(h); draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$"); +xlimits(-5,5); +ylimits(-1,1,Crop); + xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); + attach(legend(),point(10S),30S); + shipout("runge1"); erase(); @@ -52,11 +55,13 @@ draw(graph(p,a,b,n=500),"$x\longmapsto{}H_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$"); unitsize(2cm); + xlimits(-5,5); ylimits(-1,5,Crop); xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); + attach(legend(),point(10S),30S); shipout("runge2"); @@ -86,7 +91,9 @@ draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$"); xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); + attach(legend(),point(10S),30S); + shipout("runge3"); erase(); @@ -110,9 +117,12 @@ fhorner p=fhorner(h); draw(graph(p,a,b,n=500),"$x\longmapsto{}L_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\cos(x)$"); + ylimits(-1,5,Crop); + xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); + attach(legend(),point(10S),30S); shipout("runge4"); @@ -122,8 +132,6 @@ erase(); // Test 5: The situation is much better using Tchebychev points. unitsize(2cm); -xlimits(-5,5); -ylimits(-1,2,Crop); real f(real x) {return(1/(x^2+1));} real df(real x) {return(-2*x/(x^2+1)^2);} @@ -144,6 +152,9 @@ fhorner p=fhorner(h); draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$"); +xlimits(-5,5); +ylimits(-1,2,Crop); + xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); attach(legend(),point(10S),30S); @@ -155,8 +166,6 @@ erase(); // Test 6: Adding a few more Tchebychev points yields a very good result. unitsize(2cm); -xlimits(-5,5); -ylimits(-1,2,Crop); real f(real x) {return(1/(x^2+1));} real df(real x) {return(-2*x/(x^2+1)^2);} @@ -175,6 +184,9 @@ fhorner p=fhorner(h); draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\frac{1}{x^2+1}$"); +xlimits(-5,5); +ylimits(-1,2,Crop); + xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); attach(legend(),point(10S),30S); @@ -187,8 +199,6 @@ erase(); // Test 7: Another Tchebychev example. unitsize(2cm); -xlimits(-2,2); -ylimits(-0.5,2,Crop); real f(real x) {return(sqrt(abs(x-1)));} @@ -206,6 +216,9 @@ fhorner p=fhorner(h); draw(graph(p,a,b,n=500),"$x\longmapsto{}T_{"+string(n)+"}$"); draw(graph(f,a,b),red,"$x\longmapsto{}\sqrt{|x-1|}$"); +xlimits(-2,2); +ylimits(-0.5,2,Crop); + xaxis("$x$",BottomTop,LeftTicks); yaxis("$y$",LeftRight,RightTicks); attach(legend(),point(10S),30S); diff --git a/Master/texmf/doc/asymptote/examples/intro.asy b/Master/texmf/doc/asymptote/examples/intro.asy index 5d7ce12b184..fcafefb32a6 100644 --- a/Master/texmf/doc/asymptote/examples/intro.asy +++ b/Master/texmf/doc/asymptote/examples/intro.asy @@ -50,7 +50,6 @@ item("4000 downloads/month from primary\hfill\\ {\tt asymptote.sourceforge.net} site alone."); item("80\ 000 lines of low-level C++ code."); item("36\ 000 lines of high-level Asymptote code."); -item("Latest stable release: Version 2.00 (LGPL)."); if(long) { title("Vector Graphics"); diff --git a/Master/texmf/doc/asymptote/examples/latexusage-1.asy b/Master/texmf/doc/asymptote/examples/latexusage-1.asy new file mode 100644 index 00000000000..b77279c6c47 --- /dev/null +++ b/Master/texmf/doc/asymptote/examples/latexusage-1.asy @@ -0,0 +1,54 @@ +if(!settings.multipleView) settings.batchView=false; +defaultfilename="latexusage-1"; +if(settings.render < 0) settings.render=4; +settings.outformat=""; +settings.inlineimage=true; +settings.embed=true; +settings.toolbar=false; +viewportmargin=(2,2); + +// Global Asymptote definitions can be put here. +import three; +usepackage("bm"); +texpreamble("\def\V#1{\bm{#1}}"); +// One can globally override the default toolbar settings here: +// settings.toolbar=true; + +size(4cm,0); +pen colour1=red; +pen colour2=green; + +pair z0=(0,0); +pair z1=(-1,0); +pair z2=(1,0); +real r=1.5; +path c1=circle(z1,r); +path c2=circle(z2,r); +fill(c1,colour1); +fill(c2,colour2); + +picture intersection=new picture; +fill(intersection,c1,colour1+colour2); +clip(intersection,c2); + +add(intersection); + +draw(c1); +draw(c2); + +//draw("$\A$",box,z1); // Requires [inline] package option. +//draw(Label("$\B$","$B$"),box,z2); // Requires [inline] package option. +draw("$A$",box,z1); +draw("$\V{B}$",box,z2); + +pair z=(0,-2); +real m=3; +margin BigMargin=Margin(0,m*dot(unit(z1-z),unit(z0-z))); + +draw(Label("$A\cap B$",0),conj(z)--z0,Arrow,BigMargin); +draw(Label("$A\cup B$",0),z--z0,Arrow,BigMargin); +draw(z--z1,Arrow,Margin(0,m)); +draw(z--z2,Arrow,Margin(0,m)); + +shipout(bbox(0.25cm)); +viewportsize=(390.0pt,0); diff --git a/Master/texmf/doc/asymptote/examples/latexusage-2.asy b/Master/texmf/doc/asymptote/examples/latexusage-2.asy new file mode 100644 index 00000000000..49c6458419c --- /dev/null +++ b/Master/texmf/doc/asymptote/examples/latexusage-2.asy @@ -0,0 +1,24 @@ +if(!settings.multipleView) settings.batchView=false; +settings.inlinetex=true; +deletepreamble(); +defaultfilename="latexusage-2"; +if(settings.render < 0) settings.render=4; +settings.outformat=""; +settings.inlineimage=true; +settings.embed=true; +settings.toolbar=false; +viewportmargin=(2,2); + +// Global Asymptote definitions can be put here. +import three; +usepackage("bm"); +texpreamble("\def\V#1{\bm{#1}}"); +// One can globally override the default toolbar settings here: +// settings.toolbar=true; + + +currentprojection=orthographic(5,4,2); +draw(unitcube,blue); +label("$V-E+F=2$",(0,1,0.5),3Y,blue+fontsize(17pt)); +size(0,113.81102pt,keepAspect=true); +viewportsize=(390.0pt,0); diff --git a/Master/texmf/doc/asymptote/examples/latexusage-3.asy b/Master/texmf/doc/asymptote/examples/latexusage-3.asy new file mode 100644 index 00000000000..00173cb17ef --- /dev/null +++ b/Master/texmf/doc/asymptote/examples/latexusage-3.asy @@ -0,0 +1,39 @@ +if(!settings.multipleView) settings.batchView=false; +settings.inlinetex=true; +deletepreamble(); +defaultfilename="latexusage-3"; +if(settings.render < 0) settings.render=4; +settings.outformat=""; +settings.inlineimage=true; +settings.embed=true; +settings.toolbar=false; +viewportmargin=(2,2); + +// Global Asymptote definitions can be put here. +import three; +usepackage("bm"); +texpreamble("\def\V#1{\bm{#1}}"); +// One can globally override the default toolbar settings here: +// settings.toolbar=true; + + +pair z0=(0,0); +pair z1=(2,0); +pair z2=(5,0); +pair zf=z1+0.75*(z2-z1); + +draw(z1--z2); +dot(z1,red+0.15cm); +dot(z2,darkgreen+0.3cm); +label("$m$",z1,1.2N,red); +label("$M$",z2,1.5N,darkgreen); +label("$\hat{\ }$",zf,0.2*S,fontsize(24pt)+blue); + +pair s=-0.2*I; +draw("$x$",z0+s--z1+s,N,red,Arrows,Bars,PenMargins); +s=-0.5*I; +draw("$\bar{x}$",z0+s--zf+s,blue,Arrows,Bars,PenMargins); +s=-0.95*I; +draw("$X$",z0+s--z2+s,darkgreen,Arrows,Bars,PenMargins); +size(390.0pt,0,keepAspect=true); +viewportsize=(390.0pt,0); diff --git a/Master/texmf/doc/asymptote/examples/latexusage.tex b/Master/texmf/doc/asymptote/examples/latexusage.tex index ae555a476bd..f3c858348b9 100644 --- a/Master/texmf/doc/asymptote/examples/latexusage.tex +++ b/Master/texmf/doc/asymptote/examples/latexusage.tex @@ -9,14 +9,14 @@ % Use this form with latex or pdflatex to create PDF attachments by default: %\usepackage[attach]{asymptote} -% Enable this line to support PDF hyperlinks: -%\usepackage{hyperref}\hypersetup{setpagesize=false,unicode} - % Enable this line to support the attach option: %\usepackage[dvips]{attachfile2} \begin{document} +% Optional subdirectory for asy files (no spaces): +\def\asydir{} + \begin{asydef} // Global Asymptote definitions can be put here. import three; @@ -81,8 +81,8 @@ and height to \LaTeX\ explicitly. This 3D example can be viewed interactively either with Adobe Reader or Asymptote's fast OpenGL-based renderer. To support {\tt latexmk}, 3D figures should specify \verb+inline=true+. It is sometimes desirable to embed 3D files as annotated -attachments; this requires the optional \verb+\usepackage{attachfile2}+ -package and the \verb+attach=true+ option: +attachments; this requires the \verb+attach=true+ option as well as the +\verb+attachfile2+ \LaTeX\ package. \begin{center} \begin{asy}[height=4cm,inline=true,attach=false] currentprojection=orthographic(5,4,2); diff --git a/Master/texmf/doc/asymptote/examples/orthocenter.asy b/Master/texmf/doc/asymptote/examples/orthocenter.asy index 73dfde51954..5c6807b4f25 100644 --- a/Master/texmf/doc/asymptote/examples/orthocenter.asy +++ b/Master/texmf/doc/asymptote/examples/orthocenter.asy @@ -37,5 +37,4 @@ dot("$A'$",Ap,dir(A--Ap),red); dot("$B'$",Bp,dir(B--Bp),red); dot("$C'$",Cp,dir(C--Cp),red); -label(graphic("piicon.eps","width=2.5cm"),Ap,5ENE,red); - +label(graphic("piicon","width=2.5cm"),Ap,5ENE,red); diff --git a/Master/texmf/doc/asymptote/examples/pdb.asy b/Master/texmf/doc/asymptote/examples/pdb.asy index b4f9175ae14..b3b954c8c6a 100644 --- a/Master/texmf/doc/asymptote/examples/pdb.asy +++ b/Master/texmf/doc/asymptote/examples/pdb.asy @@ -11,6 +11,8 @@ currentlight=White; defaultrender.merge=true; // Fast low-quality rendering //defaultrender.merge=false; // Slow high-quality rendering +bool pixel=false; // Set to true to draw dots as pixels. +real width=10*linewidth(currentpen); size(200); currentprojection=perspective(30,30,15); @@ -126,7 +128,10 @@ for(chain c : chains) { for(int i=0; i < c.a.length-1; ++i) draw(c.a[i].v--c.a[i+1].v,chainpen,currentlight); for(atom a : c.a) - dot(a.v,color(a.name),currentlight); + if(pixel) + pixel(a.v,color(a.name),width); + else + dot(a.v,color(a.name),currentlight); natoms += c.a.length; } endgroup3(); @@ -136,7 +141,10 @@ write("Number of hetero atoms: ",atoms.length); begingroup3("hetero"); for(atom h : atoms) - dot(h.v,color(h.name),currentlight); + if(pixel) + pixel(h.v,color(h.name),width); + else + dot(h.v,color(h.name),currentlight); endgroup3(); write("Number of hetero bonds: ",bonds.length); @@ -154,7 +162,7 @@ string viewfilename=prefix+".views"; if(!error(input(viewfilename,check=false))) options="3Dviews2="+viewfilename; -if(getviews) { +if(getviews && prc()) { picture pic; add(pic,embed("label",currentpicture,options=options),(0,0),N); label(pic,cameralink("label"),(0,0),S,fontsize(12pt)); diff --git a/Master/texmf/doc/asymptote/examples/penfunctionimage.asy b/Master/texmf/doc/asymptote/examples/penfunctionimage.asy new file mode 100644 index 00000000000..38951e550d5 --- /dev/null +++ b/Master/texmf/doc/asymptote/examples/penfunctionimage.asy @@ -0,0 +1,27 @@ +import palette; + +size(200); + +real fracpart(real x) {return (x-floor(x));} + +pair pws(pair z) { + pair w=(z+exp(pi*I/5)/0.9)/(1+z/0.9*exp(-pi*I/5)); + return exp(w)*(w^3-0.5*I); +} + +int N=512; + +pair a=(-1,-1); +pair b=(0.5,0.5); +real dx=(b-a).x/N; +real dy=(b-a).y/N; + +pen f(int u, int v) { + pair z=a+(u*dx,v*dy); + pair w=pws(z); + real phase=degrees(w,warn=false); + real modulus=w == 0 ? 0: fracpart(log(abs(w))); + return hsv(phase,1,sqrt(modulus)); +} + +image(f,N,N,(0,0),(300,300),antialias=true); diff --git a/Master/texmf/doc/asymptote/examples/slidedemo.asy b/Master/texmf/doc/asymptote/examples/slidedemo.asy index 7a753a54d61..0cbd15af741 100644 --- a/Master/texmf/doc/asymptote/examples/slidedemo.asy +++ b/Master/texmf/doc/asymptote/examples/slidedemo.asy @@ -1,6 +1,6 @@ // Slide demo. // Command-line options to enable stepping and/or reverse video: -// asy [-u stepping=true] [-u reverse=true] slidedemo +// asy [-u stepping=true] [-u reverse=true] [-u itemstep=true] slidedemo orientation=Landscape; diff --git a/Master/texmf/doc/asymptote/examples/square.asy b/Master/texmf/doc/asymptote/examples/square.asy index 1bff4e438f5..6fd9d2314d7 100644 --- a/Master/texmf/doc/asymptote/examples/square.asy +++ b/Master/texmf/doc/asymptote/examples/square.asy @@ -1,2 +1,2 @@ -size(100,100); +size(3cm); draw((0,0)--(1,0)--(1,1)--(0,1)--cycle); diff --git a/Master/texmf/doc/asymptote/examples/vertexshading.asy b/Master/texmf/doc/asymptote/examples/vertexshading.asy index 284ca3230de..ea97b98daf3 100644 --- a/Master/texmf/doc/asymptote/examples/vertexshading.asy +++ b/Master/texmf/doc/asymptote/examples/vertexshading.asy @@ -1,5 +1,4 @@ import three; -//settings.prc=false; size(200); diff --git a/Master/texmf/doc/asymptote/examples/worksheet.asy b/Master/texmf/doc/asymptote/examples/worksheet.asy index f26797acabb..9894e5802b8 100644 --- a/Master/texmf/doc/asymptote/examples/worksheet.asy +++ b/Master/texmf/doc/asymptote/examples/worksheet.asy @@ -19,7 +19,7 @@ draw(f,z0--z0+50mm); add(pic,f,z,Align); z += step; -for(int i=1; i <= 14; ++i) { +for(int i=1; i <= 15; ++i) { draw(pic,z--z+length); z += step; draw(pic,z--z+length,dashed+gray); @@ -36,6 +36,7 @@ for(int i=1; i <= 14; ++i) { } else if(i == 12) label(1); else if(i == 13) label(2); + else if(i == 14) label(3); } draw(pic,z--z+length); diff --git a/Master/texmf/doc/asymptote/examples/worldmap.asy b/Master/texmf/doc/asymptote/examples/worldmap.asy new file mode 100644 index 00000000000..59479fffbe2 --- /dev/null +++ b/Master/texmf/doc/asymptote/examples/worldmap.asy @@ -0,0 +1,87 @@ +settings.outformat="pdf";
+size(20cm);
+
+// The required data file is available here:
+// http://www.uni-graz.at/~schwaige/asymptote/worldmap.dat
+// This data was originally obtained from
+// http://www.ngdc.noaa.gov/mgg_coastline/mapit.jsp
+
+real findtheta(real phi, real epsilon=realEpsilon) {
+ // Determine for given phi the unique solution -pi/2 <= theta <= pi/2 off
+ // 2*theta+sin(2*theta)=pi*sin(phi)
+ // in the non-trivial cases by Newton iteration;
+ // theoretically the initial guess pi*sin(phi)/4 always works.
+ real nwtn(real x, real y) {return x-(2x+sin(2x)-y)/(2+2*cos(2x));};
+ real y=pi*sin(phi);
+ if(y == 0) return 0.0;
+ if(abs(y) == 1) return pi/2;
+ real startv=y/4;
+ real endv=nwtn(startv,y);
+ if(epsilon < 500*realEpsilon) epsilon=500*realEpsilon;
+ while(abs(endv-startv) > epsilon) {startv=endv; endv=nwtn(startv,y);};
+ return endv;
+}
+
+pair mollweide(real lambda, real phi, real lambda0=0){
+ // calculate the Mollweide projection centered at lambda0 for the point
+ // with coordinates(phi,lambda)
+ static real c1=2*sqrt(2)/pi;
+ static real c2=sqrt(2);
+ real theta=findtheta(phi);
+ return(c1*(lambda-lambda0)*cos(theta), c2*sin(theta));
+}
+
+guide gfrompairs(pair[] data){
+ guide gtmp;
+ for(int i=0; i < data.length; ++i) {
+ pair tmp=mollweide(radians(data[i].y),radians(data[i].x));
+ gtmp=gtmp--tmp;
+ }
+ return gtmp;
+}
+
+string datafile="worldmap.dat";
+
+file in=input(datafile,comment="/").line();
+// new commentchar since "#" is contained in the file
+pair[][] arrarrpair=new pair[][] ;
+int cnt=-1;
+bool newseg=false;
+while(true) {
+ if(eof(in)) break;
+ string str=in;
+ string[] spstr=split(str,"");
+
+ if(spstr[0] == "#") {++cnt; arrarrpair[cnt]=new pair[] ; newseg=true;}
+ if(spstr[0] != "#" && newseg) {
+ string[] spstr1=split(str,'\t'); // separator is TAB not SPACE
+ pair tmp=((real) spstr1[1],(real) spstr1[0]);
+ arrarrpair[cnt].push(tmp);
+ }
+}
+
+for(int i=0; i < arrarrpair.length; ++i)
+ draw(gfrompairs(arrarrpair[i]),1bp+black);
+
+// lines of longitude and latitude
+pair[] constlong(real lambda, int np=100) {
+ pair[] tmp;
+ for(int i=0; i <= np; ++i) tmp.push((-90+i*180/np,lambda));
+ return tmp;
+}
+
+pair[] constlat(real phi, int np=100) {
+ pair[] tmp;
+ for(int i=0; i <= 2*np; ++i) tmp.push((phi,-180+i*180/np));
+ return tmp;
+}
+
+for(int j=1; j <= 5; ++j) draw(gfrompairs(constlong(-180+j/6*360)),white);
+draw(gfrompairs(constlong(-180)),1.5bp+white);
+draw(gfrompairs(constlong(180)),1.5bp+white);
+for(int j=0; j <= 12; ++j) draw(gfrompairs(constlat(-90+j/6*180)),white);
+//draw(gfrompairs(constlong(10)),dotted);
+
+close(in);
+shipout(bbox(1mm,darkblue,Fill(lightblue)), view=true);
+
diff --git a/Master/texmf/doc/info/asy-faq.info b/Master/texmf/doc/info/asy-faq.info index 059fa578d1a..6fc4b7ce85c 100644 --- a/Master/texmf/doc/info/asy-faq.info +++ b/Master/texmf/doc/info/asy-faq.info @@ -1,15 +1,16 @@ Info file: asy-faq.info, -*-Text-*- produced by bfnnconv.pl from the Bizarre Format With No Name. +INFO-DIR-SECTION Languages START-INFO-DIR-ENTRY * asymptote FAQ: (asy-faq). Asymptote Frequently Asked Questions. END-INFO-DIR-ENTRY -File: $prefix.info, Node: Top, Next: Question 1.1, Up: (dir) +File: asy-faq.info, Node: Top, Next: Question 1.1, Up: (dir) ASYMPTOTE FREQUENTLY ASKED QUESTIONS - 11 Jul 2010 + 26 May 2011 This is the list of Frequently Asked Questions about Asymptote (asy). diff --git a/Master/texmf/doc/info/asymptote.info b/Master/texmf/doc/info/asymptote.info index e72ff70242c..55fbad3858a 100644 --- a/Master/texmf/doc/info/asymptote.info +++ b/Master/texmf/doc/info/asymptote.info @@ -1,7 +1,7 @@ This is asymptote.info, produced by makeinfo version 4.13 from ../asymptote.texi. -This file documents `Asymptote', version 2.02. +This file documents `Asymptote', version 2.10. `http://asymptote.sourceforge.net' @@ -23,7 +23,7 @@ File: asymptote.info, Node: Top, Next: Description, Up: (dir) Asymptote ********* -This file documents `Asymptote', version 2.02. +This file documents `Asymptote', version 2.10. `http://asymptote.sourceforge.net' @@ -347,10 +347,10 @@ file::). `http://www.imagemagick.org/script/binary-releases.php' -is required to support output formats other than EPS and PDF (*note -convert::). The `Python' interpreter from `http://www.python.org' is -only required if you wish to try out the graphical user interface -(*note GUI::). +is required to support output formats other than EPS, PDF, SVG, and PNG +(*note convert::). The `Python' interpreter from +`http://www.python.org' is only required if you wish to try out the +graphical user interface (*note GUI::). Example code will be installed by default in the `examples' subdirectory of the installation directory (by default, `C:\Program @@ -454,7 +454,7 @@ ASYMPTOTE_PSVIEWER="C:\Program Files\Ghostgum\gsview\gsview32.exe"; 2. Right-click on `My Computer'; - 3. Choose `Properties' from the popup menu; + 3. Choose `View system information'; 4. Click the `Advanced' tab; @@ -655,12 +655,14 @@ Desktop `asy' icon (or make `Asymptote' the default application for the extension `asy'). This method, known as _batch mode_, outputs a `PostScript' file -`test.eps'. The `-V' option opens up a `PostScript' viewer window so -you can immediately view the result: +`test.eps'. If you prefer PDF output, use the command line +asy -V -f pdf test + In either case, the `-V' option opens up a viewer window so you can +immediately view the result: -The `--' connector joins the two points `(0,0)' and `(100,100)' with a -line segment. +Here, the `--' connector joins the two points `(0,0)' and `(100,100)' +with a line segment. 3.2 Drawing in interactive mode =============================== @@ -711,7 +713,7 @@ draw((0,0)--(2,1),Arrow); To connect several points and create a cyclic path, use the `cycle' keyword: -size(100,100); +size(3cm); draw((0,0)--(1,0)--(1,1)--(0,1)--cycle); @@ -2893,7 +2895,9 @@ existing data will be preserved, the position will be set to the end-of-file, and both reading and writing operations will be enabled. For security reasons, writing to files in directories other than the current directory is allowed only if the `-globalwrite' (or `-nosafe') -command-line option is specified. +command-line option is specified. The function `string mktemp(string +s)' may be used to create and return the name of a unique temporary +file in the current directory based on the string `s'. There are two special files: `stdin', which reads from the keyboard, and `stdout', which writes to the terminal. The implicit initializer @@ -2914,8 +2918,10 @@ written before the data `x'. An arbitrary number of data values may be listed when writing scalars or one-dimensional arrays. The `suffix' may be one of the following: `none' (do nothing), `flush' (output buffered data), `endl' (terminate with a newline and flush), `newl' (terminate -with a newline), `tab' (terminate with a tab), or `comma' (terminate -with a comma). Here are some simple examples of data output: +with a newline), `DOSendl' (terminate with a DOS newline and flush), +`DOSnewl' (terminate with a DOS newline), `tab' (terminate with a tab), +or `comma' (terminate with a comma). Here are some simple examples of +data output: file fout=output("test.txt"); write(fout,1); // Writes "1" write(fout); // Writes a new line @@ -3654,6 +3660,13 @@ x=3; write(f(4,3)); and outputs 43. + Parameters can be specified as "keyword-only" by putting `keyword' +immediately before the parameter name, as in `int f(int keyword x)' or +`int f(int keyword x=77)'. This forces the caller of the function to +use a named argument to give a value for this parameter. That is, +`f(x=42)' is legal, but `f(25)' is not. Keyword-only parameters must +be listed after normal parameters in a function definition. + As a technical detail, we point out that, since variables of the same name but different signatures are allowed in the same scope, the code int f(int x, int x()) { @@ -3721,6 +3734,15 @@ subtract(... new int[] {10, 1, 2}); ignored for rest formals and the rest argument is not bound to a keyword. + In some cases, keyword-only parameters are helpful to avoid +arguments intended for the rest parameter to be assigned to other +parameters. For example, here the use of `keyword' is to avoid +`pnorm(1.0,2.0,0.3)' matching `1.0' to `p'. +real pnorm(real keyword p=2.0 ... real[] v) +{ + return sum(v^p)^(1/p); +} + The overloading resolution in `Asymptote' is similar to the function matching rules used in C++. Every argument match is given a score. Exact matches score better than matches with casting, and matches with @@ -3961,9 +3983,10 @@ of type `T[]'. arrays). `T[] array(int n, T value, int depth=intMax)' - returns an array consisting of `n' deep copies of a 0, 1, or 2 - dimensional array `T value'. If `depth' is specified, this deep - copying recurses to no more than the number of levels specified. + returns an array consisting of `n' copies of `value'. If `value' + is itself an array, a deep copy of `value' is made for each entry. + If `depth' is specified, this deep copying only recurses to the + specified number of levels. `int[] sequence(int n)' if `n >= 1' returns the array `{0,1,...,n-1}' (otherwise returns a @@ -4642,15 +4665,14 @@ File: asymptote.info, Node: LaTeX usage, Next: Base modules, Prev: Programmin *************** `Asymptote' comes with a convenient `LaTeX' style file `asymptote.sty' -(version 1.15 or later) that makes `LaTeX' `Asymptote'-aware. Entering -`Asymptote' code directly into the `LaTeX' source file, at the point -where it is needed, keeps figures organized and avoids the need to -invent new file names for each figure. Simply add the line -`\usepackage{asymptote}' at the beginning of your file and enclose your -`Asymptote' code within a `\begin{asy}...\end{asy}' environment. As -with the `LaTeX' `comment' environment, the `\end{asy}' command must -appear on a line by itself, with no leading spaces or trailing -commands/comments. +that makes `LaTeX' `Asymptote'-aware. Entering `Asymptote' code +directly into the `LaTeX' source file, at the point where it is needed, +keeps figures organized and avoids the need to invent new file names +for each figure. Simply add the line `\usepackage{asymptote}' at the +beginning of your file and enclose your `Asymptote' code within a +`\begin{asy}...\end{asy}' environment. As with the `LaTeX' `comment' +environment, the `\end{asy}' command must appear on a line by itself, +with no trailing commands/comments. The sample `LaTeX' file below, named `latexusage.tex', can be run as follows: @@ -4662,8 +4684,8 @@ or pdflatex latexusage asy latexusage-*.asy pdflatex latexusage - To switch between using `latex' and `pdflatex' you may first need to -remove the files `latexusage-*', `latexusage.pre', and `latexusage.aux'. + To switch between using inline Asymptote code with `latex' and +`pdflatex' you may first need to remove the files `latexusage-*.tex'. An even better method for processing a `LaTeX' file with embedded `Asymptote' code is to use the `latexmk' utility from @@ -4679,17 +4701,21 @@ in a file `latexmkrc' in the same directory. The command latexmk -pdf latexusage will then call `Asymptote' automatically, recompiling only the figures that have changed. Since each figure is compiled in a separate system -process, this method also tends to use less memory. +process, this method also tends to use less memory. External +`Asymptote' code in `filename.asy' should be included with +\asyinclude[<options>]{<filename.asy>} + so that `latexmk' will recognize when the code is changed. Note that +`latemk' requires `perl', available from `http://www.perl.org/'. - One can specify `width', `height', `viewportwidth', + One can specify `width', `height', `keepAspect', `viewportwidth', `viewportheight', `attach', and `inline'. `keyval'-style options to -the `asy' environment. Three-dimensional PRC files may either be -embedded within the page (the default) or attached as annotated (but -printable) attachments, using the `attach' option and the `attachfile2' -(or older `attachfile') `LaTeX' package. The default value of -`viewportwidth' is `\the\linewidth' for inline 3D figures and `0' for -attachments. The `inline' option generates inline `LaTeX' code instead -of EPS or PDF files. This makes 2D LaTeX symbols visible to the +the `asy' and `asyinclude' environments. Three-dimensional PRC files +may either be embedded within the page (the default) or attached as +annotated (but printable) attachments, using the `attach' option and +the `attachfile2' (or older `attachfile') `LaTeX' package. The default +value of `viewportwidth' is `\the\linewidth' for inline 3D figures and +`0' for attachments. The `inline' option generates inline `LaTeX' code +instead of EPS or PDF files. This makes 2D LaTeX symbols visible to the `\begin{asy}...\end{asy}' environment. In this mode, Asymptote correctly aligns 2D LaTeX symbols defined outside of `\begin{asy}...\end{asy}', but treats their size as zero; an optional @@ -4716,14 +4742,14 @@ option, labels might not show up in DVI viewers that cannot handle raw % Use this form with latex or pdflatex to create PDF attachments by default: %\usepackage[attach]{asymptote} -% Enable this line to support PDF hyperlinks: -%\usepackage{hyperref}\hypersetup{setpagesize=false,unicode} - % Enable this line to support the attach option: %\usepackage[dvips]{attachfile2} \begin{document} +% Optional subdirectory for asy files (no spaces): +\def\asydir{} + \begin{asydef} // Global Asymptote definitions can be put here. import three; @@ -4788,8 +4814,8 @@ and height to \LaTeX\ explicitly. This 3D example can be viewed interactively either with Adobe Reader or Asymptote's fast OpenGL-based renderer. To support {\tt latexmk}, 3D figures should specify \verb+inline=true+. It is sometimes desirable to embed 3D files as annotated -attachments; this requires the optional \verb+\usepackage{attachfile2}+ -package and the \verb+attach=true+ option: +attachments; this requires the \verb+attach=true+ option as well as the +\verb+attachfile2+ \LaTeX\ package. \begin{center} \begin{asy}[height=4cm,inline=true,attach=false] currentprojection=orthographic(5,4,2); @@ -6529,12 +6555,15 @@ palette("$f(x,y)$",range,(0,200),(100,250),Top,Palette, -One can also draw an image directly from a two-dimensional pen array: +One can also draw an image directly from a two-dimensional pen array or +a function `pen f(int, int)': void image(picture pic=currentpicture, pen[][] data, pair initial, pair final, bool transpose=(initial.x < final.x && initial.y < final.y), bool copy=true, bool antialias=false); - as illustrated in the following example: +void image(picture pic=currentpicture, pen f(int, int), int width, int height, + pair initial, pair final, bool antialias=false); + as illustrated in the following examples: size(200); @@ -6552,6 +6581,36 @@ image(v,(0,0),(1,1)); +import palette; + +size(200); + +real fracpart(real x) {return (x-floor(x));} + +pair pws(pair z) { + pair w=(z+exp(pi*I/5)/0.9)/(1+z/0.9*exp(-pi*I/5)); + return exp(w)*(w^3-0.5*I); +} + +int N=512; + +pair a=(-1,-1); +pair b=(0.5,0.5); +real dx=(b-a).x/N; +real dy=(b-a).y/N; + +pen f(int u, int v) { + pair z=a+(u*dx,v*dy); + pair w=pws(z); + real phase=degrees(w,warn=false); + real modulus=w == 0 ? 0: fracpart(log(abs(w))); + return hsv(phase,1,sqrt(modulus)); +} + +image(f,N,N,(0,0),(300,300),antialias=true); + + + For convenience, the module `palette' also defines functions that may be used to construct a pen array from a given function and palette: pen[] palette(real[] f, pen[] palette); @@ -7123,6 +7182,12 @@ illustrated in the example `arrows3.asy'. `BeginDotMargin3', `EndDotMargin3', `DotMargin3', `DotMargins3', `Margin3', and `TrueMargin3'. + The routine +void pixel(picture pic=currentpicture, triple v, pen p=currentpen, + real width=1); + can be used to draw on picture `pic' a pixel of width `width' at +position `v' using pen `p'. + Further three-dimensional examples are provided in the files `near_earth.asy', `conicurv.asy', and (in the `animations' subdirectory) `cube.asy'. @@ -7844,89 +7909,89 @@ Usage: ../asy [options] [file ...] Options (negate by replacing - with -no): --V,-View View output; command-line only --a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C] --antialias n Antialiasing width for rasterized output [2] --arcballradius pixels Arcball radius [750] --auto3D Automatically activate 3D scene [true] --autobillboard 3D labels always face viewer by default [true] --autoimport string Module to automatically import --autoplain Enable automatic importing of plain [true] --autoplay Autoplay 3D animations [false] --autorotate Enable automatic PDF page rotation [false] --batchMask Mask fpu exceptions in batch mode [false] --batchView View output in batch mode [false] --bw Convert all colors to black and white [false] --cd directory Set current directory; command-line only --cmyk Convert rgb colors to cmyk [false] --c,-command string Command to autoexecute --compact Conserve memory at the expense of speed [false] --d,-debug Enable debugging messages [false] --divisor n Garbage collect using purge(divisor=n) [2] --doubleclick ms Emulated double-click timeout [200] --embed Embed rendered preview image [true] --exitonEOF Exit interactive mode on EOF [true] --fitscreen Fit rendered image to screen [true] --framedelay ms Additional frame delay [0] --framerate frames/s Animation speed [30] --globalwrite Allow write to other directory [false] --gray Convert all colors to grayscale [false] --h,-help Show summary of options; command-line only --historylines n Retain n lines of history [1000] --iconify Iconify rendering window [false] --inlineimage Generate inline embedded image [false] --inlinetex Generate inline TeX code [false] --interactiveMask Mask fpu exceptions in interactive mode [true] --interactiveView View output in interactive mode [true] --interactiveWrite Write expressions entered at the prompt to stdout [true] --k,-keep Keep intermediate files [false] --keepaux Keep intermediate LaTeX .aux files [false] --level n Postscript level [3] --l,-listvariables List available global functions and variables [false] --localhistory Use a local interactive history file [false] --loop Loop 3D animations [false] --m,-mask Mask fpu exceptions; command-line only --maxtile pair Maximum rendering tile size [(0,0)] --maxviewport pair Maximum viewport size [(2048,2048)] --multiline Input code over multiple lines at the prompt [false] --multipleView View output from multiple batch-mode files [false] --multisample n Multisampling width for screen images [4] --O,-offset pair PostScript offset [(0,0)] --f,-outformat format Convert each output file to specified format --o,-outname name Alternative output directory/filename --p,-parseonly Parse file [false] --pdfreload Automatically reload document in pdfviewer [false] --pdfreloaddelay usec Delay before attempting initial pdf reload [750000] --position pair Initial 3D rendering screen position [(0,0)] --prc Embed 3D PRC graphics in PDF output [true] --prompt string Prompt [> ] --prompt2 string Continuation prompt for multiline input [..] --q,-quiet Suppress welcome message [false] --render n Render 3D graphics using n pixels per bp (-1=auto) [-1] --resizestep step Resize step [1.2] --reverse reverse 3D animations [false] --rgb Convert cmyk colors to rgb [false] --safe Disable system call [true] --scroll n Scroll standard output n lines at a time [0] --spinstep deg/s Spin speed [60] --svgemulation Emulate unimplemented SVG shading [false] --tabcompletion Interactive prompt auto-completion [true] --tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex] --thick Render thick 3D lines [true] --thin Render thin 3D lines [true] --threads Use POSIX threads for 3D rendering [true] --toolbar Show 3D toolbar in PDF output [true] --s,-translate Show translated virtual machine code [false] --twice Run LaTeX twice (to resolve references) [false] --twosided Use two-sided 3D lighting model for rendering [true] --u,-user string General purpose user string --v,-verbose Increase verbosity level (can specify multiple times) [0] --version Show version; command-line only --wait Wait for child processes to finish before exiting [false] --warn string Enable warning; command-line only --where Show where listed variables are declared [false] --zoomfactor factor Zoom step factor [1.05] --zoomstep step Mouse motion zoom step [0.1] +-V,-View View output; command-line only +-a,-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C] +-antialias n Antialiasing width for rasterized output [2] +-arcballradius pixels Arcball radius [750] +-auto3D Automatically activate 3D scene [true] +-autobillboard 3D labels always face viewer by default [true] +-autoimport string Module to automatically import +-autoplain Enable automatic importing of plain [true] +-autoplay Autoplay 3D animations [false] +-autorotate Enable automatic PDF page rotation [false] +-batchMask Mask fpu exceptions in batch mode [false] +-batchView View output in batch mode [false] +-bw Convert all colors to black and white [false] +-cd directory Set current directory; command-line only +-cmyk Convert rgb colors to cmyk [false] +-c,-command string Command to autoexecute +-compact Conserve memory at the expense of speed [false] +-d,-debug Enable debugging messages [false] +-divisor n Garbage collect using purge(divisor=n) [2] +-doubleclick ms Emulated double-click timeout [200] +-embed Embed rendered preview image [true] +-exitonEOF Exit interactive mode on EOF [true] +-fitscreen Fit rendered image to screen [true] +-framedelay ms Additional frame delay [0] +-framerate frames/s Animation speed [30] +-globalwrite Allow write to other directory [false] +-gray Convert all colors to grayscale [false] +-h,-help Show summary of options; command-line only +-historylines n Retain n lines of history [1000] +-iconify Iconify rendering window [false] +-inlineimage Generate inline embedded image [false] +-inlinetex Generate inline TeX code [false] +-interactiveMask Mask fpu exceptions in interactive mode [true] +-interactiveView View output in interactive mode [true] +-interactiveWrite Write expressions entered at the prompt to stdout [true] +-k,-keep Keep intermediate files [false] +-keepaux Keep intermediate LaTeX .aux files [false] +-level n Postscript level [3] +-l,-listvariables List available global functions and variables [false] +-localhistory Use a local interactive history file [false] +-loop Loop 3D animations [false] +-m,-mask Mask fpu exceptions; command-line only +-maxtile pair Maximum rendering tile size [(0,0)] +-maxviewport pair Maximum viewport size [(2048,2048)] +-multiline Input code over multiple lines at the prompt [false] +-multipleView View output from multiple batch-mode files [false] +-multisample n Multisampling width for screen images [4] +-O,-offset pair PostScript offset [(0,0)] +-f,-outformat format Convert each output file to specified format +-o,-outname name Alternative output directory/filename +-p,-parseonly Parse file [false] +-pdfreload Automatically reload document in pdfviewer [false] +-pdfreloaddelay usec Delay before attempting initial pdf reload [750000] +-position pair Initial 3D rendering screen position [(0,0)] +-prc Embed 3D PRC graphics in PDF output [true] +-prompt string Prompt [> ] +-prompt2 string Continuation prompt for multiline input [..] +-q,-quiet Suppress welcome message [false] +-render n Render 3D graphics using n pixels per bp (-1=auto) [-1] +-resizestep step Resize step [1.2] +-reverse reverse 3D animations [false] +-rgb Convert cmyk colors to rgb [false] +-safe Disable system call [true] +-scroll n Scroll standard output n lines at a time [0] +-spinstep deg/s Spin speed [60] +-svgemulation Emulate unimplemented SVG shading [false] +-tabcompletion Interactive prompt auto-completion [true] +-tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex] +-thick Render thick 3D lines [true] +-thin Render thin 3D lines [true] +-threads Use POSIX threads for 3D rendering [true] +-toolbar Show 3D toolbar in PDF output [true] +-s,-translate Show translated virtual machine code [false] +-twice Run LaTeX twice (to resolve references) [false] +-twosided Use two-sided 3D lighting model for rendering [true] +-u,-user string General purpose user string +-v,-verbose Increase verbosity level (can specify multiple times) [0] +-version Show version; command-line only +-wait Wait for child processes to finish before exiting [false] +-warn string Enable warning; command-line only +-where Show where listed variables are declared [false] +-zoomfactor factor Zoom step factor [1.05] +-zoomstep step Mouse motion zoom step [0.1] All boolean options can be negated by prepending `no' to the option name. @@ -8397,7 +8462,7 @@ Index (line 14) * -- <1>: Self & prefix operators. (line 6) -* --: Tutorial. (line 125) +* --: Tutorial. (line 127) * ---: Bezier curves. (line 83) * -=: Self & prefix operators. (line 6) @@ -8406,7 +8471,7 @@ Index * -u: Options. (line 183) * -V <1>: Tutorial. (line 19) * -V: Configuring. (line 6) -* ..: Tutorial. (line 125) +* ..: Tutorial. (line 127) * .asy: Search paths. (line 13) * /: Arithmetic & logical. (line 20) @@ -8415,7 +8480,7 @@ Index * 2D graphs: graph. (line 6) * 3D graphs: graph3. (line 6) * 3D grids: grid3. (line 6) -* 3D PostScript: three. (line 570) +* 3D PostScript: three. (line 576) * 3D rendering: Compiling from UNIX source. (line 16) * :: Arithmetic & logical. @@ -8438,7 +8503,7 @@ Index (line 28) * ^=: Self & prefix operators. (line 6) -* ^^: Tutorial. (line 132) +* ^^: Tutorial. (line 134) * a4: Configuring. (line 61) * abort: Data types. (line 322) * abs <1>: Mathematical functions. @@ -8464,18 +8529,18 @@ Index (line 48) * Airy: Mathematical functions. (line 48) -* alias <1>: Arrays. (line 186) +* alias <1>: Arrays. (line 187) * alias: Structures. (line 52) * align: Options. (line 167) * Align: label. (line 12) -* all: Arrays. (line 334) +* all: Arrays. (line 335) * Allow: Pens. (line 327) * AND: Arithmetic & logical. (line 80) * and: Bezier curves. (line 56) * angle: Data types. (line 68) * animate <1>: animation. (line 12) -* animate <2>: Files. (line 150) +* animate <2>: Files. (line 154) * animate: Configuring. (line 67) * animation: animation. (line 6) * annotate: annotate. (line 6) @@ -8505,7 +8570,7 @@ Index * arrow: label. (line 72) * Arrow: draw. (line 26) * arrow: Drawing commands. (line 31) -* arrow keys: Tutorial. (line 35) +* arrow keys: Tutorial. (line 37) * Arrow3: three. (line 543) * Arrows: draw. (line 26) * arrows: draw. (line 26) @@ -8523,6 +8588,7 @@ Index * asy: Import. (line 102) * asy-mode: Editing modes. (line 6) * asy.vim: Editing modes. (line 33) +* asyinclude: LaTeX usage. (line 44) * asymptote.sty: LaTeX usage. (line 6) * asymptote.xml: Editing modes. (line 49) * ASYMPTOTE_CONFIG: Options. (line 114) @@ -8536,7 +8602,7 @@ Index (line 6) * atleast: Bezier curves. (line 56) * attach <1>: graph. (line 415) -* attach: LaTeX usage. (line 46) +* attach: LaTeX usage. (line 49) * autoadjust: three. (line 354) * autoimport: Options. (line 110) * automatic scaling: graph. (line 682) @@ -8582,11 +8648,11 @@ Index * Bi_deriv: Mathematical functions. (line 48) * Billboard: three. (line 472) -* binary format: Files. (line 70) +* binary format: Files. (line 74) * binary operators: Arithmetic & logical. (line 6) * binarytree: binarytree. (line 6) -* binput: Files. (line 70) +* binput: Files. (line 74) * black stripes: three. (line 210) * Blank: draw. (line 26) * block.bottom: flowchart. (line 19) @@ -8609,10 +8675,10 @@ Index * BottomView: three. (line 381) * bounding box: Frames and pictures. (line 168) * Bounds: graph3. (line 20) -* boutput: Files. (line 70) +* boutput: Files. (line 74) * box <1>: three. (line 305) * box: Frames and pictures. (line 22) -* bp: Tutorial. (line 24) +* bp: Tutorial. (line 26) * break: Programming. (line 29) * breakpoints: Debugger. (line 21) * brick: Pens. (line 251) @@ -8648,11 +8714,11 @@ Index * CJK: unicode. (line 12) * clamped: graph. (line 37) * clear <1>: Debugger. (line 23) -* clear: Files. (line 88) +* clear: Files. (line 92) * clip: fill. (line 111) * CLZ: Arithmetic & logical. (line 80) -* cm: Tutorial. (line 61) +* cm: Tutorial. (line 63) * cmd: Configuring. (line 34) * cmyk: Pens. (line 34) * colatitude: Data types. (line 129) @@ -8662,16 +8728,16 @@ Index * coloredSegments: tube. (line 25) * colorless: Pens. (line 54) * colors: Pens. (line 51) -* comma: Files. (line 58) -* comma-separated-value mode: Arrays. (line 367) +* comma: Files. (line 60) +* comma-separated-value mode: Arrays. (line 368) * command-line options <1>: Options. (line 6) * command-line options: Configuring. (line 83) * comment character: Files. (line 15) -* compass directions: Tutorial. (line 104) +* compass directions: Tutorial. (line 106) * Compiling from UNIX source: Compiling from UNIX source. (line 6) -* complement: Arrays. (line 149) -* concat: Arrays. (line 182) +* complement: Arrays. (line 150) +* concat: Arrays. (line 183) * conditional <1>: Arithmetic & logical. (line 73) * conditional: Programming. (line 8) @@ -8691,11 +8757,11 @@ Index * controlSpecifier: Paths and guides. (line 379) * convert <1>: Options. (line 142) * convert <2>: animation. (line 6) -* convert <3>: Files. (line 150) +* convert <3>: Files. (line 154) * convert: Configuring. (line 67) * convertOptions: Options. (line 129) * Coons shading: fill. (line 74) -* copy: Arrays. (line 173) +* copy: Arrays. (line 174) * Cos: Mathematical functions. (line 20) * cos: Mathematical functions. @@ -8709,10 +8775,10 @@ Index * cross: Data types. (line 167) * crossframe: markers. (line 23) * crosshatch: Pens. (line 267) -* csv: Arrays. (line 367) +* csv: Arrays. (line 368) * CTZ: Arithmetic & logical. (line 80) -* cubicroots: Arrays. (line 323) +* cubicroots: Arrays. (line 324) * curl <1>: three. (line 6) * curl: Bezier curves. (line 63) * curlSpecifier: Paths and guides. (line 391) @@ -8724,7 +8790,7 @@ Index * custom tick locations: graph. (line 249) * cut: Paths and guides. (line 237) * cycle <1>: three. (line 6) -* cycle: Tutorial. (line 73) +* cycle: Tutorial. (line 75) * cyclic <1>: three. (line 502) * cyclic <2>: Arrays. (line 39) * cyclic: Paths and guides. (line 74) @@ -8751,11 +8817,11 @@ Index (line 17) * degrees: Data types. (line 73) * delete <1>: Arrays. (line 39) -* delete: Files. (line 145) +* delete: Files. (line 149) * description: Description. (line 6) -* diagonal: Arrays. (line 308) +* diagonal: Arrays. (line 309) * diamond: flowchart. (line 57) -* dimension: Arrays. (line 372) +* dimension: Arrays. (line 373) * dir <1>: three. (line 502) * dir <2>: Paths and guides. (line 98) * dir <3>: Data types. (line 85) @@ -8766,7 +8832,9 @@ Index * dirtime: Paths and guides. (line 152) * display: Configuring. (line 67) * do: Programming. (line 29) -* dot <1>: Arrays. (line 264) +* DOSendl: Files. (line 60) +* DOSnewl: Files. (line 60) +* dot <1>: Arrays. (line 265) * dot <2>: Data types. (line 98) * dot: draw. (line 83) * DotMargin: draw. (line 42) @@ -8775,7 +8843,7 @@ Index * DotMargins3: three. (line 559) * dotted: Pens. (line 95) * double deferred drawing: three. (line 256) -* double precision: Files. (line 70) +* double precision: Files. (line 74) * Draw: Frames and pictures. (line 147) * draw: draw. (line 110) * Draw: draw. (line 26) @@ -8788,7 +8856,7 @@ Index * dvisvgm: Configuring. (line 67) * E <1>: Mathematical functions. (line 48) -* E: Tutorial. (line 104) +* E: Tutorial. (line 106) * Editing modes: Editing modes. (line 6) * Ei: Mathematical functions. (line 48) @@ -8809,7 +8877,7 @@ Index * EndBar3: three. (line 543) * EndDotMargin: draw. (line 42) * EndDotMargin3: three. (line 559) -* endl: Files. (line 58) +* endl: Files. (line 60) * EndMargin: draw. (line 42) * EndMargin3: three. (line 559) * EndPenMargin: draw. (line 42) @@ -8818,15 +8886,15 @@ Index * EndPoint: label. (line 57) * envelope: Frames and pictures. (line 22) * environment variables: Configuring. (line 87) -* eof <1>: Arrays. (line 349) -* eof: Files. (line 88) -* eol <1>: Arrays. (line 349) -* eol: Files. (line 88) +* eof <1>: Arrays. (line 350) +* eof: Files. (line 92) +* eol <1>: Arrays. (line 350) +* eol: Files. (line 92) * EPS <1>: Options. (line 142) * EPS: label. (line 80) * erase <1>: Frames and pictures. (line 7) * erase <2>: Data types. (line 239) -* erase: Tutorial. (line 35) +* erase: Tutorial. (line 37) * erf: Mathematical functions. (line 6) * erfc: Mathematical functions. @@ -8836,7 +8904,7 @@ Index * errorbars: graph. (line 484) * eval: Import. (line 98) * evenodd <1>: Pens. (line 152) -* evenodd: Tutorial. (line 146) +* evenodd: Tutorial. (line 148) * exit <1>: Debugger. (line 57) * exit <2>: Interactive mode. (line 59) * exit: Data types. (line 331) @@ -8858,14 +8926,14 @@ Index (line 48) * fabs: Mathematical functions. (line 6) -* face: three. (line 578) +* face: three. (line 584) * factorial: Mathematical functions. (line 39) * Fedora: UNIX binary distributions. (line 15) * feynman: feynman. (line 6) * fft <1>: math. (line 26) -* fft: Arrays. (line 251) +* fft: Arrays. (line 252) * FFTW: Compiling from UNIX source. (line 58) * file <1>: Debugger. (line 45) @@ -8879,7 +8947,7 @@ Index * FillDraw: draw. (line 26) * filloutside: fill. (line 27) * fillrule: Pens. (line 152) -* find <1>: Arrays. (line 158) +* find <1>: Arrays. (line 159) * find: Data types. (line 224) * firstcut: Paths and guides. (line 247) * fit: Frames and pictures. (line 103) @@ -8888,7 +8956,7 @@ Index * floor: Mathematical functions. (line 26) * flowchart: flowchart. (line 6) -* flush: Files. (line 58) +* flush: Files. (line 60) * fmod: Mathematical functions. (line 6) * font: Pens. (line 192) @@ -8917,10 +8985,10 @@ Index (line 39) * geometry: geometry. (line 6) * getc: Files. (line 29) -* getpair: Files. (line 113) -* getreal: Files. (line 113) -* getstring: Files. (line 113) -* gettriple: Files. (line 113) +* getpair: Files. (line 117) +* getreal: Files. (line 117) +* getstring: Files. (line 117) +* gettriple: Files. (line 117) * glOptions <1>: Options. (line 129) * glOptions: three. (line 210) * GNU Scientific Library: Mathematical functions. @@ -8950,7 +9018,7 @@ Index * guide: Paths and guides. (line 300) * guide3: three. (line 6) * hatch: Pens. (line 267) -* height: LaTeX usage. (line 46) +* height: LaTeX usage. (line 49) * help <1>: Debugger. (line 30) * help <2>: Help. (line 6) * help: Interactive mode. (line 44) @@ -8960,11 +9028,11 @@ Index * hex: Data types. (line 280) * hexidecimal <1>: Pens. (line 59) * hexidecimal: Data types. (line 280) -* hidden surface removal: three. (line 578) +* hidden surface removal: three. (line 584) * histogram: Mathematical functions. (line 39) * history <1>: Interactive mode. (line 59) -* history: Files. (line 138) +* history: Files. (line 142) * historylines: Interactive mode. (line 64) * HookHead: draw. (line 26) * HookHead3: three. (line 543) @@ -8977,7 +9045,7 @@ Index * i_scaled: Mathematical functions. (line 48) * iconic: three. (line 210) -* identity <1>: Arrays. (line 305) +* identity <1>: Arrays. (line 306) * identity <2>: Mathematical functions. (line 6) * identity: Transforms. (line 24) @@ -8993,14 +9061,14 @@ Index * implicit linear solver: MetaPost. (line 10) * implicit scaling: Implicit scaling. (line 6) * import: Import. (line 46) -* inches: Tutorial. (line 61) +* inches: Tutorial. (line 63) * including images: label. (line 80) * increasing: math. (line 59) * inheritance: Structures. (line 181) * initialized: Arrays. (line 39) * initializers: Variable initializers. (line 6) -* inline: LaTeX usage. (line 46) +* inline: LaTeX usage. (line 49) * InOutTicks: graph3. (line 34) * input <1>: Interactive mode. (line 48) * input: Files. (line 11) @@ -9031,7 +9099,7 @@ Index * InTicks: graph3. (line 34) * intMax: Data types. (line 28) * intMin: Data types. (line 28) -* inverse <1>: Arrays. (line 311) +* inverse <1>: Arrays. (line 312) * inverse: Transforms. (line 16) * invert: three. (line 422) * invisible: Pens. (line 39) @@ -9044,8 +9112,12 @@ Index (line 48) * Kate: Editing modes. (line 49) * KDE editor: Editing modes. (line 49) +* keepAspect <1>: LaTeX usage. (line 49) +* keepAspect: Frames and pictures. (line 54) * keyboard bindings:: three. (line 169) * keys: Arrays. (line 39) +* keyword: Named arguments. (line 37) +* keyword-only: Named arguments. (line 37) * keywords: Named arguments. (line 6) * Korean: unicode. (line 12) * label: three. (line 466) @@ -9063,7 +9135,7 @@ Index * latex: Options. (line 142) * LaTeX fonts: Pens. (line 192) * LaTeX usage: LaTeX usage. (line 6) -* latexmk: LaTeX usage. (line 30) +* latexmk: LaTeX usage. (line 29) * latin1: latin1. (line 6) * latitude: Data types. (line 134) * latticeshade: fill. (line 32) @@ -9091,8 +9163,8 @@ Index * libsigsegv <1>: Help. (line 33) * libsigsegv: Functions. (line 88) * limits: graph. (line 636) -* line: Arrays. (line 349) -* line mode: Arrays. (line 349) +* line: Arrays. (line 350) +* line mode: Arrays. (line 350) * Linear: graph. (line 682) * linecap: Pens. (line 129) * linejoin: Pens. (line 138) @@ -9119,7 +9191,7 @@ Index * MacOS X binary distributions: MacOS X binary distributions. (line 6) * makepen: Pens. (line 300) -* map: Arrays. (line 140) +* map: Arrays. (line 141) * Margin: draw. (line 42) * Margin3: three. (line 559) * margins: three. (line 262) @@ -9135,7 +9207,7 @@ Index * mathematical functions: Mathematical functions. (line 6) * max <1>: three. (line 502) -* max <2>: Arrays. (line 230) +* max <2>: Arrays. (line 231) * max <3>: Frames and pictures. (line 7) * max: Paths and guides. (line 264) * maxbound: Data types. (line 104) @@ -9156,7 +9228,7 @@ Index * midpoint: Paths and guides. (line 166) * MidPoint: label. (line 57) * min <1>: three. (line 502) -* min <2>: Arrays. (line 223) +* min <2>: Arrays. (line 224) * min <3>: Frames and pictures. (line 7) * min: Paths and guides. (line 260) * minbound: Data types. (line 101) @@ -9164,8 +9236,9 @@ Index * mintimes: Paths and guides. (line 214) * miterjoin: Pens. (line 138) * miterlimit: Pens. (line 147) -* mm: Tutorial. (line 61) -* mode: Files. (line 84) +* mktemp: Files. (line 43) +* mm: Tutorial. (line 63) +* mode: Files. (line 88) * monotonic: graph. (line 37) * mouse: GUI. (line 6) * mouse bindings: three. (line 137) @@ -9174,14 +9247,14 @@ Index * multisample: three. (line 127) * multisampling: Compiling from UNIX source. (line 16) -* N: Tutorial. (line 104) -* name: Files. (line 84) +* N: Tutorial. (line 106) +* name: Files. (line 88) * named arguments: Named arguments. (line 6) * natural: graph. (line 37) * new <1>: Arrays. (line 109) * new: Structures. (line 6) * newframe: Frames and pictures. (line 7) -* newl: Files. (line 58) +* newl: Files. (line 60) * newton: Mathematical functions. (line 65) * next: Debugger. (line 42) @@ -9191,7 +9264,7 @@ Index * NoFill: draw. (line 26) * NoMargin: draw. (line 42) * NoMargin3: three. (line 559) -* none: Files. (line 58) +* none: Files. (line 60) * None: draw. (line 19) * normal: three. (line 488) * nosafe: Options. (line 162) @@ -9247,8 +9320,8 @@ Index * pack: label. (line 102) * packing: Rest arguments. (line 30) * pair <1>: Data types. (line 41) -* pair: Tutorial. (line 49) -* pairs: Arrays. (line 247) +* pair: Tutorial. (line 51) +* pairs: Arrays. (line 248) * paperheight: Configuring. (line 61) * papertype: Configuring. (line 61) * paperwidth: Configuring. (line 61) @@ -9262,7 +9335,7 @@ Index * path: Paths and guides. (line 7) * path markers: graph. (line 484) * path3: three. (line 6) -* path[]: Tutorial. (line 132) +* path[]: Tutorial. (line 134) * patterns <1>: patterns. (line 6) * patterns: Pens. (line 238) * PDF: Options. (line 142) @@ -9277,11 +9350,13 @@ Index * PenMargins2: three. (line 559) * PenMargins3: three. (line 559) * periodic: graph. (line 37) +* perl: LaTeX usage. (line 29) * perpendicular: geometry. (line 6) * perspective: three. (line 358) * picture: Frames and pictures. (line 35) * picture alignment: Frames and pictures. (line 209) * piecewisestraight: Paths and guides. (line 81) +* pixel: three. (line 566) * Pl: Mathematical functions. (line 48) * plain: plain. (line 6) @@ -9301,11 +9376,11 @@ Index (line 19) * postscript: Frames and pictures. (line 271) * PostScript fonts: Pens. (line 210) -* PostScript subpath: Tutorial. (line 132) +* PostScript subpath: Tutorial. (line 134) * pow10: Mathematical functions. (line 6) * prc: three. (line 231) -* precision: Files. (line 88) +* precision: Files. (line 92) * precontrol <1>: three. (line 502) * precontrol: Paths and guides. (line 128) * prefix operators: Self & prefix operators. @@ -9317,15 +9392,15 @@ Index * psview: Microsoft Windows. (line 16) * psviewer: Configuring. (line 6) * psviewerOptions: Options. (line 129) -* pt: Tutorial. (line 61) +* pt: Tutorial. (line 63) * public: Structures. (line 6) * push: Arrays. (line 39) * Python usage: Interactive mode. (line 80) -* quadraticroots: Arrays. (line 314) +* quadraticroots: Arrays. (line 315) * quarticroots: math. (line 22) * quit <1>: Debugger. (line 54) * quit <2>: Interactive mode. (line 59) -* quit: Tutorial. (line 35) +* quit: Tutorial. (line 37) * quote: Import. (line 116) * quotient: Arithmetic & logical. (line 6) @@ -9341,10 +9416,10 @@ Index (line 39) * randMax: Mathematical functions. (line 39) -* read: Arrays. (line 390) +* read: Arrays. (line 391) * reading: Files. (line 11) -* reading string arrays: Arrays. (line 359) -* readline: Files. (line 130) +* reading string arrays: Arrays. (line 360) +* readline: Files. (line 134) * real: Data types. (line 33) * realDigits: Data types. (line 33) * realEpsilon: Data types. (line 33) @@ -9359,7 +9434,7 @@ Index * reltime: Paths and guides. (line 158) * remainder: Mathematical functions. (line 6) -* rename: Files. (line 147) +* rename: Files. (line 151) * render <1>: Options. (line 142) * render: three. (line 47) * replace: Data types. (line 252) @@ -9369,10 +9444,10 @@ Index * restricted: Structures. (line 6) * return: Debugger. (line 48) * reverse <1>: three. (line 502) -* reverse <2>: Arrays. (line 145) +* reverse <2>: Arrays. (line 146) * reverse <3>: Paths and guides. (line 169) * reverse: Data types. (line 248) -* rewind: Files. (line 88) +* rewind: Files. (line 92) * rfind: Data types. (line 229) * rgb: Pens. (line 30) * Riemann zeta function: Mathematical functions. @@ -9394,10 +9469,10 @@ Index (line 6) * runtime imports: Import. (line 98) * Russian: unicode. (line 7) -* S: Tutorial. (line 104) +* S: Tutorial. (line 106) * safe: Options. (line 162) * save: Frames and pictures. (line 262) -* saveline: Files. (line 130) +* saveline: Files. (line 134) * scale: three. (line 452) * Scale: graph. (line 698) * scale <1>: graph. (line 682) @@ -9407,21 +9482,21 @@ Index * scale3: three. (line 449) * scaled graph: graph. (line 663) * scientific graph: graph. (line 396) -* scroll: Files. (line 104) -* search: Arrays. (line 163) +* scroll: Files. (line 108) +* search: Arrays. (line 164) * search paths: Search paths. (line 6) * Seascape: Frames and pictures. (line 100) * secondary axis: graph. (line 813) * secondaryX: graph. (line 813) * secondaryY: graph. (line 813) * seconds: Data types. (line 300) -* seek: Files. (line 88) -* seekeof: Files. (line 88) +* seek: Files. (line 92) +* seekeof: Files. (line 92) * segment: math. (line 50) * segmentation fault: Help. (line 33) * self operators: Self & prefix operators. (line 6) -* sequence: Arrays. (line 127) +* sequence: Arrays. (line 128) * settings <1>: Options. (line 114) * settings: Configuring. (line 23) * sgn: Mathematical functions. @@ -9435,7 +9510,7 @@ Index * showtarget: three. (line 338) * Si: Mathematical functions. (line 48) -* signedint: Files. (line 70) +* signedint: Files. (line 74) * SimpleHead: draw. (line 26) * simplex: simplex. (line 6) * simpson: Mathematical functions. @@ -9444,9 +9519,9 @@ Index (line 20) * sin: Mathematical functions. (line 6) -* single precision: Files. (line 70) -* singleint: Files. (line 70) -* singlereal: Files. (line 70) +* single precision: Files. (line 74) +* singleint: Files. (line 74) +* singlereal: Files. (line 74) * sinh: Mathematical functions. (line 6) * SixViews: three. (line 396) @@ -9467,8 +9542,8 @@ Index * slopefield: slopefield. (line 6) * solid: Pens. (line 95) * solids: solids. (line 9) -* solve: Arrays. (line 283) -* sort: Arrays. (line 189) +* solve: Arrays. (line 284) +* sort: Arrays. (line 190) * Spline <1>: graph3. (line 100) * Spline: graph. (line 34) * split: Data types. (line 261) @@ -9481,8 +9556,8 @@ Index * stack overflow: Functions. (line 88) * static: Static. (line 6) * stats: stats. (line 6) -* stdin: Files. (line 45) -* stdout: Files. (line 45) +* stdin: Files. (line 47) +* stdout: Files. (line 47) * step: Debugger. (line 39) * stickframe: markers. (line 16) * stop: Debugger. (line 10) @@ -9501,8 +9576,8 @@ Index * subpictures: Frames and pictures. (line 103) * substr: Data types. (line 244) * Subversion: Subversion. (line 6) -* sum: Arrays. (line 218) -* superpath: Tutorial. (line 132) +* sum: Arrays. (line 219) +* superpath: Tutorial. (line 134) * Suppress: Pens. (line 331) * SuppressQuiet: Pens. (line 335) * surface <1>: graph3. (line 100) @@ -9510,10 +9585,10 @@ Index * SVG: Options. (line 142) * SVN: Subversion. (line 6) * system <1>: Options. (line 162) -* system: Files. (line 155) +* system: Files. (line 159) * syzygy: syzygy. (line 6) -* tab: Files. (line 58) -* tab completion: Tutorial. (line 35) +* tab: Files. (line 60) +* tab completion: Tutorial. (line 37) * Tan: Mathematical functions. (line 20) * tan: Mathematical functions. @@ -9521,7 +9596,7 @@ Index * tanh: Mathematical functions. (line 6) * target: three. (line 338) -* tell: Files. (line 88) +* tell: Files. (line 92) * tension <1>: three. (line 6) * tension: Bezier curves. (line 56) * tensionSpecifier: Paths and guides. (line 385) @@ -9565,12 +9640,12 @@ Index * transform: Transforms. (line 6) * transform3: three. (line 432) * transparency: Pens. (line 222) -* transpose: Arrays. (line 210) +* transpose: Arrays. (line 211) * tree: tree. (line 9) * trembling: trembling. (line 6) * triangle: geometry. (line 6) * triangulate: contour. (line 157) -* tridiagonal: Arrays. (line 271) +* tridiagonal: Arrays. (line 272) * trigonometric integrals: Mathematical functions. (line 48) * triple: Data types. (line 108) @@ -9588,18 +9663,18 @@ Index * unfill: fill. (line 106) * UnFill: draw. (line 26) * unicode: unicode. (line 6) -* uniform: Arrays. (line 154) +* uniform: Arrays. (line 155) * Uninstall: Uninstall. (line 6) * unique: math. (line 64) * unit: Data types. (line 78) * unitbox <1>: three. (line 307) -* unitbox: Tutorial. (line 153) +* unitbox: Tutorial. (line 155) * unitcircle <1>: three. (line 274) -* unitcircle: Tutorial. (line 126) +* unitcircle: Tutorial. (line 128) * unitrand: Mathematical functions. (line 39) * unitsize <1>: Frames and pictures. (line 64) -* unitsize: Tutorial. (line 84) +* unitsize: Tutorial. (line 86) * UNIX binary distributions: UNIX binary distributions. (line 6) * unpacking: Rest arguments. (line 39) @@ -9608,7 +9683,7 @@ Index * update: Files. (line 35) * UpsideDown: Frames and pictures. (line 95) * usepackage: Frames and pictures. (line 291) -* user coordinates: Tutorial. (line 84) +* user coordinates: Tutorial. (line 86) * user-defined operators: User-defined operators. (line 6) * usleep: Data types. (line 337) @@ -9619,29 +9694,29 @@ Index (line 6) * vectorfield: graph. (line 975) * vectorfield3: graph3. (line 159) -* vectorization: Arrays. (line 328) +* vectorization: Arrays. (line 329) * verbatim: Frames and pictures. (line 271) * vertex-dependent colors: three. (line 81) * Vertical: flowchart. (line 81) -* viewportheight: LaTeX usage. (line 46) +* viewportheight: LaTeX usage. (line 49) * viewportmargin: three. (line 262) * viewportsize: three. (line 262) -* viewportwidth: LaTeX usage. (line 46) +* viewportwidth: LaTeX usage. (line 49) * views: three. (line 231) * vim: Editing modes. (line 33) * virtual functions: Structures. (line 181) * void: Data types. (line 10) -* W: Tutorial. (line 104) +* W: Tutorial. (line 106) * whatever: Paths and guides. (line 232) * Wheel: palette. (line 22) * wheel mouse: GUI. (line 6) * while: Programming. (line 29) -* white-space string delimiter mode: Arrays. (line 359) -* width: LaTeX usage. (line 46) +* white-space string delimiter mode: Arrays. (line 360) +* width: LaTeX usage. (line 49) * windingnumber: Paths and guides. (line 268) -* word: Arrays. (line 359) -* write <1>: Arrays. (line 399) -* write: Files. (line 50) +* word: Arrays. (line 360) +* write <1>: Arrays. (line 400) +* write: Files. (line 52) * X: three. (line 274) * xasy: GUI. (line 6) * xaxis3: graph3. (line 7) @@ -9649,11 +9724,11 @@ Index * xelatex: embed. (line 10) * xequals: graph. (line 294) * XEquals: graph. (line 280) -* xinput: Files. (line 70) +* xinput: Files. (line 74) * xlimits: graph. (line 636) * XOR: Arithmetic & logical. (line 80) -* xoutput: Files. (line 70) +* xoutput: Files. (line 74) * xpart: Data types. (line 89) * xscale: Transforms. (line 33) * xscale3: three. (line 440) @@ -9714,139 +9789,140 @@ Node: UNIX binary distributions11388 Node: MacOS X binary distributions12494 Node: Microsoft Windows13378 Ref: psview14088 -Node: Configuring15009 -Node: Search paths19230 -Node: Compiling from UNIX source20027 -Ref: multisampling20616 -Node: Editing modes23022 -Node: Subversion25454 -Node: Uninstall25917 -Node: Tutorial26267 -Ref: unitcircle30493 -Node: Drawing commands32429 -Node: draw34140 -Ref: arrows35288 -Node: fill40531 -Ref: gradient shading41575 -Node: clip45803 -Node: label46395 -Ref: Label47094 -Node: Bezier curves52819 -Node: Programming56396 -Ref: array iteration57210 -Node: Data types58291 -Ref: format67299 -Node: Paths and guides70902 -Ref: circle71156 -Ref: arctime76644 -Ref: extension80499 -Node: Pens87182 -Ref: fillrule94548 -Ref: basealign95445 -Ref: transparency98271 -Ref: makepen101714 -Ref: overwrite102552 -Node: Transforms103762 -Node: Frames and pictures105553 -Ref: envelope106694 -Ref: size107777 -Ref: unitsize108764 -Ref: shipout109824 -Ref: filltype112157 -Ref: add115294 -Ref: add about116240 -Ref: tex119178 -Node: Files120052 -Ref: cd121017 -Ref: scroll125449 -Node: Variable initializers128522 -Node: Structures131247 -Node: Operators138691 -Node: Arithmetic & logical139005 -Node: Self & prefix operators140979 -Node: User-defined operators141767 -Node: Implicit scaling142678 -Node: Functions143241 -Ref: stack overflow145994 -Node: Default arguments146558 -Node: Named arguments147297 -Node: Rest arguments149459 -Node: Mathematical functions152269 -Node: Arrays156876 -Ref: sort163926 -Ref: tridiagonal166330 -Ref: solve167558 -Node: Slices171751 -Node: Casts175641 -Node: Import177606 -Node: Static182833 -Node: LaTeX usage185727 -Node: Base modules191768 -Node: plain194268 -Node: simplex194920 -Node: math195193 -Node: interpolate197898 -Node: geometry198177 -Node: trembling198771 -Node: stats199122 -Node: patterns199382 -Node: markers199618 -Node: tree201401 -Node: binarytree201589 -Node: drawtree202178 -Node: syzygy202382 -Node: feynman202656 -Node: roundedpath202931 -Node: animation203214 -Ref: animate203631 -Node: embed204770 -Node: slide206373 -Node: MetaPost206713 -Node: unicode207429 -Node: latin1208317 -Node: babel208685 -Node: labelpath208914 -Node: labelpath3209734 -Node: annotate210045 -Node: CAD210516 -Node: graph210826 -Ref: ticks217955 -Ref: pathmarkers231234 -Ref: marker231699 -Ref: markuniform232050 -Ref: errorbars233841 -Ref: automatic scaling237897 -Node: palette248543 -Ref: images248661 -Ref: image252832 -Ref: logimage253310 -Ref: penimage254116 -Node: three254560 -Ref: PostScript3D279102 -Node: obj280794 -Node: graph3281046 -Ref: GaussianSurface286171 -Node: grid3287275 -Node: solids288015 -Node: tube288963 -Node: flowchart291198 -Node: contour295767 -Node: contour3300892 -Node: slopefield301199 -Node: ode302636 -Node: Options302896 -Ref: configuration file308741 -Ref: settings308741 -Ref: convert309942 -Node: Interactive mode312909 -Ref: history315062 -Node: GUI316367 -Node: GUI installation316870 -Node: GUI usage318000 -Node: PostScript to Asymptote318903 -Node: Help319659 -Node: Debugger321395 -Node: Credits323180 -Node: Index324112 +Node: Configuring15020 +Node: Search paths19234 +Node: Compiling from UNIX source20031 +Ref: multisampling20620 +Node: Editing modes23026 +Node: Subversion25458 +Node: Uninstall25921 +Node: Tutorial26271 +Ref: unitcircle30569 +Node: Drawing commands32505 +Node: draw34216 +Ref: arrows35364 +Node: fill40607 +Ref: gradient shading41651 +Node: clip45879 +Node: label46471 +Ref: Label47170 +Node: Bezier curves52895 +Node: Programming56472 +Ref: array iteration57286 +Node: Data types58367 +Ref: format67375 +Node: Paths and guides70978 +Ref: circle71232 +Ref: arctime76720 +Ref: extension80575 +Node: Pens87258 +Ref: fillrule94624 +Ref: basealign95521 +Ref: transparency98347 +Ref: makepen101790 +Ref: overwrite102628 +Node: Transforms103838 +Node: Frames and pictures105629 +Ref: envelope106770 +Ref: size107853 +Ref: unitsize108840 +Ref: shipout109900 +Ref: filltype112233 +Ref: add115370 +Ref: add about116316 +Ref: tex119254 +Node: Files120128 +Ref: cd121093 +Ref: scroll125778 +Node: Variable initializers128851 +Node: Structures131576 +Node: Operators139020 +Node: Arithmetic & logical139334 +Node: Self & prefix operators141308 +Node: User-defined operators142096 +Node: Implicit scaling143007 +Node: Functions143570 +Ref: stack overflow146323 +Node: Default arguments146887 +Node: Named arguments147626 +Node: Rest arguments150197 +Node: Mathematical functions153318 +Node: Arrays157925 +Ref: sort165013 +Ref: tridiagonal167417 +Ref: solve168645 +Node: Slices172838 +Node: Casts176728 +Node: Import178693 +Node: Static183920 +Node: LaTeX usage186814 +Node: Base modules193031 +Node: plain195531 +Node: simplex196183 +Node: math196456 +Node: interpolate199161 +Node: geometry199440 +Node: trembling200034 +Node: stats200385 +Node: patterns200645 +Node: markers200881 +Node: tree202664 +Node: binarytree202852 +Node: drawtree203441 +Node: syzygy203645 +Node: feynman203919 +Node: roundedpath204194 +Node: animation204477 +Ref: animate204894 +Node: embed206033 +Node: slide207636 +Node: MetaPost207976 +Node: unicode208692 +Node: latin1209580 +Node: babel209948 +Node: labelpath210177 +Node: labelpath3210997 +Node: annotate211308 +Node: CAD211779 +Node: graph212089 +Ref: ticks219218 +Ref: pathmarkers232497 +Ref: marker232962 +Ref: markuniform233313 +Ref: errorbars235104 +Ref: automatic scaling239160 +Node: palette249806 +Ref: images249924 +Ref: image254095 +Ref: logimage254573 +Ref: penimage255551 +Ref: penfunctionimage255772 +Node: three256496 +Ref: PostScript3D281241 +Node: obj282933 +Node: graph3283185 +Ref: GaussianSurface288310 +Node: grid3289414 +Node: solids290154 +Node: tube291102 +Node: flowchart293337 +Node: contour297906 +Node: contour3303031 +Node: slopefield303338 +Node: ode304775 +Node: Options305035 +Ref: configuration file310963 +Ref: settings310963 +Ref: convert312164 +Node: Interactive mode315131 +Ref: history317284 +Node: GUI318589 +Node: GUI installation319092 +Node: GUI usage320222 +Node: PostScript to Asymptote321125 +Node: Help321881 +Node: Debugger323617 +Node: Credits325402 +Node: Index326334 End Tag Table diff --git a/Master/texmf/doc/man/man1/asy.1 b/Master/texmf/doc/man/man1/asy.1 index d9e680befc7..2548dbc79d7 100644 --- a/Master/texmf/doc/man/man1/asy.1 +++ b/Master/texmf/doc/man/man1/asy.1 @@ -31,249 +31,253 @@ in the user's home directory using the long form: For a complete description, see the Info files. .TP -.B \-V,\-View +.B \-V,\-View View output; command-line only. .TP -.B \-a,\-align C|B|T|Z +.B \-a,\-align C|B|T|Z Center, Bottom, Top, or Zero page alignment [C]. .TP -.B \-antialias n +.B \-antialias n Antialiasing width for rasterized output [2]. --arcballradius pixels Arcball radius [750] .TP -.B \-auto3D +.B \-arcballradius pixels +Arcball radius [750]. +.TP +.B \-auto3D Automatically activate 3D scene [true]. --autobillboard 3D labels always face viewer by default [true] .TP -.B \-autoimport string +.B \-autobillboard +3D labels always face viewer by default [true]. +.TP +.B \-autoimport string Module to automatically import. .TP -.B \-autoplain +.B \-autoplain Enable automatic importing of plain [true]. .TP -.B \-autoplay +.B \-autoplay Autoplay 3D animations [false]. .TP -.B \-autorotate +.B \-autorotate Enable automatic PDF page rotation [false]. .TP -.B \-batchMask +.B \-batchMask Mask fpu exceptions in batch mode [false]. .TP -.B \-batchView +.B \-batchView View output in batch mode [false]. .TP -.B \-bw +.B \-bw Convert all colors to black and white [false]. .TP -.B \-cd directory +.B \-cd directory Set current directory; command-line only. .TP -.B \-cmyk +.B \-cmyk Convert rgb colors to cmyk [false]. .TP -.B \-c,\-command string +.B \-c,\-command string Command to autoexecute. .TP -.B \-compact +.B \-compact Conserve memory at the expense of speed [false]. .TP -.B \-d,\-debug +.B \-d,\-debug Enable debugging messages [false]. .TP -.B \-divisor n +.B \-divisor n Garbage collect using purge(divisor=n) [2]. .TP -.B \-doubleclick ms +.B \-doubleclick ms Emulated double-click timeout [200]. .TP -.B \-embed +.B \-embed Embed rendered preview image [true]. .TP -.B \-exitonEOF +.B \-exitonEOF Exit interactive mode on EOF [true]. .TP -.B \-fitscreen +.B \-fitscreen Fit rendered image to screen [true]. .TP -.B \-framedelay ms +.B \-framedelay ms Additional frame delay [0]. .TP -.B \-framerate frames/s +.B \-framerate frames/s Animation speed [30]. .TP -.B \-globalwrite +.B \-globalwrite Allow write to other directory [false]. .TP -.B \-gray +.B \-gray Convert all colors to grayscale [false]. .TP -.B \-h,\-help +.B \-h,\-help Show summary of options; command-line only. .TP -.B \-historylines n +.B \-historylines n Retain n lines of history [1000]. .TP -.B \-iconify +.B \-iconify Iconify rendering window [false]. .TP -.B \-inlineimage +.B \-inlineimage Generate inline embedded image [false]. .TP -.B \-inlinetex +.B \-inlinetex Generate inline TeX code [false]. .TP -.B \-interactiveMask +.B \-interactiveMask Mask fpu exceptions in interactive mode [true]. .TP -.B \-interactiveView +.B \-interactiveView View output in interactive mode [true]. .TP -.B \-interactiveWrite +.B \-interactiveWrite Write expressions entered at the prompt to stdout [true]. .TP -.B \-k,\-keep +.B \-k,\-keep Keep intermediate files [false]. .TP -.B \-keepaux +.B \-keepaux Keep intermediate LaTeX .aux files [false]. .TP -.B \-level n +.B \-level n Postscript level [3]. .TP -.B \-l,\-listvariables +.B \-l,\-listvariables List available global functions and variables [false]. .TP -.B \-localhistory +.B \-localhistory Use a local interactive history file [false]. .TP -.B \-loop +.B \-loop Loop 3D animations [false]. .TP -.B \-m,\-mask +.B \-m,\-mask Mask fpu exceptions; command-line only. .TP -.B \-maxtile pair +.B \-maxtile pair Maximum rendering tile size [(0,0)]. .TP -.B \-maxviewport pair +.B \-maxviewport pair Maximum viewport size [(2048,2048)]. .TP -.B \-multiline +.B \-multiline Input code over multiple lines at the prompt [false]. .TP -.B \-multipleView +.B \-multipleView View output from multiple batch-mode files [false]. .TP -.B \-multisample n +.B \-multisample n Multisampling width for screen images [4]. .TP -.B \-O,\-offset pair +.B \-O,\-offset pair PostScript offset [(0,0)]. .TP -.B \-f,\-outformat format +.B \-f,\-outformat format Convert each output file to specified format. .TP -.B \-o,\-outname name +.B \-o,\-outname name Alternative output directory/filename. .TP -.B \-p,\-parseonly +.B \-p,\-parseonly Parse file [false]. .TP -.B \-pdfreload +.B \-pdfreload Automatically reload document in pdfviewer [false]. .TP -.B \-pdfreloaddelay usec +.B \-pdfreloaddelay usec Delay before attempting initial pdf reload [750000]. .TP -.B \-position pair +.B \-position pair Initial 3D rendering screen position [(0,0)]. .TP -.B \-prc +.B \-prc Embed 3D PRC graphics in PDF output [true]. .TP -.B \-prompt string +.B \-prompt string Prompt [> ]. .TP -.B \-prompt2 string +.B \-prompt2 string Continuation prompt for multiline input [..]. .TP -.B \-q,\-quiet +.B \-q,\-quiet Suppress welcome message [false]. .TP -.B \-render n -Render 3D graphics using n pixels per bp (-1=auto) [-1]. +.B \-render n +Render 3D graphics using n pixels per bp (-1=auto) [0]. .TP -.B \-resizestep step +.B \-resizestep step Resize step [1.2]. .TP -.B \-reverse +.B \-reverse reverse 3D animations [false]. .TP -.B \-rgb +.B \-rgb Convert cmyk colors to rgb [false]. .TP -.B \-safe +.B \-safe Disable system call [true]. .TP -.B \-scroll n +.B \-scroll n Scroll standard output n lines at a time [0]. .TP -.B \-spinstep deg/s +.B \-spinstep deg/s Spin speed [60]. .TP -.B \-svgemulation +.B \-svgemulation Emulate unimplemented SVG shading [false]. .TP -.B \-tabcompletion +.B \-tabcompletion Interactive prompt auto-completion [true]. .TP -.B \-tex engine +.B \-tex engine latex|pdflatex|xelatex|tex|pdftex|context|none [latex]. .TP -.B \-thick +.B \-thick Render thick 3D lines [true]. .TP -.B \-thin +.B \-thin Render thin 3D lines [true]. .TP -.B \-threads +.B \-threads Use POSIX threads for 3D rendering [true]. .TP -.B \-toolbar +.B \-toolbar Show 3D toolbar in PDF output [true]. .TP -.B \-s,\-translate +.B \-s,\-translate Show translated virtual machine code [false]. .TP -.B \-twice +.B \-twice Run LaTeX twice (to resolve references) [false]. .TP -.B \-twosided +.B \-twosided Use two-sided 3D lighting model for rendering [true]. .TP -.B \-u,\-user string +.B \-u,\-user string General purpose user string. .TP -.B \-v,\-verbose +.B \-v,\-verbose Increase verbosity level (can specify multiple times) [0]. .TP -.B \-version +.B \-version Show version; command-line only. .TP -.B \-wait +.B \-wait Wait for child processes to finish before exiting [false]. .TP -.B \-warn string +.B \-warn string Enable warning; command-line only. .TP -.B \-where +.B \-where Show where listed variables are declared [false]. .TP -.B \-zoomfactor factor +.B \-zoomfactor factor Zoom step factor [1.05]. .TP -.B \-zoomstep step +.B \-zoomstep step Mouse motion zoom step [0.1]. .SH SEE ALSO diff --git a/Master/texmf/doc/man/man1/asy.man1.pdf b/Master/texmf/doc/man/man1/asy.man1.pdf Binary files differindex b15add600aa..e3b3344fa34 100644 --- a/Master/texmf/doc/man/man1/asy.man1.pdf +++ b/Master/texmf/doc/man/man1/asy.man1.pdf diff --git a/Master/texmf/doc/man/man1/xasy.man1.pdf b/Master/texmf/doc/man/man1/xasy.man1.pdf Binary files differindex 3a4582db84f..23a8435a0fb 100644 --- a/Master/texmf/doc/man/man1/xasy.man1.pdf +++ b/Master/texmf/doc/man/man1/xasy.man1.pdf diff --git a/Master/texmf/tex/latex/asymptote/asymptote.sty b/Master/texmf/tex/latex/asymptote/asymptote.sty index 4db253d4095..6518baba61f 100644 --- a/Master/texmf/tex/latex/asymptote/asymptote.sty +++ b/Master/texmf/tex/latex/asymptote/asymptote.sty @@ -1,304 +1,398 @@ -%%% Asymptote style file for LaTeX -%%% Contributed by Tom Prince 14 May 2003 -%%% Modified by John Bowman -%%% Adapted from comment.sty (Under GPL v2+) - -\ProvidesPackage{asymptote}[2010/07/10 v1.15 Asymptote style file for LaTeX] +%% +%% This is file `asymptote.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% asy-latex.dtx (with options: `pkg') +%% ____________________________ +%% The ASYMPTOTE package +%% +%% (C) 2003 Tom Prince +%% (C) 2003-2010 John Bowman +%% (C) 2010 Will Robertson +%% +%% Adapted from comment.sty +%% +%% Licence: GPL2+ +%% +\ProvidesPackage{asymptote} + [2011/05/15 v1.24 Asymptote style file for LaTeX] +\def\Asymptote{{\tt Asymptote}} +\InputIfFileExists{\jobname.pre}{}{} +\newbox\ASYbox +\newcounter{asy} +\newwrite\AsyStream +\newwrite\AsyPreStream +\newif\ifASYinline +\newif\ifASYattach +\newif\ifASYkeepAspect +\ASYkeepAspecttrue \RequirePackage{keyval} \RequirePackage{ifthen} -\newif\ifASYdefaultinline -\newif\ifASYdefaultattach -\DeclareOption{inline}{\ASYdefaultinlinetrue} -\DeclareOption{attach}{\ASYdefaultattachtrue} -\ProcessOptions* - -\def\unquoteJobname#1"#2"#3\relax{\def\rawJobname{#1}% - \ifx\rawJobname\empty\def\rawJobname{#2}\fi} -\expandafter\unquoteJobname\jobname""\relax -% Work around jobname bug in MiKTeX 2.5 and 2.6: -% Turn stars in file names (resulting from spaces, etc.) into minus signs -\def\fixstar#1*#2\relax{\def\argtwo{#2}\ifx\argtwo\empty\gdef\Jobname{#1}\else -\fixstar#1-#2\relax\fi} -\expandafter\fixstar\rawJobname*\relax - \RequirePackage{color,graphicx} - -\def\makeinnocent#1{\catcode`#1=12 } +\IfFileExists{ifpdf.sty}{ + \RequirePackage{ifpdf} +}{ + \expandafter\newif\csname ifpdf\endcsname + \ifx\pdfoutput\@undefined\else + \ifcase\pdfoutput\else + \pdftrue + \fi + \fi +} +\IfFileExists{ifxetex.sty}{ + \RequirePackage{ifxetex} +}{ + \expandafter\newif\csname ifxetex\endcsname + \ifx\XeTeXversion\@undefined\else + \xetextrue + \fi +} +\IfFileExists{catchfile.sty}{ + \RequirePackage{catchfile} +}{ + \newcommand\CatchFileDef[3]{% + \begingroup + \everyeof{% + \ENDCATCHFILEMARKER + \noexpand + }% + \long\def\@tempa##1\ENDCATCHFILEMARKER{% + \endgroup + \def#1{##1}% + }% + #3% + \expandafter\@tempa\@@input #2\relax + } +} +\newif\if@asy@attachfile@loaded +\AtBeginDocument{% + \@ifpackageloaded{attachfile2}{\@asy@attachfile@loadedtrue}{}% + \let\asy@check@attachfile\asy@check@attachfile@loaded +} +\newcommand\asy@check@attachfile@loaded{% + \if@asy@attachfile@loaded\else + \PackageError{asymptote}{You must load the attachfile2 package}{^^J% + You have requested the [attach] option for some or all of your^^J% + Asymptote graphics, which requires the attachfile2 package.^^J% + Please load it in the document preamble.^^J% + }% + \fi +} +\newcommand\asy@check@attachfile{% + \AtBeginDocument{\asy@check@attachfile@loaded}% + \let\asy@check@attachfile\@empty +} \def\csarg#1#2{\expandafter#1\csname#2\endcsname} -\newwrite\AsyStream -\newwrite\AsyPreStream -\newread\AsyTestStream - -\def\AsyInput#1{\openin\AsyTestStream=#1 -\ifeof\AsyTestStream -\else - \input #1 -\fi -\closein\AsyTestStream% +\DeclareOption{inline}{% + \ASYinlinetrue } - -\AsyInput{\jobname.pre} - -\immediate\openout\AsyPreStream=\jobname.pre - -\newif\ifASYinline -\newif\ifASYattach +\DeclareOption{attach}{% + \asy@check@attachfile + \ASYattachtrue +} +\ProcessOptions* +\def\asydir{} +\def\ASYprefix{} \newif\ifASYPDF - -\ifx\pdfoutput\undefined -\else -\ifcase\pdfoutput +\ifxetex + \ASYPDFtrue \else -\ASYPDFtrue + \ifpdf + \ASYPDFtrue + \fi \fi +\ifASYPDF + \def\AsyExtension{pdf} +\else + \def\AsyExtension{eps} \fi - -\newbox\ASYbox -\newcounter{asy} - -\def\ProcessAsymptote#1% start it all off -{\begingroup +\def\unquoteJobname#1"#2"#3\relax{% + \def\rawJobname{#1}% + \ifx\rawJobname\empty + \def\rawJobname{#2}% + \fi +} +\expandafter\unquoteJobname\jobname""\relax +\def\fixstar#1*#2\relax{% + \def\argtwo{#2}% + \ifx\argtwo\empty + \gdef\Jobname{#1}% + \else + \fixstar#1-#2\relax + \fi +} +\expandafter\fixstar\rawJobname*\relax +\def\Ginclude@eps#1{% + \message{<#1>}% + \bgroup + \def\@tempa{!}% + \dimen@\Gin@req@width + \dimen@ii.1bp\relax + \divide\dimen@\dimen@ii + \@tempdima\Gin@req@height + \divide\@tempdima\dimen@ii + \special{PSfile=#1\space + llx=\Gin@llx\space + lly=\Gin@lly\space + urx=\Gin@urx\space + ury=\Gin@ury\space + \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi + \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi + \ifGin@clip clip\fi}% + \egroup +} +\immediate\openout\AsyPreStream=\jobname.pre\relax +\AtEndDocument{\immediate\closeout\AsyPreStream} +\def\WriteAsyLine#1{% + \immediate\write\AsyStream{\detokenize{#1}}% +} +\def\globalASYdefs{} +\def\WriteGlobalAsyLine#1{% + \expandafter\g@addto@macro + \expandafter\globalASYdefs + \expandafter{\detokenize{#1^^J}}% +} +\def\ProcessAsymptote#1{% + \begingroup \def\CurrentAsymptote{#1}% - \let\do\makeinnocent \dospecials - \makeinnocent\^^L% and whatever other special cases - \endlinechar`\^^M \catcode`\^^M=12 \xAsymptote} -{\catcode`\^^M=12 \endlinechar=-1 % + \let\do\@makeother \dospecials + \@makeother\^^L% and whatever other special cases + \catcode`\ =10 + \endlinechar`\^^M \catcode`\^^M=12 \xAsymptote +} +\begingroup + \catcode`\^^M=12 \endlinechar=-1\relax% \gdef\xAsymptote{% - \expandafter\ProcessAsymptoteLine} - \gdef\ProcessAsymptoteLine#1^^M{\def\test{#1} - \csarg\ifx{End\CurrentAsymptote Test}\test - \edef\next{\noexpand\EndOfAsymptote{\CurrentAsymptote}}% - \else \ThisAsymptote{#1}\let\next\ProcessAsymptoteLine - \fi \next} -} - -\def\ASYstringmeaning#1{\expandafter\ASYgobblearrow\meaning#1} -\def\ASYstringcsnoescape#1{\expandafter\ASYgobbleescape\string#1} -{\escapechar-1 - \expandafter\expandafter\expandafter\gdef - \expandafter\expandafter\expandafter\ASYgobblearrow - \expandafter\string\csname macro:->\endcsname{} -} -\def\ASYgobbleescape#1{\ifnum`\\=`#1 \else #1\fi} - -\def\WriteAsyLine#1{\def\ASYtmp{#1}% - \immediate\write\AsyStream{\ASYstringmeaning\ASYtmp}} - -\def\gedefappend#1#2{% - \toks@ = \expandafter{#1}% - \global\edef#1{\the\toks@ #2}% -}% -\def\globalASYdefs{} -\def\WriteGlobalAsyLine#1{\def\ASYtmp{#1^^J}% -\gedefappend\globalASYdefs{\ASYstringmeaning\ASYtmp}} - -\def\EndOfAsymptote#1{\endgroup\end{#1}% - \csname After#1Asymptote\endcsname} -\def\AsymptoteEndDef#1{{\escapechar=-1\relax - \csarg\xdef{End#1Test}{\string\\end\string\{#1\string\}}% - }} - -\def\AfterasyAsymptote{% - \ifx\ASYwidth\empty - \ifx\ASYheight\empty + \expandafter\ProcessAsymptoteLine% + } + \gdef\ProcessAsymptoteLine#1^^M{% + \def\@tempa{#1}% + {% + \escapechar=-1\relax% + \xdef\@tempb{\string\\end\string\{\CurrentAsymptote\string\}}% + }% + \ifx\@tempa\@tempb% + \edef\next{\endgroup\noexpand\end{\CurrentAsymptote}}% + \else% + \ThisAsymptote{#1}% + \let\next\ProcessAsymptoteLine% + \fi% + \next% + } +\endgroup +\newcommand\asy[1][]{% + \stepcounter{asy}% + \setkeys{ASYkeys}{#1}% + \ifASYattach + \ASYinlinefalse + \fi + \ifx\asydir\empty\else + \def\ASYprefix{\asydir/}% + \fi + \immediate\write\AsyPreStream{% + \noexpand\InputIfFileExists{% + \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}% + } + \asy@write@graphic@header + \let\ThisAsymptote\WriteAsyLine + \ProcessAsymptote{asy}% +} +\def\endasy{% + \asy@finalise@stream + \asy@input@graphic +} +\def\asy@write@graphic@header{% + \immediate\openout\AsyStream=\ASYprefix\jobname-\the\c@asy.asy\relax + \gdef\AsyFile{\ASYprefix\Jobname-\the\c@asy}% + \immediate\write\AsyStream{% + if(!settings.multipleView) settings.batchView=false;^^J% + \ifxetex + settings.tex="xelatex";^^J% + \else\ifASYPDF + settings.tex="pdflatex";^^J% + \fi\fi + \ifASYinline + settings.inlinetex=true;^^J% + deletepreamble();^^J% + \fi + defaultfilename="\Jobname-\the\c@asy";^^J% + if(settings.render < 0) settings.render=4;^^J% + settings.outformat="";^^J% + \ifASYattach + settings.inlineimage=false;^^J% + settings.embed=false;^^J% + settings.toolbar=true;^^J% \else - \immediate\write\AsyStream{size(0,\ASYheight);}% + settings.inlineimage=true;^^J% + settings.embed=true;^^J% + settings.toolbar=false;^^J% + viewportmargin=(2,2);^^J% \fi - \else - \ifx\ASYheight\empty - \immediate\write\AsyStream{size(\ASYwidth,0);}% + \globalASYdefs + }% +} +\def\asy@expand@keepAspect{% + \ifASYkeepAspect keepAspect=true% + \else keepAspect=false% + \fi% +} +\def\asy@finalise@stream{% + \ifx\ASYwidth\@empty + \ifx\ASYheight\@empty + % write nothing! \else - \immediate\write\AsyStream{size(\ASYwidth,\ASYheight);}% + \immediate\write\AsyStream{size(0,\ASYheight,\asy@expand@keepAspect);}% \fi - \fi - \ifASYattach - \def\ASYdefaultviewportwidth{0}% \else - \def\ASYdefaultviewportwidth{\the\linewidth}% + \ifx\ASYheight\@empty + \immediate\write\AsyStream{size(\ASYwidth,0,\asy@expand@keepAspect);}% + \else + \immediate\write\AsyStream{size(\ASYwidth,\ASYheight,\asy@expand@keepAspect);}% + \fi \fi - \ifx\ASYviewportwidth\empty - \ifx\ASYviewportheight\empty + \edef\ASYviewportwidth{\ASYviewportwidth}% locally "freeze" viewportwidth + \ifx\ASYviewportwidth\@empty + \ifx\ASYviewportheight\@empty + % write nothing! \else \immediate\write\AsyStream{viewportsize=(0,\ASYviewportheight);}% \fi \else - \ifx\ASYviewportheight\empty + \ifx\ASYviewportheight\@empty \immediate\write\AsyStream{viewportsize=(\ASYviewportwidth,0);}% \else - \immediate\write% - \AsyStream{viewportsize=(\ASYviewportwidth,\ASYviewportheight);}% + \immediate\write\AsyStream{% + viewportsize=(\ASYviewportwidth,\ASYviewportheight);}% \fi \fi - \gdef\ASYwidth{}% - \gdef\ASYheight{}% - \gdef\ASYviewportwidth{\ASYdefaultviewportwidth}% - \gdef\ASYviewportheight{}% \immediate\closeout\AsyStream - +} +\def\asy@input@graphic{% \ifASYinline - \openin\AsyTestStream=\AsyFile.tex - \else - \ifASYPDF - \openin\AsyTestStream=\AsyFile.pdf - \else - \openin\AsyTestStream=\AsyFile.eps - \fi - \fi - \ifeof\AsyTestStream - \ifASYinline + \IfFileExists{"\AsyFile.tex"}{% + \catcode`:=12\relax + \@@input"\AsyFile.tex"\relax + }{% \PackageWarning{asymptote}{file `\AsyFile.tex' not found}% - \closein\AsyTestStream% - \else - \closein\AsyTestStream% - \openin\AsyTestStream=\AsyFile.tex - \ifeof\AsyTestStream + }% + \else + \IfFileExists{"\AsyFile.\AsyExtension"}{% + \ifASYattach \ifASYPDF - \PackageWarning{asymptote}{file `\AsyFile.pdf' not found}% + \IfFileExists{"\AsyFile+0.pdf"}{% + \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile+0".pdf}}% + }{% + \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile".pdf}}% + }% \else - \PackageWarning{asymptote}{file `\AsyFile.eps' not found}% + \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{"\AsyFile.eps"}}% \fi + \textattachfile{\AsyFile.\AsyExtension}{\phantom{\copy\ASYbox}}% + \vskip-\ht\ASYbox + \indent + \box\ASYbox \else - \catcode`:=12 - \input \AsyFile.tex% - \fi - \closein\AsyTestStream% - \fi - \else - \closein\AsyTestStream% - \ifASYinline - \catcode`:=12 - \input \AsyFile.tex% - \else - \ifASYattach \ifASYPDF - \openin\AsyTestStream=\AsyFile+0.pdf - \fi - \ifeof\AsyTestStream - \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{\AsyFile}}% + \includegraphics[hiresbb]{"\AsyFile".pdf}% \else - \setbox\ASYbox=\hbox{\includegraphics[hiresbb]{\AsyFile+0}}% + \includegraphics[hiresbb]{"\AsyFile.eps"}% \fi - \textattachfile{\AsyFile.pdf}{\phantom{\copy\ASYbox}}% - \vskip-\ht\ASYbox% - \indent% - \box\ASYbox% - \closein\AsyTestStream% - \else - \includegraphics[hiresbb]{\AsyFile}% \fi - \fi + }{% + \IfFileExists{"\AsyFile.tex"}{% + \catcode`:=12 + \@@input"\AsyFile.tex"\relax + }{% + \PackageWarning{asymptote}{% + file `\AsyFile.\AsyExtension' not found% + }% + }% + }% \fi - \relax% - \endgroup} -\gdef\ASYwidth{}% +} +\def\asydef{% + \let\ThisAsymptote\WriteGlobalAsyLine + \ProcessAsymptote{asydef}% +} +\newcommand\asyinclude[2][]{% + \begingroup + \stepcounter{asy}% + \setkeys{ASYkeys}{#1}% + \ifASYattach + \ASYinlinefalse + \fi + \ifx\asydir\empty\else + \def\ASYprefix{\asydir/}% + \fi + \immediate\write\AsyPreStream{% + \noexpand\InputIfFileExists{% + \ASYprefix\noexpand\jobname-\the\c@asy.pre}{}{}% + } + \asy@write@graphic@header + \IfFileExists{#2.asy}{% + \CatchFileDef\@tempa{#2.asy}{% + \let\do\@makeother + \dospecials + \endlinechar=10\relax + } + }{ + \IfFileExists{#2}{% + \CatchFileDef\@tempa{#2}{% + \let\do\@makeother + \dospecials + \endlinechar=10\relax + } + }{ + \PackageWarning{asymptote}{file #2 not found}% + } + } + \immediate\write\AsyStream{\unexpanded\expandafter{\@tempa}}% + \asy@finalise@stream + \asy@input@graphic + \endgroup +} +\newcommand{\ASYanimategraphics}[5][]{% + \IfFileExists{_#3.pdf}{% + \animategraphics[{#1}]{#2}{_#3}{#4}{#5}% + }{} +} +\newcommand\asysetup[1]{\setkeys{ASYkeys}{#1}} +\define@key{ASYkeys}{dir}{% + \def\asydir{#1}% +} +\def\ASYwidth{} \define@key{ASYkeys}{width}{% - \gdef\ASYwidth{#1}% + \edef\ASYwidth{\the\dimexpr#1\relax}% } -\gdef\ASYheight{}% +\def\ASYheight{} \define@key{ASYkeys}{height}{% - \gdef\ASYheight{#1}% + \edef\ASYheight{\the\dimexpr#1\relax}% +} +\define@key{ASYkeys}{keepAspect}[true]{% + \ifthenelse{\equal{#1}{true}} + {\ASYkeepAspecttrue} + {\ASYkeepAspectfalse}% +} +\def\ASYviewportwidth{\ASYdefaultviewportwidth} +\def\ASYdefaultviewportwidth{% + \ifASYattach \@empty \else \the\linewidth \fi } -\gdef\ASYviewportwidth{\ASYdefaultviewportwidth}% \define@key{ASYkeys}{viewportwidth}{% - \gdef\ASYviewportwidth{#1}% + \edef\ASYviewportwidth{\the\dimexpr#1\relax}% } -\gdef\ASYviewportheight{}% +\def\ASYviewportheight{} \define@key{ASYkeys}{viewportheight}{% - \gdef\ASYviewportheight{#1}% -} -\define@key{ASYkeys}{attach}[true]{% - \ifthenelse{\equal{#1}{true}}{\global\ASYattachtrue}{\global\ASYattachfalse}% + \edef\ASYviewportheight{\the\dimexpr#1\relax}% } \define@key{ASYkeys}{inline}[true]{% - \ifthenelse{\equal{#1}{true}}{\global\ASYinlinetrue}{\global\ASYinlinefalse}% + \ifthenelse{\equal{#1}{true}} + {\ASYinlinetrue} + {\ASYinlinefalse}% } -\newcommand\asy[1][]{% - \begingroup - \let\par\empty - \stepcounter{asy}% - \global\let\ifASYinline\ifASYdefaultinline - \global\let\ifASYattach\ifASYdefaultattach - \setkeys{ASYkeys}{#1}% - \ifASYattach - \global\ASYinlinefalse - \fi - \immediate\write\AsyPreStream% - {\@backslashchar AsyInput{\jobname-\the\c@asy.pre}} - \immediate\openout\AsyStream=\jobname-\the\c@asy.asy - \gdef\AsyFile{\Jobname-\the\c@asy}% - \immediate\write\AsyStream{if(!settings.multipleView)}% - \immediate\write\AsyStream{ settings.batchView=false;}% - \ifx\XeTeXversion\undefined - \ifASYPDF - \immediate\write\AsyStream{settings.tex="pdflatex";}% - \fi - \else - \immediate\write\AsyStream{settings.tex="xelatex";}% - \ASYPDFtrue - \fi - - \ifASYinline - \immediate\write\AsyStream{settings.inlinetex=true;}% - \immediate\write\AsyStream{deletepreamble();}% - \fi - \immediate\write\AsyStream{defaultfilename="\AsyFile";}% - \immediate\write\AsyStream{if(settings.render < 0) settings.render=4;}% - \ifASYattach - \immediate\write\AsyStream{settings.inlineimage=false;}% - \immediate\write\AsyStream{settings.embed=false;}% - \immediate\write\AsyStream{settings.outformat="pdf";}% - \immediate\write\AsyStream{settings.toolbar=true;}% - \else - \immediate\write\AsyStream{settings.inlineimage=true;}% - \immediate\write\AsyStream{settings.embed=true;}% - \immediate\write\AsyStream{settings.outformat="";}% - \immediate\write\AsyStream{settings.toolbar=false;}% - \immediate\write\AsyStream{viewportmargin=(2,2);}% - \fi - \immediate\write\AsyStream{\globalASYdefs}% - \let\ThisAsymptote\WriteAsyLine% - \ProcessAsymptote{asy}% +\define@key{ASYkeys}{attach}[true]{% + \ifthenelse{\equal{#1}{true}} + {\ASYattachtrue} + {\ASYattachfalse}% } -\AsymptoteEndDef{asy} -\def\asydef{% - \let\ThisAsymptote\WriteGlobalAsyLine% - \ProcessAsymptote{asydef}} -\AsymptoteEndDef{asydef} -\def\AfterasydefAsymptote{} - -\AtEndDocument{\immediate\closeout\AsyPreStream} - -\newcommand{\ASYanimategraphics}[5][]{% -\openin\AsyTestStream=_#3.pdf -\ifeof\AsyTestStream% -\else% -\animategraphics[{#1}]{#2}{_#3}{#4}{#5}% -\fi% -} - -% Work around bug in dvips.def: allow spaces in file names. -\def\Ginclude@eps#1{% - \message{<#1>}% - \bgroup - \def\@tempa{!}% - \dimen@\Gin@req@width - \dimen@ii.1bp% - \divide\dimen@\dimen@ii - \@tempdima\Gin@req@height - \divide\@tempdima\dimen@ii - \special{PSfile=#1\space - llx=\Gin@llx\space - lly=\Gin@lly\space - urx=\Gin@urx\space - ury=\Gin@ury\space - \ifx\Gin@scalex\@tempa\else rwi=\number\dimen@\space\fi - \ifx\Gin@scaley\@tempa\else rhi=\number\@tempdima\space\fi - \ifGin@clip clip\fi}% - \egroup} - -\def\Asymptote{{\tt Asymptote}} - -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "shared" -%%% End: diff --git a/Master/tlpkg/asymptote/asy.exe b/Master/tlpkg/asymptote/asy.exe Binary files differindex 01deb9e10d0..4671ff50309 100755 --- a/Master/tlpkg/asymptote/asy.exe +++ b/Master/tlpkg/asymptote/asy.exe |