diff options
author | Karl Berry <karl@freefriends.org> | 2011-06-19 12:55:47 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-06-19 12:55:47 +0000 |
commit | e3c76dde873b406caea8362741da0537cea3ac9d (patch) | |
tree | 7fd2f7e1f928a36d640b2720562eded540bf0857 /Master/texmf/asymptote | |
parent | 1e36e2153080d89f519641dbfc1351b35176a7ea (diff) |
asymptote 2.12
git-svn-id: svn://tug.org/texlive/trunk@23055 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf/asymptote')
-rwxr-xr-x | Master/texmf/asymptote/GUI/xasyVersion.py | 2 | ||||
-rw-r--r-- | Master/texmf/asymptote/asy-keywords.el | 4 | ||||
-rw-r--r-- | Master/texmf/asymptote/geometry.asy | 6747 | ||||
-rw-r--r-- | Master/texmf/asymptote/obj.asy | 6 | ||||
-rw-r--r-- | Master/texmf/asymptote/palette.asy | 38 | ||||
-rw-r--r-- | Master/texmf/asymptote/version.asy | 2 |
6 files changed, 3424 insertions, 3375 deletions
diff --git a/Master/texmf/asymptote/GUI/xasyVersion.py b/Master/texmf/asymptote/GUI/xasyVersion.py index d90a53ca618..5add418b757 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.10" +xasyVersion = "2.12" diff --git a/Master/texmf/asymptote/asy-keywords.el b/Master/texmf/asymptote/asy-keywords.el index 6ab0cf8f752..ac4d86b3799 100644 --- a/Master/texmf/asymptote/asy-keywords.el +++ b/Master/texmf/asymptote/asy-keywords.el @@ -2,7 +2,7 @@ ;; This file is automatically generated by asy-list.pl. ;; Changes will be overwritten. ;; -(defvar asy-keywords-version "2.10") +(defvar asy-keywords-version "2.12") (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 )) @@ -14,4 +14,4 @@ Braid FitResult Label Legend Segment Solution TreeNode abscissa arc arrowhead bi 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 DOSendl DOSnewl 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 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 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 calculateScaling 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 copyPairOrTriple 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 drawpixel 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 jobname 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 makeNode makedraw makepen map margin markangle markangleradius markanglespace markarc marker markinterval marknodes markrightangle markuniform mass masscenter massformat math max max3 maxAfterTransform maxbezier maxbound maxcoords maxlength maxratio maxtimes mean medial median midpoint min min3 minAfterTransform minbezier minbound minipage minratio mintimes miterlimit mktemp 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 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 printBytecode 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 sinh size size3 skewness skip slant sleep slope slopefield solve solveBVP sort sourceline sphere split sqrt square srand standardizecoordsys startScript 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 trembleFuzz triangle triangleAbc triangleabc triangulate tricoef tridiagonal trilinear trim 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 expansionfactor extendcap exterior fermionpen figureborder figuremattpen file3 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 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 plain_bounds plain_scaling 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 undefined unitcircle unitsquare up urlpen urlskip version vertexpen vertexsize viewportmargin viewportsize vline white wye xformStack yellow ylabelwidth zerotickfuzz zerowinding )) +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 expansionfactor extendcap exterior fermionpen figureborder figuremattpen file3 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 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 plain_bounds plain_scaling 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 swap textpen ticksize tildeframe tildemarksizefactor tinv titlealign titlepagepen titlepageposition titlepen titleskip top trailingzero treeLevelStep treeMinNodeWidth treeNodeStep trembleAngle trembleFrequency trembleRandom 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/geometry.asy b/Master/texmf/asymptote/geometry.asy index 61ff1ba8e8f..e87dc00550c 100644 --- a/Master/texmf/asymptote/geometry.asy +++ b/Master/texmf/asymptote/geometry.asy @@ -32,194 +32,194 @@ import math; import markers; // *=======================================================* // *........................HEADER.........................* -/*<asyxml><variable type="real" signature="epsgeo"><code></asyxml>*/ -real epsgeo=10*sqrt(realEpsilon);/*<asyxml></code><documentation>Variable used in the approximate calculations.</documentation></variable></asyxml>*/ - -/*<asyxml><function type="void" signature="addMargins(picture,real,real,real,real)"><code></asyxml>*/ -void addMargins(picture pic=currentpicture, - real lmargin=0, real bmargin=0, - real rmargin=lmargin, real tmargin=bmargin, - bool rigid=true, bool allObject=true) +/*<asyxml><variable type = "real" signature = "epsgeo"><code></asyxml>*/ +real epsgeo = 10 * sqrt(realEpsilon);/*<asyxml></code><documentation>Variable used in the approximate calculations.</documentation></variable></asyxml>*/ + +/*<asyxml><function type = "void" signature = "addMargins(picture, real, real, real, real)"><code></asyxml>*/ +void addMargins(picture pic = currentpicture, + real lmargin = 0, real bmargin = 0, + real rmargin = lmargin, real tmargin = bmargin, + bool rigid = true, bool allObject = true) {/*<asyxml></code><documentation>Add margins to 'pic' with respect to the current bounding box of 'pic'. If 'rigid' is false, margins are added iff an infinite curve will be prolonged on the margin. - If 'allObject' is false, fixed-size objects (such as labels and + If 'allObject' is false, fixed - size objects (such as labels and arrowheads) will be ignored.</documentation></function></asyxml>*/ - pair m=allObject ? truepoint(pic,SW) : point(pic,SW); - pair M=allObject ? truepoint(pic,NE) : point(pic,NE); + pair m = allObject ? truepoint(pic, SW) : point(pic, SW); + pair M = allObject ? truepoint(pic, NE) : point(pic, NE); if(rigid) { - draw(m-inverse(pic.calculateTransform())*(lmargin,bmargin),invisible); - draw(M+inverse(pic.calculateTransform())*(rmargin,tmargin),invisible); - } else pic.addBox(m,M,-(lmargin,bmargin),(rmargin,tmargin)); + draw(m - inverse(pic.calculateTransform()) * (lmargin, bmargin), invisible); + draw(M + inverse(pic.calculateTransform()) * (rmargin, tmargin), invisible); + } else pic.addBox(m, M, -(lmargin, bmargin), (rmargin, tmargin)); } real approximate(real t) { - real ot=t; - if(abs(t-ceil(t)) < epsgeo) ot=ceil(t); - else if(abs(t-floor(t)) < epsgeo) ot=floor(t); + real ot = t; + if(abs(t - ceil(t)) < epsgeo) ot = ceil(t); + else if(abs(t - floor(t)) < epsgeo) ot = floor(t); return ot; } real[] approximate(real[] T) { - return map(approximate,T); + return map(approximate, T); } -/*<asyxml><function type="real" signature="binomial(real,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "binomial(real, real)"><code></asyxml>*/ real binomial(real n, real k) -{/*<asyxml></code><documentation>Return n!/((n-k)!*k!)</documentation></function></asyxml>*/ - return gamma(n+1)/(gamma(n-k+1)*gamma(k+1)); +{/*<asyxml></code><documentation>Return n!/((n - k)!*k!)</documentation></function></asyxml>*/ + return gamma(n + 1)/(gamma(n - k + 1) * gamma(k + 1)); } -/*<asyxml><function type="real" signature="rf(real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "rf(real, real, real)"><code></asyxml>*/ real rf(real x, real y, real z) {/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the first kind. x, y, and z must be non negative, and at most one can be zero.</documentation></function></asyxml>*/ - real ERRTOL=0.0025, - TINY=1.5e-38, - BIG=3e37, - THIRD=1/3, - C1=1/24, - C2=0.1, - C3=3/44, - C4=1/14; - real alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt; - if(min(x,y,z) < 0 || min(x+y,x+z,y+z) < TINY || - max(x,y,z) > BIG) abort("rf: invalid arguments."); - xt=x; - yt=y; - zt=z; + real ERRTOL = 0.0025, + TINY = 1.5e-38, + BIG = 3e37, + THIRD = 1/3, + C1 = 1/24, + C2 = 0.1, + C3 = 3/44, + C4 = 1/14; + real alamb, ave, delx, dely, delz, e2, e3, sqrtx, sqrty, sqrtz, xt, yt, zt; + if(min(x, y, z) < 0 || min(x + y, x + z, y + z) < TINY || + max(x, y, z) > BIG) abort("rf: invalid arguments."); + xt = x; + yt = y; + zt = z; do { - sqrtx=sqrt(xt); - sqrty=sqrt(yt); - sqrtz=sqrt(zt); - alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz; - xt=0.25*(xt+alamb); - yt=0.25*(yt+alamb); - zt=0.25*(zt+alamb); - ave=THIRD*(xt+yt+zt); - delx=(ave-xt)/ave; - dely=(ave-yt)/ave; - delz=(ave-zt)/ave; - } while(max(fabs(delx),fabs(dely),fabs(delz)) > ERRTOL); - e2=delx*dely-delz*delz; - e3=delx*dely*delz; - return (1.0+(C1*e2-C2-C3*e3)*e2+C4*e3)/sqrt(ave); -} - -/*<asyxml><function type="real" signature="rd(real,real,real)"><code></asyxml>*/ + sqrtx = sqrt(xt); + sqrty = sqrt(yt); + sqrtz = sqrt(zt); + alamb = sqrtx * (sqrty + sqrtz) + sqrty * sqrtz; + xt = 0.25 * (xt + alamb); + yt = 0.25 * (yt + alamb); + zt = 0.25 * (zt + alamb); + ave = THIRD * (xt + yt + zt); + delx = (ave - xt)/ave; + dely = (ave - yt)/ave; + delz = (ave - zt)/ave; + } while(max(fabs(delx), fabs(dely), fabs(delz)) > ERRTOL); + e2 = delx * dely - delz * delz; + e3 = delx * dely * delz; + return (1.0 + (C1 * e2 - C2 - C3 * e3) * e2 + C4 * e3)/sqrt(ave); +} + +/*<asyxml><function type = "real" signature = "rd(real, real, real)"><code></asyxml>*/ real rd(real x, real y, real z) {/*<asyxml></code><documentation>Computes Carlson's elliptic integral of the second kind. x and y must be positive, and at most one can be zero. z must be non negative.</documentation></function></asyxml>*/ - real ERRTOL=0.0015, - TINY=1e-25, - BIG=4.5*10.0^21, - C1=(3/14), - C2=(1/6), - C3=(9/22), - C4=(3/26), - C5=(0.25*C3), - C6=(1.5*C4); - real alamb,ave,delx,dely,delz,ea,eb,ec,ed,ee,fac,sqrtx,sqrty, - sqrtz,sum,xt,yt,zt; - if (min(x,y) < 0 || min(x+y,z) < TINY || max(x,y,z) > BIG) + real ERRTOL = 0.0015, + TINY = 1e-25, + BIG = 4.5 * 10.0^21, + C1 = (3/14), + C2 = (1/6), + C3 = (9/22), + C4 = (3/26), + C5 = (0.25 * C3), + C6 = (1.5 * C4); + real alamb, ave, delx, dely, delz, ea, eb, ec, ed, ee, fac, sqrtx, sqrty, + sqrtz, sum, xt, yt, zt; + if (min(x, y) < 0 || min(x + y, z) < TINY || max(x, y, z) > BIG) abort("rd: invalid arguments"); - xt=x; - yt=y; - zt=z; - sum=0; - fac=1; + xt = x; + yt = y; + zt = z; + sum = 0; + fac = 1; do { - sqrtx=sqrt(xt); - sqrty=sqrt(yt); - sqrtz=sqrt(zt); - alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz; - sum += fac/(sqrtz*(zt+alamb)); - fac=0.25*fac; - xt=0.25*(xt+alamb); - yt=0.25*(yt+alamb); - zt=0.25*(zt+alamb); - ave=0.2*(xt+yt+3.0*zt); - delx=(ave-xt)/ave; - dely=(ave-yt)/ave; - delz=(ave-zt)/ave; - } while (max(fabs(delx),fabs(dely),fabs(delz)) > ERRTOL); - ea=delx*dely; - eb=delz*delz; - ec=ea-eb; - ed=ea-6*eb; - ee=ed+ec+ec; - return 3*sum+fac*(1.0+ed*(-C1+C5*ed-C6*delz*ee) - +delz*(C2*ee+delz*(-C3*ec+delz*C4*ea)))/(ave*sqrt(ave)); -} - -/*<asyxml><function type="real" signature="elle(real,real)"><code></asyxml>*/ + sqrtx = sqrt(xt); + sqrty = sqrt(yt); + sqrtz = sqrt(zt); + alamb = sqrtx * (sqrty + sqrtz) + sqrty * sqrtz; + sum += fac/(sqrtz * (zt + alamb)); + fac = 0.25 * fac; + xt = 0.25 * (xt + alamb); + yt = 0.25 * (yt + alamb); + zt = 0.25 * (zt + alamb); + ave = 0.2 * (xt + yt + 3.0 * zt); + delx = (ave - xt)/ave; + dely = (ave - yt)/ave; + delz = (ave - zt)/ave; + } while (max(fabs(delx), fabs(dely), fabs(delz)) > ERRTOL); + ea = delx * dely; + eb = delz * delz; + ec = ea - eb; + ed = ea - 6 * eb; + ee = ed + ec + ec; + return 3 * sum + fac * (1.0 + ed * (-C1 + C5 * ed - C6 * delz * ee) + +delz * (C2 * ee + delz * (-C3 * ec + delz * C4 * ea)))/(ave * sqrt(ave)); +} + +/*<asyxml><function type = "real" signature = "elle(real, real)"><code></asyxml>*/ real elle(real phi, real k) {/*<asyxml></code><documentation>Legendre elliptic integral of the 2nd kind, evaluated using Carlson's functions RD and RF. - The argument ranges are -infinity < phi < +infinity, 0 <= k*sin(phi) <= 1.</documentation></function></asyxml>*/ + The argument ranges are -infinity < phi < +infinity, 0 <= k * sin(phi) <= 1.</documentation></function></asyxml>*/ real result; if (phi >= 0 && phi <= pi/2) { - real cc,q,s; - s=sin(phi); - cc=cos(phi)^2; - q=(1-s*k)*(1+s*k); - result=s*(rf(cc,q,1)-(s*k)^2*rd(cc,q,1)/3); + real cc, q, s; + s = sin(phi); + cc = cos(phi)^2; + q = (1 - s * k) * (1 + s * k); + result = s * (rf(cc, q, 1) - (s * k)^2 * rd(cc, q, 1)/3); } else if (phi <= pi && phi >= 0) { - result=2*elle(pi/2,k)-elle(pi-phi,k); + result = 2 * elle(pi/2, k) - elle(pi - phi, k); } else - if (phi <= 3*pi/2 && phi >= 0) { - result=2*elle(pi/2,k)+elle(phi-pi,k); + if (phi <= 3 * pi/2 && phi >= 0) { + result = 2 * elle(pi/2, k) + elle(phi - pi, k); } else - if (phi <= 2*pi && phi >= 0) { - result=4*elle(pi/2,k)-elle(2*pi-phi,k); + if (phi <= 2 * pi && phi >= 0) { + result = 4 * elle(pi/2, k) - elle(2 * pi - phi, k); } else if (phi >= 0) { - int nb=floor(0.5*phi/pi); - result=nb*elle(2*pi,k)+elle(phi%(2*pi),k); - } else result=-elle(-phi,k); + int nb = floor(0.5 * phi/pi); + result = nb * elle(2 * pi, k) + elle(phi%(2 * pi), k); + } else result = -elle(-phi, k); return result; } -/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real,real,real,real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "pair[]" signature = "intersectionpoints(pair, pair, real, real, real, real, real, real)"><code></asyxml>*/ pair[] intersectionpoints(pair A, pair B, real a, real b, real c, real d, real f, real g) {/*<asyxml></code><documentation>Intersection points with the line (AB) and the quadric curve - a*x^2+b*x*y+c*y^2+d*x+f*y+g=0 given in the default coordinate system</documentation></function></asyxml>*/ + a * x^2 + b * x * y + c * y^2 + d * x + f * y + g = 0 given in the default coordinate system</documentation></function></asyxml>*/ pair[] op; - real ap=B.y-A.y, - bpp=A.x-B.x, - cp=A.y*B.x-A.x*B.y; + real ap = B.y - A.y, + bpp = A.x - B.x, + cp = A.y * B.x - A.x * B.y; real sol[]; if (abs(ap) > epsgeo) { - real aa=ap*c+a*bpp^2/ap-b*bpp, - bb=ap*f-bpp*d+2*a*bpp*cp/ap-b*cp, - cc=ap*g-cp*d+a*cp^2/ap; - sol=quadraticroots(aa,bb,cc); - for (int i=0; i<sol.length; ++i) { - op.push((-bpp*sol[i]/ap-cp/ap,sol[i])); + real aa = ap * c + a * bpp^2/ap - b * bpp, + bb = ap * f - bpp * d + 2 * a * bpp * cp/ap - b * cp, + cc = ap * g - cp * d + a * cp^2/ap; + sol = quadraticroots(aa, bb, cc); + for (int i = 0; i < sol.length; ++i) { + op.push((-bpp * sol[i]/ap - cp/ap, sol[i])); } } else { - real aa=a*bpp, - bb=d*bpp-b*cp, - cc=g*bpp-cp*f+c*cp^2/bpp; - sol=quadraticroots(aa,bb,cc); - for (int i=0; i<sol.length; ++i) { - op.push((sol[i],-cp/bpp)); + real aa = a * bpp, + bb = d * bpp - b * cp, + cc = g * bpp - cp * f + c * cp^2/bpp; + sol = quadraticroots(aa, bb, cc); + for (int i = 0; i < sol.length; ++i) { + op.push((sol[i], -cp/bpp)); } } return op; } -/*<asyxml><function type="pair[]" signature="intersectionpoints(pair,pair,real[])"><code></asyxml>*/ +/*<asyxml><function type = "pair[]" signature = "intersectionpoints(pair, pair, real[])"><code></asyxml>*/ pair[] intersectionpoints(pair A, pair B, real[] equation) {/*<asyxml></code><documentation>Return the intersection points of the line AB with the conic whose an equation is - equation[0]*x^2+equation[1]*x*y+equation[2]*y^2+equation[3]*x+equation[4]*y+equation[5]=0</documentation></function></asyxml>*/ + equation[0] * x^2 + equation[1] * x * y + equation[2] * y^2 + equation[3] * x + equation[4] * y + equation[5] = 0</documentation></function></asyxml>*/ if(equation.length != 6) abort("intersectionpoints: bad length of array for a conic equation."); return intersectionpoints(A, B, equation[0], equation[1], equation[2], equation[3], equation[4], equation[5]); @@ -230,194 +230,194 @@ pair[] intersectionpoints(pair A, pair B, real[] equation) // *=======================================================* // *......................COORDINATES......................* -real EPS=sqrt(realEpsilon); +real EPS = sqrt(realEpsilon); -/*<asyxml><typedef type="convert" return="pair" params="pair"><code></asyxml>*/ +/*<asyxml><typedef type = "convert" return = "pair" params = "pair"><code></asyxml>*/ typedef pair convert(pair);/*<asyxml></code><documentation>Function type to convert pair in an other coordinate system.</documentation></typedef></asyxml>*/ -/*<asyxml><typedef type="abs" return="real" params="pair"><code></asyxml>*/ +/*<asyxml><typedef type = "abs" return = "real" params = "pair"><code></asyxml>*/ typedef real abs(pair);/*<asyxml></code><documentation>Function type to calculate modulus of pair.</documentation></typedef></asyxml>*/ -/*<asyxml><typedef type="dot" return="real" params="pair,pair"><code></asyxml>*/ -typedef real dot(pair,pair);/*<asyxml></code><documentation>Function type to calculate dot product.</documentation></typedef></asyxml>*/ -/*<asyxml><typedef type="polar" return="pair" params="real,real"><code></asyxml>*/ -typedef pair polar(real,real);/*<asyxml></code><documentation>Function type to calculate the coordinates from the polar coordinates.</documentation></typedef></asyxml>*/ +/*<asyxml><typedef type = "dot" return = "real" params = "pair, pair"><code></asyxml>*/ +typedef real dot(pair, pair);/*<asyxml></code><documentation>Function type to calculate dot product.</documentation></typedef></asyxml>*/ +/*<asyxml><typedef type = "polar" return = "pair" params = "real, real"><code></asyxml>*/ +typedef pair polar(real, real);/*<asyxml></code><documentation>Function type to calculate the coordinates from the polar coordinates.</documentation></typedef></asyxml>*/ -/*<asyxml><struct signature="coordsys"><code></asyxml>*/ +/*<asyxml><struct signature = "coordsys"><code></asyxml>*/ struct coordsys {/*<asyxml></code><documentation>This structure represents a coordinate system in the plane.</documentation></asyxml>*/ - /*<asyxml><method type="pair" signature="relativetodefault(pair)"><code></asyxml>*/ - restricted convert relativetodefault=new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to this coordinate system to + /*<asyxml><method type = "pair" signature = "relativetodefault(pair)"><code></asyxml>*/ + restricted convert relativetodefault = new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to this coordinate system to the pair relatively to the default coordinate system.</documentation></method></asyxml>*/ - /*<asyxml><method type="pair" signature="defaulttorelativet(pair)"><code></asyxml>*/ - restricted convert defaulttorelative=new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to the default coordinate system to + /*<asyxml><method type = "pair" signature = "defaulttorelativet(pair)"><code></asyxml>*/ + restricted convert defaulttorelative = new pair(pair m){return m;};/*<asyxml></code><documentation>Convert a pair given relatively to the default coordinate system to the pair relatively to this coordinate system.</documentation></method></asyxml>*/ - /*<asyxml><method type="real" signature="dot(pair,pair)"><code></asyxml>*/ - restricted dot dot=new real(pair m, pair n){return dot(m,n);};/*<asyxml></code><documentation>Return the dot product of this coordinate system.</documentation></method></asyxml>*/ - /*<asyxml><method type="real" signature="abs(pair)"><code></asyxml>*/ - restricted abs abs=new real(pair m){return abs(m);};/*<asyxml></code><documentation>Return the modulus of a pair in this coordinate system.</documentation></method></asyxml>*/ - /*<asyxml><method type="pair" signature="polar(real,real)"><code></asyxml>*/ - restricted polar polar=new pair(real r, real a){return (r*cos(a),r*sin(a));};/*<asyxml></code><documentation>Polar coordinates routine of this coordinate system.</documentation></method></asyxml>*/ - /*<asyxml><property type="pair" signature="O, i, j"><code></asyxml>*/ - restricted pair O=(0,0), i=(1,0), j=(0,1);/*<asyxml></code><documentation>Origin and units vector.</documentation></property></asyxml>*/ - /*<asyxml><method type="void" signature="init(convert,convert,polar,dot)"><code></asyxml>*/ + /*<asyxml><method type = "real" signature = "dot(pair, pair)"><code></asyxml>*/ + restricted dot dot = new real(pair m, pair n){return dot(m, n);};/*<asyxml></code><documentation>Return the dot product of this coordinate system.</documentation></method></asyxml>*/ + /*<asyxml><method type = "real" signature = "abs(pair)"><code></asyxml>*/ + restricted abs abs = new real(pair m){return abs(m);};/*<asyxml></code><documentation>Return the modulus of a pair in this coordinate system.</documentation></method></asyxml>*/ + /*<asyxml><method type = "pair" signature = "polar(real, real)"><code></asyxml>*/ + restricted polar polar = new pair(real r, real a){return (r * cos(a), r * sin(a));};/*<asyxml></code><documentation>Polar coordinates routine of this coordinate system.</documentation></method></asyxml>*/ + /*<asyxml><property type = "pair" signature = "O, i, j"><code></asyxml>*/ + restricted pair O = (0, 0), i = (1, 0), j = (0, 1);/*<asyxml></code><documentation>Origin and units vector.</documentation></property></asyxml>*/ + /*<asyxml><method type = "void" signature = "init(convert, convert, polar, dot)"><code></asyxml>*/ void init(convert rtd, convert dtr, polar polar, dot dot) {/*<asyxml></code><documentation>The default constructor of the coordinate system.</documentation></method></asyxml>*/ - this.relativetodefault=rtd; - this.defaulttorelative=dtr; - this.polar=polar; - this.dot=dot; - this.abs=new real(pair m){return sqrt(dot(m,m));};; - this.O=rtd((0,0)); - this.i=rtd((1,0))-O; - this.j=rtd((0,1))-O; + this.relativetodefault = rtd; + this.defaulttorelative = dtr; + this.polar = polar; + this.dot = dot; + this.abs = new real(pair m){return sqrt(dot(m, m));};; + this.O = rtd((0, 0)); + this.i = rtd((1, 0)) - O; + this.j = rtd((0, 1)) - O; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><operator type="bool" signature="==(coordsys,coordsys)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "==(coordsys, coordsys)"><code></asyxml>*/ bool operator ==(coordsys c1, coordsys c2) {/*<asyxml></code><documentation>Return true iff the coordinate system have the same origin and units vector.</documentation></operator></asyxml>*/ return c1.O == c2.O && c1.i == c2.i && c1.j == c2.j; } -/*<asyxml><function type="coordsys" signature="cartesiansystem(pair,pair,pair)"><code></asyxml>*/ -coordsys cartesiansystem(pair O=(0,0), pair i, pair j) +/*<asyxml><function type = "coordsys" signature = "cartesiansystem(pair, pair, pair)"><code></asyxml>*/ +coordsys cartesiansystem(pair O = (0, 0), pair i, pair j) {/*<asyxml></code><documentation>Return the Cartesian coordinate system (O, i, j).</documentation></function></asyxml>*/ coordsys R; - real[][] P={{0,0},{0,0}}; + real[][] P = {{0, 0}, {0, 0}}; real[][] iP; - P[0][0]=i.x; - P[0][1]=j.x; - P[1][0]=i.y; - P[1][1]=j.y; - iP=inverse(P); - real ni=abs(i); - real nj=abs(j); - real ij=angle(j)-angle(i); + P[0][0] = i.x; + P[0][1] = j.x; + P[1][0] = i.y; + P[1][1] = j.y; + iP = inverse(P); + real ni = abs(i); + real nj = abs(j); + real ij = angle(j) - angle(i); pair rtd(pair m) { - return O+(P[0][0]*m.x+P[0][1]*m.y,P[1][0]*m.x+P[1][1]*m.y); + return O + (P[0][0] * m.x + P[0][1] * m.y, P[1][0] * m.x + P[1][1] * m.y); } pair dtr(pair m) { m-=O; - return (iP[0][0]*m.x+iP[0][1]*m.y,iP[1][0]*m.x+iP[1][1]*m.y); + return (iP[0][0] * m.x + iP[0][1] * m.y, iP[1][0] * m.x + iP[1][1] * m.y); } pair polar(real r, real a) { - real ca=sin(ij-a)/(ni*sin(ij)); - real sa=sin(a)/(nj*sin(ij)); - return r*(ca,sa); + real ca = sin(ij - a)/(ni * sin(ij)); + real sa = sin(a)/(nj * sin(ij)); + return r * (ca, sa); } real tdot(pair m, pair n) { - return m.x*n.x*ni^2+m.y*n.y*nj^2+(m.x*n.y+n.x*m.y)*dot(i,j); + return m.x * n.x * ni^2 + m.y * n.y * nj^2 + (m.x * n.y + n.x * m.y) * dot(i, j); } - R.init(rtd,dtr,polar,tdot); + R.init(rtd, dtr, polar, tdot); return R; } -/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,coordsys,pen,pen,pen,pen,pen)"><code></asyxml>*/ -void show(picture pic=currentpicture, Label lo="$O$", - Label li="$\vec{\imath}$", - Label lj="$\vec{\jmath}$", +/*<asyxml><function type = "void" signature = "show(picture, Label, Label, Label, coordsys, pen, pen, pen, pen, pen)"><code></asyxml>*/ +void show(picture pic = currentpicture, Label lo = "$O$", + Label li = "$\vec{\imath}$", + Label lj = "$\vec{\jmath}$", coordsys R, - pen dotpen=currentpen, pen xpen=currentpen, pen ypen=xpen, - pen ipen=red, - pen jpen=ipen, - arrowbar arrow=Arrow) -{/*<asyxml></code><documentation>Draw the components (O, i, j, x-axis, y-axis) of 'R'.</documentation></function></asyxml>*/ + pen dotpen = currentpen, pen xpen = currentpen, pen ypen = xpen, + pen ipen = red, + pen jpen = ipen, + arrowbar arrow = Arrow) +{/*<asyxml></code><documentation>Draw the components (O, i, j, x - axis, y - axis) of 'R'.</documentation></function></asyxml>*/ unravel R; - dot(pic,O,dotpen); - drawline(pic,O,O+i,xpen); - drawline(pic,O,O+j,ypen); - draw(pic,li,O--(O+i),ipen,arrow); - Label lj=lj.copy(); - lj.align(lj.align,unit(I*j)); - draw(pic,lj,O--(O+j),jpen,arrow); - draw(pic,lj,O--(O+j),jpen,arrow); - Label lo=lo.copy(); - lo.align(lo.align,-2*dir(O--O+i,O--O+j)); + dot(pic, O, dotpen); + drawline(pic, O, O + i, xpen); + drawline(pic, O, O + j, ypen); + draw(pic, li, O--(O + i), ipen, arrow); + Label lj = lj.copy(); + lj.align(lj.align, unit(I * j)); + draw(pic, lj, O--(O + j), jpen, arrow); + draw(pic, lj, O--(O + j), jpen, arrow); + Label lo = lo.copy(); + lo.align(lo.align, -2 * dir(O--O + i, O--O + j)); lo.p(dotpen); - label(pic,lo,O); + label(pic, lo, O); } -/*<asyxml><operator type="pair" signature="/(pair,coordsys)"><code></asyxml>*/ +/*<asyxml><operator type = "pair" signature = "/(pair, coordsys)"><code></asyxml>*/ pair operator /(pair p, coordsys R) -{/*<asyxml></code><documentation>Return the xy-coordinates of 'p' relatively to +{/*<asyxml></code><documentation>Return the xy - coordinates of 'p' relatively to the coordinate system 'R'. - For example, if R=cartesiansystem((1,2),(1,0),(0,1)), (0,0)/R is (-1,-2).</documentation></operator></asyxml>*/ + For example, if R = cartesiansystem((1, 2), (1, 0), (0, 1)), (0, 0)/R is (-1, -2).</documentation></operator></asyxml>*/ return R.defaulttorelative(p); } -/*<asyxml><operator type="pair" signature="*(coordsys,pair)"><code></asyxml>*/ +/*<asyxml><operator type = "pair" signature = "*(coordsys, pair)"><code></asyxml>*/ pair operator *(coordsys R, pair p) {/*<asyxml></code><documentation>Return the coordinates of 'p' given in the - xy-coordinates 'R'. - For example, if R=cartesiansystem((1,2),(1,0),(0,1)), R*(0,0) is (1,2).</documentation></operator></asyxml>*/ + xy - coordinates 'R'. + For example, if R = cartesiansystem((1, 2), (1, 0), (0, 1)), R * (0, 0) is (1, 2).</documentation></operator></asyxml>*/ return R.relativetodefault(p); } -/*<asyxml><operator type="path" signature="*(coordsys,path)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "*(coordsys, path)"><code></asyxml>*/ path operator *(coordsys R, path g) -{/*<asyxml></code><documentation>Return the reconstructed path applying R*pair to each node, pre and post control point of 'g'.</documentation></operator></asyxml>*/ - guide og=R*point(g,0); - real l=length(g); - for(int i=1; i <= l; ++i) +{/*<asyxml></code><documentation>Return the reconstructed path applying R * pair to each node, pre and post control point of 'g'.</documentation></operator></asyxml>*/ + guide og = R * point(g, 0); + real l = length(g); + for(int i = 1; i <= l; ++i) { - pair P=R*point(g,i); - pair post=R*postcontrol(g,i-1); - pair pre=R*precontrol(g,i); + pair P = R * point(g, i); + pair post = R * postcontrol(g, i - 1); + pair pre = R * precontrol(g, i); if(i == l && (cyclic(g))) - og=og..controls post and pre..cycle; + og = og..controls post and pre..cycle; else - og=og..controls post and pre..P; + og = og..controls post and pre..P; } return og; } -/*<asyxml><operator type="coordsys" signature="*(transform,coordsys)"><code></asyxml>*/ +/*<asyxml><operator type = "coordsys" signature = "*(transform, coordsys)"><code></asyxml>*/ coordsys operator *(transform t, coordsys R) -{/*<asyxml></code><documentation>Provide transform*coordsys. +{/*<asyxml></code><documentation>Provide transform * coordsys. Note that shiftless(t) is applied to R.i and R.j.</documentation></operator></asyxml>*/ coordsys oc; - oc=cartesiansystem(t*R.O,shiftless(t)*R.i,shiftless(t)*R.j); + oc = cartesiansystem(t * R.O, shiftless(t) * R.i, shiftless(t) * R.j); return oc; } -/*<asyxml><constant type="coordsys" signature="defaultcoordsys"><code></asyxml>*/ -restricted coordsys defaultcoordsys=cartesiansystem(0,(1,0),(0,1));/*<asyxml></code><documentation>One can always refer to the default coordinate system using this constant.</documentation></constant></asyxml>*/ -/*<asyxml><variable type="coordsys" signature="currentcoordsys"><code></asyxml>*/ -coordsys currentcoordsys=defaultcoordsys;/*<asyxml></code><documentation>The coordinate system used by default.</documentation></variable></asyxml>*/ +/*<asyxml><constant type = "coordsys" signature = "defaultcoordsys"><code></asyxml>*/ +restricted coordsys defaultcoordsys = cartesiansystem(0, (1, 0), (0, 1));/*<asyxml></code><documentation>One can always refer to the default coordinate system using this constant.</documentation></constant></asyxml>*/ +/*<asyxml><variable type = "coordsys" signature = "currentcoordsys"><code></asyxml>*/ +coordsys currentcoordsys = defaultcoordsys;/*<asyxml></code><documentation>The coordinate system used by default.</documentation></variable></asyxml>*/ -/*<asyxml><struct signature="point"><code></asyxml>*/ +/*<asyxml><struct signature = "point"><code></asyxml>*/ struct point {/*<asyxml></code><documentation>This structure replaces the pair to embed its coordinate system. - For example, if 'P=point(cartesiansystem((1,2),i,j), (0,0))', - P is equal to the pair (1,2).</documentation></asyxml>*/ - /*<asyxml><property type="coordsys" signature="coordsys"><code></asyxml>*/ - coordsys coordsys;/*<asyxml></code><documentation>The coordinate system of this point.</documentation></property><property type="pair" signature="coordinates"><code></asyxml>*/ - restricted pair coordinates;/*<asyxml></code><documentation>The coordinates of this point relatively to the coordinate system 'coordsys'.</documentation></property><property type="real" signature="x,y"><code></asyxml>*/ + For example, if 'P = point(cartesiansystem((1, 2), i, j), (0, 0))', + P is equal to the pair (1, 2).</documentation></asyxml>*/ + /*<asyxml><property type = "coordsys" signature = "coordsys"><code></asyxml>*/ + coordsys coordsys;/*<asyxml></code><documentation>The coordinate system of this point.</documentation></property><property type = "pair" signature = "coordinates"><code></asyxml>*/ + restricted pair coordinates;/*<asyxml></code><documentation>The coordinates of this point relatively to the coordinate system 'coordsys'.</documentation></property><property type = "real" signature = "x, y"><code></asyxml>*/ restricted real x, y;/*<asyxml></code><documentation>The xpart and the ypart of 'coordinates'.</documentation></property></asyxml>*/ - /*<asyxml><method type="" signature="init(coordsys,pair)"><code><property type="real" signature="m"><code></asyxml>*/ - real m=1;/*<asyxml></code><documentation>Used to cast mass<->point.</documentation></property></asyxml>*/ + /*<asyxml><method type = "" signature = "init(coordsys, pair)"><code><property type = "real" signature = "m"><code></asyxml>*/ + real m = 1;/*<asyxml></code><documentation>Used to cast mass<->point.</documentation></property></asyxml>*/ void init(coordsys R, pair coordinates, real mass) {/*<asyxml></code><documentation>The constructor.</documentation></method></asyxml>*/ - this.coordsys=R; - this.coordinates=coordinates; - this.x=coordinates.x; - this.y=coordinates.y; - this.m=mass; + this.coordsys = R; + this.coordinates = coordinates; + this.x = coordinates.x; + this.y = coordinates.y; + this.m = mass; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="point" signature="point(coordsys,pair,real)"><code></asyxml>*/ -point point(coordsys R, pair p, real m=1) +/*<asyxml><function type = "point" signature = "point(coordsys, pair, real)"><code></asyxml>*/ +point point(coordsys R, pair p, real m = 1) {/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the coordinate system 'R' and the mass 'm'.</documentation></function></asyxml>*/ point op; @@ -425,7 +425,7 @@ point point(coordsys R, pair p, real m=1) return op; } -/*<asyxml><function type="point" signature="point(explicit pair,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit pair, real)"><code></asyxml>*/ point point(explicit pair p, real m) {/*<asyxml></code><documentation>Return the point which has the coodinates 'p' in the current coordinate system and the mass 'm'.</documentation></function></asyxml>*/ @@ -434,8 +434,8 @@ point point(explicit pair p, real m) return op; } -/*<asyxml><function type="point" signature="point(coordsys,explicit point,real)"><code></asyxml>*/ -point point(coordsys R, explicit point M, real m=M.m) +/*<asyxml><function type = "point" signature = "point(coordsys, explicit point, real)"><code></asyxml>*/ +point point(coordsys R, explicit point M, real m = M.m) {/*<asyxml></code><documentation>Return the point of 'R' which has the coordinates of 'M' and the mass 'm'. Do not confuse this routine with the further routine 'changecoordsys'.</documentation></function></asyxml>*/ point op; @@ -443,32 +443,32 @@ point point(coordsys R, explicit point M, real m=M.m) return op; } -/*<asyxml><function type="point" signature="changecoordsys(coordsys,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "changecoordsys(coordsys, point)"><code></asyxml>*/ point changecoordsys(coordsys R, point M) {/*<asyxml></code><documentation>Return the point 'M' in the coordinate system 'coordsys'. In other words, the returned point marks the same plot as 'M' does.</documentation></function></asyxml>*/ point op; - coordsys mco=M.coordsys; + coordsys mco = M.coordsys; op.init(R, R.defaulttorelative(mco.relativetodefault(M.coordinates)), M.m); return op; } -/*<asyxml><function type="pair" signature="pair coordinates(point)"><code></asyxml>*/ +/*<asyxml><function type = "pair" signature = "pair coordinates(point)"><code></asyxml>*/ pair coordinates(point M) {/*<asyxml></code><documentation>Return the coordinates of 'M' in its coordinate system.</documentation></function></asyxml>*/ return M.coordinates; } -/*<asyxml><function type="bool" signature="bool samecoordsys(bool...point[])"><code></asyxml>*/ -bool samecoordsys(bool warn=true ... point[] M) +/*<asyxml><function type = "bool" signature = "bool samecoordsys(bool...point[])"><code></asyxml>*/ +bool samecoordsys(bool warn = true ... point[] M) {/*<asyxml></code><documentation>Return true iff all the points have the same coordinate system. If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/ - bool ret=true; - coordsys t=M[0].coordsys; - for (int i=1; i < M.length; ++i) { - ret=(t == M[i].coordsys); + bool ret = true; + coordsys t = M[0].coordsys; + for (int i = 1; i < M.length; ++i) { + ret = (t == M[i].coordsys); if(!ret) break; - t=M[i].coordsys; + t = M[i].coordsys; } if(warn && !ret) warning("coodinatesystem", @@ -477,588 +477,588 @@ The operation will be done relative to the default coordinate system."); return ret; } -/*<asyxml><function type="point[]" signature="standardizecoordsys(coordsys,bool...point[])"><code></asyxml>*/ -point[] standardizecoordsys(coordsys R=currentcoordsys, - bool warn=true ... point[] M) +/*<asyxml><function type = "point[]" signature = "standardizecoordsys(coordsys, bool...point[])"><code></asyxml>*/ +point[] standardizecoordsys(coordsys R = currentcoordsys, + bool warn = true ... point[] M) {/*<asyxml></code><documentation>Return the points with the same coordinate system 'R'. If 'warn' is true and the coordinate systems are different, a warning is sent.</documentation></function></asyxml>*/ - point[] op=new point[]; - op=M; + point[] op = new point[]; + op = M; if(!samecoordsys(warn ... M)) - for (int i=1; i < M.length; ++i) - op[i]=changecoordsys(R,M[i]); + for (int i = 1; i < M.length; ++i) + op[i] = changecoordsys(R, M[i]); return op; } -/*<asyxml><operator type="pair" signature="cast(point)"><code></asyxml>*/ +/*<asyxml><operator type = "pair" signature = "cast(point)"><code></asyxml>*/ pair operator cast(point P) {/*<asyxml></code><documentation>Cast point to pair.</documentation></operator></asyxml>*/ return P.coordsys.relativetodefault(P.coordinates); } -/*<asyxml><operator type="pair[]" signature="cast(point[])"><code></asyxml>*/ +/*<asyxml><operator type = "pair[]" signature = "cast(point[])"><code></asyxml>*/ pair[] operator cast(point[] P) {/*<asyxml></code><documentation>Cast point[] to pair[].</documentation></operator></asyxml>*/ pair[] op; - for (int i=0; i<P.length; ++i) { + for (int i = 0; i < P.length; ++i) { op.push((pair)P[i]); } return op; } -/*<asyxml><operator type="point" signature="cast(pair)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "cast(pair)"><code></asyxml>*/ point operator cast(pair p) {/*<asyxml></code><documentation>Cast pair to point relatively to the current coordinate system 'currentcoordsys'.</documentation></operator></asyxml>*/ - return point(currentcoordsys,p); + return point(currentcoordsys, p); } -/*<asyxml><operator type="point[]" signature="cast(pair[])"><code></asyxml>*/ +/*<asyxml><operator type = "point[]" signature = "cast(pair[])"><code></asyxml>*/ point[] operator cast(pair[] p) {/*<asyxml></code><documentation>Cast pair[] to point[] relatively to the current coordinate system 'currentcoordsys'.</documentation></operator></asyxml>*/ pair[] op; - for (int i=0; i<p.length; ++i) { + for (int i = 0; i < p.length; ++i) { op.push((point)p[i]); } return op; } -/*<asyxml><function type="pair" signature="locate(point)"><code></asyxml>*/ +/*<asyxml><function type = "pair" signature = "locate(point)"><code></asyxml>*/ pair locate(point P) {/*<asyxml></code><documentation>Return the coordinates of 'P' in the default coordinate system.</documentation></function></asyxml>*/ - return P.coordsys*P.coordinates; + return P.coordsys * P.coordinates; } -/*<asyxml><function type="point" signature="locate(pair)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "locate(pair)"><code></asyxml>*/ point locate(pair p) {/*<asyxml></code><documentation>Return the point in the current coordinate system 'currentcoordsys'.</documentation></function></asyxml>*/ return p; //automatic casting 'pair to point'. } -/*<asyxml><operator type="point" signature="*(real, explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "*(real, explicit point)"><code></asyxml>*/ point operator *(real x, explicit point P) {/*<asyxml></code><documentation>Multiply the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/ - return point(P.coordsys,x*P.coordinates,P.m); + return point(P.coordsys, x * P.coordinates, P.m); } -/*<asyxml><operator type="point" signature="/(explicit point, real)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "/(explicit point, real)"><code></asyxml>*/ point operator /(explicit point P, real x) {/*<asyxml></code><documentation>Divide the coordinates (not the mass) of 'P' by 'x'.</documentation></operator></asyxml>*/ - return point(P.coordsys,P.coordinates/x,P.m); + return point(P.coordsys, P.coordinates/x, P.m); } -/*<asyxml><operator type="point" signature="/(real,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "/(real, explicit point)"><code></asyxml>*/ point operator /(real x, explicit point P) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return point(P.coordsys,x/P.coordinates,P.m); + return point(P.coordsys, x/P.coordinates, P.m); } -/*<asyxml><operator type="point" signature="-(explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "-(explicit point)"><code></asyxml>*/ point operator -(explicit point P) {/*<asyxml></code><documentation>-P. The mass is inchanged.</documentation></operator></asyxml>*/ - return point(P.coordsys,-P.coordinates, P.m); + return point(P.coordsys, -P.coordinates, P.m); } -/*<asyxml><operator type="point" signature="+(explicit point,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "+(explicit point, explicit point)"><code></asyxml>*/ point operator +(explicit point P1, explicit point P2) -{/*<asyxml></code><documentation>Provide 'point+point'. +{/*<asyxml></code><documentation>Provide 'point + point'. If the two points haven't the same coordinate system, a warning is sent and the returned point has the default coordinate system 'defaultcoordsys'. The masses are added.</documentation></operator></asyxml>*/ - point[] P=standardizecoordsys(P1,P2); - coordsys R=P[0].coordsys; - return point(R,P[0].coordinates+P[1].coordinates, P1.m+P2.m); + point[] P = standardizecoordsys(P1, P2); + coordsys R = P[0].coordsys; + return point(R, P[0].coordinates + P[1].coordinates, P1.m + P2.m); } -/*<asyxml><operator type="point" signature="+(explicit point,explicit pair)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "+(explicit point, explicit pair)"><code></asyxml>*/ point operator +(explicit point P1, explicit pair p2) -{/*<asyxml></code><documentation>Provide 'point+pair'. +{/*<asyxml></code><documentation>Provide 'point + pair'. The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'. The mass is not changed.</documentation></operator></asyxml>*/ - coordsys R=currentcoordsys; - return point(R,P1.coordinates+point(R,p2).coordinates, P1.m); + coordsys R = currentcoordsys; + return point(R, P1.coordinates + point(R, p2).coordinates, P1.m); } point operator +(explicit pair p1, explicit point p2) { - return p2+p1; + return p2 + p1; } -/*<asyxml><operator type="point" signature="-(explicit point,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "-(explicit point, explicit point)"><code></asyxml>*/ point operator -(explicit point P1, explicit point P2) -{/*<asyxml></code><documentation>Provide 'point-point'.</documentation></operator></asyxml>*/ - return P1+(-P2); +{/*<asyxml></code><documentation>Provide 'point - point'.</documentation></operator></asyxml>*/ + return P1 + (-P2); } -/*<asyxml><operator type="point" signature="-(explicit point,explicit pair)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "-(explicit point, explicit pair)"><code></asyxml>*/ point operator -(explicit point P1, explicit pair p2) -{/*<asyxml></code><documentation>Provide 'point-pair'. +{/*<asyxml></code><documentation>Provide 'point - pair'. The pair 'p2' is supposed to be coordinates relatively to the coordinates system of 'P1'.</documentation></operator></asyxml>*/ - return P1+(-p2); + return P1 + (-p2); } point operator -(explicit pair p1, explicit point P2) { - return p1+(-P2); + return p1 + (-P2); } -/*<asyxml><operator type="point" signature="*(transform,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "*(transform, explicit point)"><code></asyxml>*/ point operator *(transform t, explicit point P) -{/*<asyxml></code><documentation>Provide 'transform*point'. +{/*<asyxml></code><documentation>Provide 'transform * point'. Note that the transforms scale, xscale, yscale and rotate are carried out relatively the default coordinate system 'defaultcoordsys' which is not desired for point defined in an other coordinate system. - On can use scale(real,point), xscale(real,point), yscale(real,point), rotate(real,point), + On can use scale(real, point), xscale(real, point), yscale(real, point), rotate(real, point), scaleO(real), xscaleO(real), yscaleO(real) and rotateO(real) (described further) to change the coordinate system of reference.</documentation></operator></asyxml>*/ - coordsys R=P.coordsys; - return point(R,(t*locate(P))/R, P.m); + coordsys R = P.coordsys; + return point(R, (t * locate(P))/R, P.m); } -/*<asyxml><operator type="point" signature="*(explicit point,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "*(explicit point, explicit point)"><code></asyxml>*/ point operator *(explicit point P1, explicit point P2) -{/*<asyxml></code><documentation>Provide 'point*point'. +{/*<asyxml></code><documentation>Provide 'point * point'. The resulted mass is the mass of P2</documentation></operator></asyxml>*/ - point[] P=standardizecoordsys(P1,P2); - coordsys R=P[0].coordsys; - return point(R,P[0].coordinates*P[1].coordinates, P2.m); + point[] P = standardizecoordsys(P1, P2); + coordsys R = P[0].coordsys; + return point(R, P[0].coordinates * P[1].coordinates, P2.m); } -/*<asyxml><operator type="point" signature="*(explicit point,explicit pair)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "*(explicit point, explicit pair)"><code></asyxml>*/ point operator *(explicit point P1, explicit pair p2) -{/*<asyxml></code><documentation>Provide 'point*pair'. +{/*<asyxml></code><documentation>Provide 'point * pair'. The pair 'p2' is supposed to be the coordinates of the point in the coordinates system of 'P1'. - 'pair*point' is also defined.</documentation></operator></asyxml>*/ - point P=point(P1.coordsys,p2, P1.m); - return P1*P; + 'pair * point' is also defined.</documentation></operator></asyxml>*/ + point P = point(P1.coordsys, p2, P1.m); + return P1 * P; } point operator *(explicit pair p1, explicit point p2) { - return p2*p1; + return p2 * p1; } -/*<asyxml><operator type="bool" signature="==(explicit point, explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "==(explicit point, explicit point)"><code></asyxml>*/ bool operator ==(explicit point M, explicit point N) {/*<asyxml></code><documentation>Provide the test 'M == N' wish returns true iff MN < EPS</documentation></operator></asyxml>*/ - return abs(locate(M)-locate(N)) < EPS; + return abs(locate(M) - locate(N)) < EPS; } -/*<asyxml><operator type="bool" signature="!=(explicit point, explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "!=(explicit point, explicit point)"><code></asyxml>*/ bool operator !=(explicit point M, explicit point N) {/*<asyxml></code><documentation>Provide the test 'M != N' wish return true iff MN >= EPS</documentation></operator></asyxml>*/ return !(M == N); } -/*<asyxml><operator type="guide" signature="cast(point)"><code></asyxml>*/ +/*<asyxml><operator type = "guide" signature = "cast(point)"><code></asyxml>*/ guide operator cast(point p) {/*<asyxml></code><documentation>Cast point to guide.</documentation></operator></asyxml>*/ return locate(p); } -/*<asyxml><operator type="path" signature="cast(point)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(point)"><code></asyxml>*/ path operator cast(point p) {/*<asyxml></code><documentation>Cast point to path.</documentation></operator></asyxml>*/ return locate(p); } -/*<asyxml><function type="void" signature="dot(picture,Label,explicit point,align,string,pen)"><code></asyxml>*/ -void dot(picture pic=currentpicture, Label L, explicit point Z, - align align=NoAlign, - string format=defaultformat, pen p=currentpen) +/*<asyxml><function type = "void" signature = "dot(picture, Label, explicit point, align, string, pen)"><code></asyxml>*/ +void dot(picture pic = currentpicture, Label L, explicit point Z, + align align = NoAlign, + string format = defaultformat, pen p = currentpen) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - Label L=L.copy(); + Label L = L.copy(); L.position(locate(Z)); if(L.s == "") { - if(format == "") format=defaultformat; - L.s="("+format(format,Z.x)+","+format(format,Z.y)+")"; + if(format == "") format = defaultformat; + L.s = "("+format(format, Z.x)+", "+format(format, Z.y)+")"; } - L.align(align,E); + L.align(align, E); L.p(p); - dot(pic,locate(Z),p); - add(pic,L); + dot(pic, locate(Z), p); + add(pic, L); } -/*<asyxml><function type="real" signature="abs(coordsys,pair)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "abs(coordsys, pair)"><code></asyxml>*/ real abs(coordsys R, pair m) {/*<asyxml></code><documentation>Return the modulus |m| in the coordinate system 'R'.</documentation></function></asyxml>*/ return R.abs(m); } -/*<asyxml><function type="real" signature="abs(explicit point)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "abs(explicit point)"><code></asyxml>*/ real abs(explicit point M) {/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system.</documentation></function></asyxml>*/ return M.coordsys.abs(M.coordinates); } -/*<asyxml><function type="real" signature="length(explicit point)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "length(explicit point)"><code></asyxml>*/ real length(explicit point M) {/*<asyxml></code><documentation>Return the modulus |M| in its coordinate system (same as 'abs').</documentation></function></asyxml>*/ return M.coordsys.abs(M.coordinates); } -/*<asyxml><function type="point" signature="conj(explicit point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "conj(explicit point)"><code></asyxml>*/ point conj(explicit point M) {/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/ - return point(M.coordsys,conj(M.coordinates), M.m); + return point(M.coordsys, conj(M.coordinates), M.m); } -/*<asyxml><function type="real" signature="degrees(explicit point,coordsys,bool)"><code></asyxml>*/ -real degrees(explicit point M, coordsys R=M.coordsys, bool warn=true) +/*<asyxml><function type = "real" signature = "degrees(explicit point, coordsys, bool)"><code></asyxml>*/ +real degrees(explicit point M, coordsys R = M.coordsys, bool warn = true) {/*<asyxml></code><documentation>Return the angle of M (in degrees) relatively to 'R'.</documentation></function></asyxml>*/ - return (degrees(locate(M)-R.O, warn) - degrees(R.i))%360; + return (degrees(locate(M) - R.O, warn) - degrees(R.i))%360; } -/*<asyxml><function type="real" signature="angle(explicit point,coordsys,bool)"><code></asyxml>*/ -real angle(explicit point M, coordsys R=M.coordsys, bool warn=true) +/*<asyxml><function type = "real" signature = "angle(explicit point, coordsys, bool)"><code></asyxml>*/ +real angle(explicit point M, coordsys R = M.coordsys, bool warn = true) {/*<asyxml></code><documentation>Return the angle of M (in radians) relatively to 'R'.</documentation></function></asyxml>*/ - return radians(degrees(M,R,warn)); + return radians(degrees(M, R, warn)); } -/*<asyxml><function type="bool" signature="finite(explicit point)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "finite(explicit point)"><code></asyxml>*/ bool finite(explicit point p) {/*<asyxml></code><documentation>Avoid to compute 'finite((pair)(infinite_point))'.</documentation></function></asyxml>*/ return finite(p.coordinates); } -/*<asyxml><function type="real" signature="dot(point,point)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "dot(point, point)"><code></asyxml>*/ real dot(point A, point B) {/*<asyxml></code><documentation>Return the dot product in the coordinate system of 'A'.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A.coordsys,A,B); - return P[0].coordsys.dot(P[0].coordinates,P[1].coordinates); + point[] P = standardizecoordsys(A.coordsys, A, B); + return P[0].coordsys.dot(P[0].coordinates, P[1].coordinates); } -/*<asyxml><function type="real" signature="dot(point,explicit pair)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "dot(point, explicit pair)"><code></asyxml>*/ real dot(point A, explicit pair B) {/*<asyxml></code><documentation>Return the dot product in the default coordinate system. - dot(explicit pair,point) is also defined.</documentation></function></asyxml>*/ - return dot(locate(A),B); + dot(explicit pair, point) is also defined.</documentation></function></asyxml>*/ + return dot(locate(A), B); } real dot(explicit pair A, point B) { - return dot(A,locate(B)); + return dot(A, locate(B)); } -/*<asyxml><function type="transforms" signature="rotateO(real)"><code></asyxml>*/ +/*<asyxml><function type = "transforms" signature = "rotateO(real)"><code></asyxml>*/ transform rotateO(real a) {/*<asyxml></code><documentation>Rotation around the origin of the current coordinate system.</documentation></function></asyxml>*/ - return rotate(a,currentcoordsys.O); + return rotate(a, currentcoordsys.O); }; -/*<asyxml><function type="transform" signature="projection(point,point)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "projection(point, point)"><code></asyxml>*/ transform projection(point A, point B) {/*<asyxml></code><documentation>Return the orthogonal projection on the line (AB).</documentation></function></asyxml>*/ - pair dir=unit(locate(A)-locate(B)); - pair a=locate(A); - real cof=dir.x*a.x+dir.y*a.y; - real tx=a.x-dir.x*cof; - real txx=dir.x^2; - real txy=dir.x*dir.y; - real ty=a.y-dir.y*cof; - real tyx=txy; - real tyy=dir.y^2; - transform t=(tx,ty,txx,txy,tyx,tyy); + pair dir = unit(locate(A) - locate(B)); + pair a = locate(A); + real cof = dir.x * a.x + dir.y * a.y; + real tx = a.x - dir.x * cof; + real txx = dir.x^2; + real txy = dir.x * dir.y; + real ty = a.y - dir.y * cof; + real tyx = txy; + real tyy = dir.y^2; + transform t = (tx, ty, txx, txy, tyx, tyy); return t; } -/*<asyxml><function type="transform" signature="projection(point,point,point,point,bool)"><code></asyxml>*/ -transform projection(point A, point B, point C, point D, bool safe=false) +/*<asyxml><function type = "transform" signature = "projection(point, point, point, point, bool)"><code></asyxml>*/ +transform projection(point A, point B, point C, point D, bool safe = false) {/*<asyxml></code><documentation>Return the (CD) parallel projection on (AB). - If 'safe=true' and (AB)//(CD) return the identity. - If 'safe=false' and (AB)//(CD) return an infinity scaling.</documentation></function></asyxml>*/ - pair a=locate(A); - pair u=unit(locate(B)-locate(A)); - pair v=unit(locate(D)-locate(C)); - real c=u.x*a.y-u.y*a.x; - real d=(conj(u)*v).y; + If 'safe = true' and (AB)//(CD) return the identity. + If 'safe = false' and (AB)//(CD) return an infinity scaling.</documentation></function></asyxml>*/ + pair a = locate(A); + pair u = unit(locate(B) - locate(A)); + pair v = unit(locate(D) - locate(C)); + real c = u.x * a.y - u.y * a.x; + real d = (conj(u) * v).y; if (abs(d) < epsgeo) { return safe ? identity() : scale(infinity); } - real tx=c*v.x/d; - real ty=c*v.y/d; - real txx=u.x*v.y/d; - real txy=-u.x*v.x/d; - real tyx=u.y*v.y/d; - real tyy=-u.y*v.x/d; - transform t=(tx,ty,txx,txy,tyx,tyy); + real tx = c * v.x/d; + real ty = c * v.y/d; + real txx = u.x * v.y/d; + real txy = -u.x * v.x/d; + real tyx = u.y * v.y/d; + real tyy = -u.y * v.x/d; + transform t = (tx, ty, txx, txy, tyx, tyy); return t; } -/*<asyxml><function type="transform" signature="scale(real,point)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "scale(real, point)"><code></asyxml>*/ transform scale(real k, point M) {/*<asyxml></code><documentation>Homothety.</documentation></function></asyxml>*/ - pair P=locate(M); - return shift(P)*scale(k)*shift(-P); + pair P = locate(M); + return shift(P) * scale(k) * shift(-P); } -/*<asyxml><function type="transform" signature="xscale(real,point)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "xscale(real, point)"><code></asyxml>*/ transform xscale(real k, point M) -{/*<asyxml></code><documentation>xscale from 'M' relatively to the x-axis of the coordinate system of 'M'.</documentation></function></asyxml>*/ - pair P=locate(M); - real a=degrees(M.coordsys.i); - return (shift(P)*rotate(a))*xscale(k)*(rotate(-a)*shift(-P)); +{/*<asyxml></code><documentation>xscale from 'M' relatively to the x - axis of the coordinate system of 'M'.</documentation></function></asyxml>*/ + pair P = locate(M); + real a = degrees(M.coordsys.i); + return (shift(P) * rotate(a)) * xscale(k) * (rotate(-a) * shift(-P)); } -/*<asyxml><function type="transform" signature="yscale(real,point)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "yscale(real, point)"><code></asyxml>*/ transform yscale(real k, point M) -{/*<asyxml></code><documentation>yscale from 'M' relatively to the y-axis of the coordinate system of 'M'.</documentation></function></asyxml>*/ - pair P=locate(M); - real a=degrees(M.coordsys.j)-90; - return (shift(P)*rotate(a))*yscale(k)*(rotate(-a)*shift(-P)); +{/*<asyxml></code><documentation>yscale from 'M' relatively to the y - axis of the coordinate system of 'M'.</documentation></function></asyxml>*/ + pair P = locate(M); + real a = degrees(M.coordsys.j) - 90; + return (shift(P) * rotate(a)) * yscale(k) * (rotate(-a) * shift(-P)); } -/*<asyxml><function type="transform" signature="scale(real,point,point,point,point,bool)"><code></asyxml>*/ -transform scale(real k, point A, point B, point C, point D, bool safe=false) -{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Affinit%C3%A9_%28math%C3%A9matiques%29"/> +/*<asyxml><function type = "transform" signature = "scale(real, point, point, point, point, bool)"><code></asyxml>*/ +transform scale(real k, point A, point B, point C, point D, bool safe = false) +{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Affinit%C3%A9_%28math%C3%A9matiques%29"/> (help me for English translation...) - If 'safe=true' and (AB)//(CD) return the identity. - If 'safe=false' and (AB)//(CD) return a infinity scaling.</documentation></function></asyxml>*/ - pair a=locate(A); - pair u=unit(locate(B)-locate(A)); - pair v=unit(locate(D)-locate(C)); - real c=u.x*a.y-u.y*a.x; - real d=(conj(u)*v).y; - real d=(conj(u)*v).y; + If 'safe = true' and (AB)//(CD) return the identity. + If 'safe = false' and (AB)//(CD) return a infinity scaling.</documentation></function></asyxml>*/ + pair a = locate(A); + pair u = unit(locate(B) - locate(A)); + pair v = unit(locate(D) - locate(C)); + real c = u.x * a.y - u.y * a.x; + real d = (conj(u) * v).y; + real d = (conj(u) * v).y; if (abs(d) < epsgeo) { return safe ? identity() : scale(infinity); } - real tx=(1-k)*c*v.x/d; - real ty=(1-k)*c*v.y/d; - real txx=(1-k)*u.x*v.y/d+k; - real txy=(k-1)*u.x*v.x/d; - real tyx=(1-k)*u.y*v.y/d; - real tyy=(k-1)*u.y*v.x/d+k; - transform t=(tx,ty,txx,txy,tyx,tyy); + real tx = (1 - k) * c * v.x/d; + real ty = (1 - k) * c * v.y/d; + real txx = (1 - k) * u.x * v.y/d + k; + real txy = (k - 1) * u.x * v.x/d; + real tyx = (1 - k) * u.y * v.y/d; + real tyy = (k - 1) * u.y * v.x/d + k; + transform t = (tx, ty, txx, txy, tyx, tyy); return t; } -/*<asyxml><function type="transform" signature="scaleO(real)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "scaleO(real)"><code></asyxml>*/ transform scaleO(real x) {/*<asyxml></code><documentation>Homothety from the origin of the current coordinate system.</documentation></function></asyxml>*/ - return scale(x,(0,0)); + return scale(x, (0, 0)); } -/*<asyxml><function type="transform" signature="xscaleO(real)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "xscaleO(real)"><code></asyxml>*/ transform xscaleO(real x) {/*<asyxml></code><documentation>xscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/ - return scale(x,(0,0),(0,1),(0,0),(1,0)); + return scale(x, (0, 0), (0, 1), (0, 0), (1, 0)); } -/*<asyxml><function type="transform" signature="yscaleO(real)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "yscaleO(real)"><code></asyxml>*/ transform yscaleO(real x) {/*<asyxml></code><documentation>yscale from the origin and relatively to the current coordinate system.</documentation></function></asyxml>*/ - return scale(x,(0,0),(1,0),(0,0),(0,1)); + return scale(x, (0, 0), (1, 0), (0, 0), (0, 1)); } -/*<asyxml><struct signature="vector"><code></asyxml>*/ +/*<asyxml><struct signature = "vector"><code></asyxml>*/ struct vector {/*<asyxml></code><documentation>Like a point but casting to pair, adding etc does not take account - of the origin of the coordinate system.</documentation><property type="point" signature="v"><code></asyxml>*/ + of the origin of the coordinate system.</documentation><property type = "point" signature = "v"><code></asyxml>*/ point v;/*<asyxml></code><documentation>Coordinates as a point (embed coordinate system and pair).</documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ -/*<asyxml><operator type="point" signature="cast(vector)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "cast(vector)"><code></asyxml>*/ point operator cast(vector v) -{/*<asyxml></code><documentation>Cast vector 'v' to point 'M' so that OM=v.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Cast vector 'v' to point 'M' so that OM = v.</documentation></operator></asyxml>*/ return v.v; } -/*<asyxml><operator type="vector" signature="cast(pair)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "cast(pair)"><code></asyxml>*/ vector operator cast(pair v) {/*<asyxml></code><documentation>Cast pair to vector relatively to the current coordinate system 'currentcoordsys'.</documentation></operator></asyxml>*/ vector ov; - ov.v=point(currentcoordsys,v); + ov.v = point(currentcoordsys, v); return ov; } -/*<asyxml><operator type="vector" signature="cast(explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "cast(explicit point)"><code></asyxml>*/ vector operator cast(explicit point v) {/*<asyxml></code><documentation>A point can be interpreted like a vector using the code '(vector)a_point'.</documentation></operator></asyxml>*/ vector ov; - ov.v=v; + ov.v = v; return ov; } -/*<asyxml><operator type="pair" signature="cast(explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "pair" signature = "cast(explicit vector)"><code></asyxml>*/ pair operator cast(explicit vector v) {/*<asyxml></code><documentation>Cast vector to pair (the coordinates of 'v' in the default coordinate system).</documentation></operator></asyxml>*/ - return locate(v.v)-v.v.coordsys.O; + return locate(v.v) - v.v.coordsys.O; } -/*<asyxml><operator type="align" signature="cast(vector)"><code></asyxml>*/ +/*<asyxml><operator type = "align" signature = "cast(vector)"><code></asyxml>*/ align operator cast(vector v) {/*<asyxml></code><documentation>Cast vector to align.</documentation></operator></asyxml>*/ return (pair)v; } -/*<asyxml><function type="vector" signature="vector(coordsys,pair)"><code></asyxml>*/ -vector vector(coordsys R=currentcoordsys, pair v) +/*<asyxml><function type = "vector" signature = "vector(coordsys, pair)"><code></asyxml>*/ +vector vector(coordsys R = currentcoordsys, pair v) {/*<asyxml></code><documentation>Return the vector of 'R' which has the coordinates 'v'.</documentation></function></asyxml>*/ vector ov; - ov.v=point(R,v); + ov.v = point(R, v); return ov; } -/*<asyxml><function type="vector" signature="vector(point)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "vector(point)"><code></asyxml>*/ vector vector(point M) {/*<asyxml></code><documentation>Return the vector OM, where O is the origin of the coordinate system of 'M'. - Useful to write 'vector(P-M);' instead of '(vector)(P-M)'.</documentation></function></asyxml>*/ + Useful to write 'vector(P - M);' instead of '(vector)(P - M)'.</documentation></function></asyxml>*/ return M; } -/*<asyxml><function type="point" signature="point(explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit vector)"><code></asyxml>*/ point point(explicit vector u) -{/*<asyxml></code><documentation>Return the point M so that OM=u, where O is the origin of the coordinate system of 'u'.</documentation></function></asyxml>*/ +{/*<asyxml></code><documentation>Return the point M so that OM = u, where O is the origin of the coordinate system of 'u'.</documentation></function></asyxml>*/ return u.v; } -/*<asyxml><function type="pair" signature="locate(explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "pair" signature = "locate(explicit vector)"><code></asyxml>*/ pair locate(explicit vector v) {/*<asyxml></code><documentation>Return the coordinates of 'v' in the default coordinate system (like casting vector to pair).</documentation></function></asyxml>*/ return (pair)v; } -/*<asyxml><function type="void" signature="show(Label,pen,arrowbar)"><code></asyxml>*/ -void show(Label L, vector v, pen p=currentpen, arrowbar arrow=Arrow) +/*<asyxml><function type = "void" signature = "show(Label, pen, arrowbar)"><code></asyxml>*/ +void show(Label L, vector v, pen p = currentpen, arrowbar arrow = Arrow) {/*<asyxml></code><documentation>Draw the vector v (from the origin of its coordinate system).</documentation></function></asyxml>*/ - coordsys R=v.v.coordsys; + coordsys R = v.v.coordsys; draw(L, R.O--v.v, p, arrow); } -/*<asyxml><function type="vector" signature="changecoordsys(coordsys,vector)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "changecoordsys(coordsys, vector)"><code></asyxml>*/ vector changecoordsys(coordsys R, vector v) {/*<asyxml></code><documentation>Return the vector 'v' relatively to coordinate system 'R'.</documentation></function></asyxml>*/ vector ov; - ov.v=point(R,(locate(v)+R.O)/R); + ov.v = point(R, (locate(v) + R.O)/R); return ov; } -/*<asyxml><operator type="vector" signature="*(real,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "*(real, explicit vector)"><code></asyxml>*/ vector operator *(real x, explicit vector v) -{/*<asyxml></code><documentation>Provide real*vector.</documentation></operator></asyxml>*/ - return x*v.v; +{/*<asyxml></code><documentation>Provide real * vector.</documentation></operator></asyxml>*/ + return x * v.v; } -/*<asyxml><operator type="vector" signature="/(explicit vector,real)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "/(explicit vector, real)"><code></asyxml>*/ vector operator /(explicit vector v, real x) {/*<asyxml></code><documentation>Provide vector/real</documentation></operator></asyxml>*/ return v.v/x; } -/*<asyxml><operator type="vector" signature="*(transform t,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "*(transform t, explicit vector)"><code></asyxml>*/ vector operator *(transform t, explicit vector v) -{/*<asyxml></code><documentation>Provide transform*vector.</documentation></operator></asyxml>*/ - return t*v.v; +{/*<asyxml></code><documentation>Provide transform * vector.</documentation></operator></asyxml>*/ + return t * v.v; } -/*<asyxml><operator type="vector" signature="*(explicit point,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "*(explicit point, explicit vector)"><code></asyxml>*/ vector operator *(explicit point M, explicit vector v) -{/*<asyxml></code><documentation>Provide point*vector</documentation></operator></asyxml>*/ - return M*v.v; +{/*<asyxml></code><documentation>Provide point * vector</documentation></operator></asyxml>*/ + return M * v.v; } -/*<asyxml><operator type="point" signature="+(explicit point,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "+(explicit point, explicit vector)"><code></asyxml>*/ point operator +(point M, explicit vector v) {/*<asyxml></code><documentation>Return 'M' shifted by 'v'.</documentation></operator></asyxml>*/ - return shift(locate(v))*M; + return shift(locate(v)) * M; } -/*<asyxml><operator type="point" signature="-(explicit point, explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "-(explicit point, explicit vector)"><code></asyxml>*/ point operator -(point M, explicit vector v) {/*<asyxml></code><documentation>Return 'M' shifted by '-v'.</documentation></operator></asyxml>*/ - return shift(-locate(v))*M; + return shift(-locate(v)) * M; } -/*<asyxml><operator type="vector" signature="-(explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "-(explicit vector)"><code></asyxml>*/ vector operator -(explicit vector v) {/*<asyxml></code><documentation>Provide -v.</documentation></operator></asyxml>*/ return -v.v; } -/*<asyxml><operator type="point" signature="+(explicit pair,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "+(explicit pair, explicit vector)"><code></asyxml>*/ point operator +(explicit pair m, explicit vector v) {/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of a point in the current coordinates system 'currentcoordsys'. Return this point shifted by the vector 'v'.</documentation></operator></asyxml>*/ - return locate(m)+v; + return locate(m) + v; } -/*<asyxml><operator type="point" signature="-(explicit pair,explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "-(explicit pair, explicit vector)"><code></asyxml>*/ point operator -(explicit pair m, explicit vector v) {/*<asyxml></code><documentation>The pair 'm' is supposed to be the coordinates of a point in the current coordinates system 'currentcoordsys'. Return this point shifted by the vector '-v'.</documentation></operator></asyxml>*/ - return m+(-v); + return m + (-v); } -/*<asyxml><operator type="vector" signature="+(explicit vector, explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "+(explicit vector, explicit vector)"><code></asyxml>*/ vector operator +(explicit vector v1, explicit vector v2) -{/*<asyxml></code><documentation>Provide vector+vector. +{/*<asyxml></code><documentation>Provide vector + vector. If the two vector haven't the same coordinate system, the returned vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/ - coordsys R=v1.v.coordsys; - if(samecoordsys(false,v1,v2)){R=defaultcoordsys;} - return vector(R,(locate(v1)+locate(v2))/R); + coordsys R = v1.v.coordsys; + if(samecoordsys(false, v1, v2)){R = defaultcoordsys;} + return vector(R, (locate(v1) + locate(v2))/R); } -/*<asyxml><operator type="vector" signature="-(explicit vector, explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "vector" signature = "-(explicit vector, explicit vector)"><code></asyxml>*/ vector operator -(explicit vector v1, explicit vector v2) -{/*<asyxml></code><documentation>Provide vector-vector. +{/*<asyxml></code><documentation>Provide vector - vector. If the two vector haven't the same coordinate system, the returned vector is relative to the default coordinate system (without warning).</documentation></operator></asyxml>*/ - return v1+(-v2); + return v1 + (-v2); } -/*<asyxml><operator type="bool" signature="==(explicit vector, explicit vector)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "==(explicit vector, explicit vector)"><code></asyxml>*/ bool operator ==(explicit vector u, explicit vector v) -{/*<asyxml></code><documentation>Return true iff |u-v|<EPS.</documentation></operator></asyxml>*/ - return abs(u-v) < EPS; +{/*<asyxml></code><documentation>Return true iff |u - v|<EPS.</documentation></operator></asyxml>*/ + return abs(u - v) < EPS; } -/*<asyxml><function type="bool" signature="collinear(vector,vector)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "collinear(vector, vector)"><code></asyxml>*/ bool collinear(vector u, vector v) {/*<asyxml></code><documentation>Return 'true' iff the vectors 'u' and 'v' are collinear.</documentation></function></asyxml>*/ - return abs(ypart((conj((pair)u)*(pair)v))) < EPS; + return abs(ypart((conj((pair)u) * (pair)v))) < EPS; } -/*<asyxml><function type="vector" signature="unit(point)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "unit(point)"><code></asyxml>*/ vector unit(point M) {/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/ return M/abs(M); } -/*<asyxml><function type="vector" signature="unit(vector)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "unit(vector)"><code></asyxml>*/ vector unit(vector u) {/*<asyxml></code><documentation>Return the unit vector according to the modulus of its coordinate system.</documentation></function></asyxml>*/ return u.v/abs(u.v); } -/*<asyxml><function type="real" signature="degrees(vector,coordsys,bool)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "degrees(vector, coordsys, bool)"><code></asyxml>*/ real degrees(vector v, - coordsys R=v.v.coordsys, - bool warn=true) + coordsys R = v.v.coordsys, + bool warn = true) {/*<asyxml></code><documentation>Return the angle of 'v' (in degrees) relatively to 'R'.</documentation></function></asyxml>*/ - return (degrees(locate(v),warn)-degrees(R.i))%360; + return (degrees(locate(v), warn) - degrees(R.i))%360; } -/*<asyxml><function type="real" signature="angle(vector,coordsys,bool)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "angle(vector, coordsys, bool)"><code></asyxml>*/ real angle(explicit vector v, - coordsys R=v.v.coordsys, - bool warn=true) + coordsys R = v.v.coordsys, + bool warn = true) {/*<asyxml></code><documentation>Return the angle of 'v' (in radians) relatively to 'R'.</documentation></function></asyxml>*/ - return radians(degrees(v,R,warn)); + return radians(degrees(v, R, warn)); } -/*<asyxml><function type="vector" signature="conj(explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "conj(explicit vector)"><code></asyxml>*/ vector conj(explicit vector u) {/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/ return conj(u.v); } -/*<asyxml><function type="transform" signature="rotate(explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "rotate(explicit vector)"><code></asyxml>*/ transform rotate(explicit vector dir) -{/*<asyxml></code><documentation>A rotation in the direction 'dir' limited to [-90,90] +{/*<asyxml></code><documentation>A rotation in the direction 'dir' limited to [-90, 90] This is useful for rotating text along a line in the direction dir. rotate(explicit point dir) is also defined. </documentation></function></asyxml>*/ @@ -1070,37 +1070,37 @@ transform rotate(explicit point dir){return rotate(locate(vector(dir)));} // *=======================================================* // *.........................BASES.........................* -/*<asyxml><variable type="point" signature="origin"><code></asyxml>*/ -point origin=point(defaultcoordsys,(0,0));/*<asyxml></code><documentation>The origin of the current coordinate system.</documentation></variable></asyxml>*/ +/*<asyxml><variable type = "point" signature = "origin"><code></asyxml>*/ +point origin = point(defaultcoordsys, (0, 0));/*<asyxml></code><documentation>The origin of the current coordinate system.</documentation></variable></asyxml>*/ -/*<asyxml><function type="point" signature="origin(coordsys)"><code></asyxml>*/ -point origin(coordsys R=currentcoordsys) +/*<asyxml><function type = "point" signature = "origin(coordsys)"><code></asyxml>*/ +point origin(coordsys R = currentcoordsys) {/*<asyxml></code><documentation>Return the origin of the coordinate system 'R'.</documentation></function></asyxml>*/ - return point(R,(0,0)); //use automatic casting; + return point(R, (0, 0)); //use automatic casting; } -/*<asyxml><variable type="real" signature="linemargin"><code></asyxml>*/ -real linemargin=0;/*<asyxml></code><documentation>Margin used to draw lines.</documentation></variable></asyxml>*/ -/*<asyxml><function type="real" signature="linemargin()"><code></asyxml>*/ +/*<asyxml><variable type = "real" signature = "linemargin"><code></asyxml>*/ +real linemargin = 0;/*<asyxml></code><documentation>Margin used to draw lines.</documentation></variable></asyxml>*/ +/*<asyxml><function type = "real" signature = "linemargin()"><code></asyxml>*/ real linemargin() {/*<asyxml></code><documentation>Return the margin used to draw lines.</documentation></function></asyxml>*/ return linemargin; } -/*<asyxml><variable type="pen" signature="addpenline"><code></asyxml>*/ -pen addpenline=squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of "finish" lines.</documentation></variable></asyxml>*/ +/*<asyxml><variable type = "pen" signature = "addpenline"><code></asyxml>*/ +pen addpenline = squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of "finish" lines.</documentation></variable></asyxml>*/ pen addpenline(pen p) { - return addpenline+p; + return addpenline + p; } -/*<asyxml><variable type="pen" signature="addpenarc"><code></asyxml>*/ -pen addpenarc=squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of arcs.</documentation></variable></asyxml>*/ -pen addpenarc(pen p) {return addpenarc+p;} +/*<asyxml><variable type = "pen" signature = "addpenarc"><code></asyxml>*/ +pen addpenarc = squarecap;/*<asyxml></code><documentation>Add this property to the drawing pen of arcs.</documentation></variable></asyxml>*/ +pen addpenarc(pen p) {return addpenarc + p;} -/*<asyxml><variable type="string" signature="defaultmassformat"><code></asyxml>*/ -string defaultmassformat="$\left(%L;%.4g\right)$";/*<asyxml></code><documentation>Format used to construct the default label of masses.</documentation></variable></asyxml>*/ +/*<asyxml><variable type = "string" signature = "defaultmassformat"><code></asyxml>*/ +string defaultmassformat = "$\left(%L;%.4g \ right)$";/*<asyxml></code><documentation>Format used to construct the default label of masses.</documentation></variable></asyxml>*/ -/*<asyxml><function type="int" signature="sgnd(real)"><code></asyxml>*/ +/*<asyxml><function type = "int" signature = "sgnd(real)"><code></asyxml>*/ int sgnd(real x) {/*<asyxml></code><documentation>Return the -1 if x < 0, 1 if x >= 0.</documentation></function></asyxml>*/ return (x == 0) ? 1 : sgn(x); @@ -1110,975 +1110,994 @@ int sgnd(int x) return (x == 0) ? 1 : sgn(x); } -/*<asyxml><function type="bool" signature="defined(pair)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "defined(pair)"><code></asyxml>*/ bool defined(point P) {/*<asyxml></code><documentation>Return true iff the coordinates of 'P' are finite.</documentation></function></asyxml>*/ return finite(P.coordinates); } -/*<asyxml><function type="bool" signature="onpath(picture,path,point,pen)"><code></asyxml>*/ -bool onpath(picture pic=currentpicture, path g, point M, pen p=currentpen) +/*<asyxml><function type = "bool" signature = "onpath(picture, path, point, pen)"><code></asyxml>*/ +bool onpath(picture pic = currentpicture, path g, point M, pen p = currentpen) {/*<asyxml></code><documentation>Return true iff 'M' is on the path drawn with the pen 'p' in 'pic'.</documentation></function></asyxml>*/ - transform t=inverse(pic.calculateTransform()); - return intersect(g, shift(locate(M))*scale(linewidth(p)/2)*t*unitcircle).length > 0; + transform t = inverse(pic.calculateTransform()); + return intersect(g, shift(locate(M)) * scale(linewidth(p)/2) * t * unitcircle).length > 0; } -/*<asyxml><function type="bool" signature="sameside(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "sameside(point, point, point)"><code></asyxml>*/ bool sameside(point M, point N, point O) {/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the point 'O'.</documentation></function></asyxml>*/ - pair m=M, n=N, o=O; - return dot(m-o,n-o) >= -epsgeo; + pair m = M, n = N, o = O; + return dot(m - o, n - o) >= -epsgeo; } -/*<asyxml><function type="bool" signature="between(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "between(point, point, point)"><code></asyxml>*/ bool between(point M, point O, point N) {/*<asyxml></code><documentation>Return 'true' iff 'O' is between 'M' and 'N'.</documentation></function></asyxml>*/ - return (!sameside(N,M,O) || M == O || N == O); + return (!sameside(N, M, O) || M == O || N == O); } typedef path pathModifier(path); -pathModifier NoModifier=new path(path g){return g;}; +pathModifier NoModifier = new path(path g){return g;}; -private void Drawline(picture pic=currentpicture, Label L="",pair P, bool dirP=true, pair Q, bool dirQ=true, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, - Label legend="", marker marker=nomarker, - pathModifier pathModifier=NoModifier) +private void Drawline(picture pic = currentpicture, Label L = "", pair P, bool dirP = true, pair Q, bool dirQ = true, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, + Label legend = "", marker marker = nomarker, + pathModifier pathModifier = NoModifier) {/* Add the two parameters 'dirP' and 'dirQ' to the native routine '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'. + 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 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()); + 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; + t = t * T; + pair z = t * P; + pair q = t * Q; + pair v = q - z; // path g; - pair ptp,ptq; + pair ptp, ptq; real cp = dirP ? 1:0; real cq = dirQ ? 1:0; // Handle horizontal and vertical lines. if(v.x == 0) { if(m.x <= z.x && z.x <= M.x) - if (dot(v,m-z) < 0) { - ptp=(z.x,z.y+cp*(m.y-z.y)); - ptq=(z.x,q.y+cq*(M.y-q.y)); + if (dot(v, m - z) < 0) { + ptp = (z.x, z.y + cp * (m.y - z.y)); + ptq = (z.x, q.y + cq * (M.y - q.y)); } else { - ptq=(z.x,q.y+cq*(m.y-q.y)); - ptp=(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); + 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 { - ptq=(q.x+cq*(m.x-q.x),z.y); - ptp=(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 - // parametric equation z + t*v - real mx=(m.x-z.x)/v.x, Mx=(M.x-z.x)/v.x; - real my=(m.y-z.y)/v.y, My=(M.y-z.y)/v.y; - real tmin=max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My); - real tmax=min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my); - pair pmin=z+tmin*v; - pair pmax=z+tmax*v; + // parametric equation z + t * v + real mx = (m.x - z.x)/v.x, Mx = (M.x - z.x)/v.x; + real my = (m.y - z.y)/v.y, My = (M.y - z.y)/v.y; + real tmin = max(v.x > 0 ? mx : Mx, v.y > 0 ? my : My); + real tmax = min(v.x > 0 ? Mx : mx, v.y > 0 ? My : my); + pair pmin = z + tmin * v; + pair pmax = z + tmax * v; if(tmin <= tmax) { - ptp=z+cp*tmin*v; - ptq=z+(cq == 0 ? v:tmax*v); + ptp = z + cp * tmin * v; + ptq = z + (cq == 0 ? v:tmax * v); } } - path g=ptp--ptq; + path g = ptp--ptq; if (length(g)>0) { if(L.s != "") { - Label lL=L.copy(); + Label lL = L.copy(); if(L.defaultposition) lL.position(Relative(.9)); lL.p(p); - lL.out(opic,g); + lL.out(opic, g); } - g=pathModifier(g); + g = pathModifier(g); if(linetype(p).length == 0){ - pair m=midpoint(g); + pair m = midpoint(g); pen tp; - tp=dirP ? p : addpenline(p); - draw(opic,pathModifier(m--ptp),tp); - tp=dirQ ? p : addpenline(p); - draw(opic,pathModifier(m--ptq),tp); + tp = dirP ? p : addpenline(p); + draw(opic, pathModifier(m--ptp), tp); + tp = dirQ ? p : addpenline(p); + draw(opic, pathModifier(m--ptq), tp); } else { - draw(opic,g,p); + draw(opic, g, p); } - marker.markroutine(opic,marker.f,g); - arrow(opic,g,p,NoMargin); - add(f,opic.fit()); + marker.markroutine(opic, marker.f, g); + arrow(opic, g, p, NoMargin); + add(f, opic.fit()); } }); } -/*<asyxml><function type="void" signature="clipdraw(picture,Label,path,align,pen,arrowbar,arrowbar,real,real,Label,marker)"><code></asyxml>*/ -void clipdraw(picture pic=currentpicture, Label L="", path g, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - real xmargin=0, real ymargin=xmargin, - Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "clipdraw(picture, Label, path, align, pen, arrowbar, arrowbar, real, real, Label, marker)"><code></asyxml>*/ +void clipdraw(picture pic = currentpicture, Label L = "", path g, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + real xmargin = 0, real ymargin = xmargin, + Label legend = "", marker marker = nomarker) {/*<asyxml></code><documentation>Draw the path 'g' on 'pic' clipped to the bounding box of 'pic'.</documentation></function></asyxml>*/ if(L.s != "") { picture tmp; - label(tmp,L,g,p); - add(pic,tmp); + label(tmp, L, g, p); + add(pic, tmp); } 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); + m += min(p) + (xmargin, ymargin); M -= max(p) + (xmargin, ymargin); + path bound = box(m, M); picture tmp; - draw(tmp,"",t*T*g,align,p,arrow,bar,NoMargin,legend,marker); - clip(tmp,bound); - add(f,tmp.fit()); + draw(tmp, "", t * T * g, align, p, arrow, bar, NoMargin, legend, marker); + clip(tmp, bound); + add(f, tmp.fit()); }); } -/*<asyxml><function type="void" signature="distance(picture pic,Label,point,point,bool,real,pen,pen,arrow)"><code></asyxml>*/ -void distance(picture pic=currentpicture, Label L="", point A, point B, - bool rotated=true, real offset=3mm, - pen p=currentpen, pen joinpen=invisible, - arrowbar arrow=Arrows(NoFill)) +/*<asyxml><function type = "void" signature = "distance(picture pic, Label, point, point, bool, real, pen, pen, arrow)"><code></asyxml>*/ +void distance(picture pic = currentpicture, Label L = "", point A, point B, + bool rotated = true, real offset = 3mm, + pen p = currentpen, pen joinpen = invisible, + arrowbar arrow = Arrows(NoFill)) {/*<asyxml></code><documentation>Draw arrow between A and B (from FAQ).</documentation></function></asyxml>*/ - pair A=A, B=B; - path g=A--B; - transform Tp=shift(-offset*unit(B-A)*I); + pair A = A, B = B; + path g = A--B; + transform Tp = shift(-offset * unit(B - A) * I); pic.add(new void(frame f, transform t) { picture opic; - path G=Tp*t*g; - transform id=identity(); - transform T=rotated ? rotate(B-A) : id; - Label L=L.copy(); - L.align(L.align,Center); - if(abs(ypart((conj(A-B)*L.align.dir))) < epsgeo && L.filltype == NoFill) - L.filltype=UnFill(1); - draw(opic,T*L,G,p,arrow,Bars,PenMargins); - pair Ap=t*A, Bp=t*B; - draw(opic,(Ap--Tp*Ap)^^(Bp--Tp*Bp), joinpen); - add(f,opic.fit()); + path G = Tp * t * g; + transform id = identity(); + transform T = rotated ? rotate(B - A) : id; + Label L = L.copy(); + L.align(L.align, Center); + if(abs(ypart((conj(A - B) * L.align.dir))) < epsgeo && L.filltype == NoFill) + L.filltype = UnFill(1); + draw(opic, T * L, G, p, arrow, Bars, PenMargins); + pair Ap = t * A, Bp = t * B; + draw(opic, (Ap--Tp * Ap)^^(Bp--Tp * Bp), joinpen); + add(f, opic.fit()); }, true); - pic.addBox(min(g),max(g),Tp*min(p),Tp*max(p)); + pic.addBox(min(g), max(g), Tp * min(p), Tp * max(p)); } -/*<asyxml><variable type="real" signature="perpfactor"><code></asyxml>*/ -real perpfactor=1;/*<asyxml></code><documentation>Factor for drawing perpendicular symbol.</documentation></variable></asyxml>*/ -/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,explicit pair,real,pen,margin,filltype)"><code></asyxml>*/ -void perpendicularmark(picture pic=currentpicture, point z, +/*<asyxml><variable type = "real" signature = "perpfactor"><code></asyxml>*/ +real perpfactor = 1;/*<asyxml></code><documentation>Factor for drawing perpendicular symbol.</documentation></variable></asyxml>*/ +/*<asyxml><function type = "void" signature = "perpendicularmark(picture, point, explicit pair, explicit pair, real, pen, margin, filltype)"><code></asyxml>*/ +void perpendicularmark(picture pic = currentpicture, point z, explicit pair align, - explicit pair dir=E, real size=0, - pen p=currentpen, - margin margin=NoMargin, - filltype filltype=NoFill) + explicit pair dir = E, real size = 0, + pen p = currentpen, + margin margin = NoMargin, + filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align - relative to the path z--z+dir. - dir(45+n*90), where n in N*, are common values for 'align'.</documentation></function></asyxml>*/ - p=squarecap+p; - if(size == 0) size=perpfactor*3mm+sqrt(1+linewidth(p))-1; + relative to the path z--z + dir. + dir(45 + n * 90), where n in N*, are common values for 'align'.</documentation></function></asyxml>*/ + p = squarecap + p; + if(size == 0) size = perpfactor * 3mm + sqrt(1 + linewidth(p)) - 1; frame apic; - pair d1=size*align*unit(dir)*dir(-45); - pair d2=I*d1; - path g=d1--d1+d2--d2; - g=margin(g,p).g; - draw(apic,g,p); - if(filltype != NoFill) filltype.fill(apic,(relpoint(g,0)-relpoint(g,0.5)+ - relpoint(g,1))--g--cycle,p+solid); - add(pic,apic,locate(z)); -} - -/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,vector,real,pen,margin,filltype)"><code></asyxml>*/ -void perpendicularmark(picture pic=currentpicture, point z, + pair d1 = size * align * unit(dir) * dir(-45); + pair d2 = I * d1; + path g = d1--d1 + d2--d2; + g = margin(g, p).g; + draw(apic, g, p); + if(filltype != NoFill) filltype.fill(apic, (relpoint(g, 0) - relpoint(g, 0.5)+ + relpoint(g, 1))--g--cycle, p + solid); + add(pic, apic, locate(z)); +} + +/*<asyxml><function type = "void" signature = "perpendicularmark(picture, point, vector, vector, real, pen, margin, filltype)"><code></asyxml>*/ +void perpendicularmark(picture pic = currentpicture, point z, vector align, - vector dir=E, real size=0, - pen p=currentpen, - margin margin=NoMargin, - filltype filltype=NoFill) + vector dir = E, real size = 0, + pen p = currentpen, + margin margin = NoMargin, + filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align - relative to the path z--z+dir. - dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ + relative to the path z--z + dir. + dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ perpendicularmark(pic, z, (pair)align, (pair)dir, size, p, margin, filltype); } -/*<asyxml><function type="void" signature="perpendicularmark(picture,point,explicit pair,path,real,pen,margin,filltype)"><code></asyxml>*/ -void perpendicularmark(picture pic=currentpicture, point z, explicit pair align, path g, - real size=0, pen p=currentpen, - margin margin=NoMargin, - filltype filltype=NoFill) +/*<asyxml><function type = "void" signature = "perpendicularmark(picture, point, explicit pair, path, real, pen, margin, filltype)"><code></asyxml>*/ +void perpendicularmark(picture pic = currentpicture, point z, explicit pair align, path g, + real size = 0, pen p = currentpen, + margin margin = NoMargin, + filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align - relative to the path z--z+dir(g,0). - dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ - perpendicularmark(pic,z,align,dir(g,0),size,p,margin,filltype); + relative to the path z--z + dir(g, 0). + dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ + perpendicularmark(pic, z, align, dir(g, 0), size, p, margin, filltype); } -/*<asyxml><function type="void" signature="perpendicularmark(picture,point,vector,path,real,pen,margin,filltype)"><code></asyxml>*/ -void perpendicularmark(picture pic=currentpicture, point z, vector align, path g, - real size=0, pen p=currentpen, - margin margin=NoMargin, - filltype filltype=NoFill) +/*<asyxml><function type = "void" signature = "perpendicularmark(picture, point, vector, path, real, pen, margin, filltype)"><code></asyxml>*/ +void perpendicularmark(picture pic = currentpicture, point z, vector align, path g, + real size = 0, pen p = currentpen, + margin margin = NoMargin, + filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw a perpendicular symbol at z aligned in the direction align - relative to the path z--z+dir(g,0). - dir(45+n*90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ - perpendicularmark(pic,z,(pair)align,dir(g,0),size,p,margin,filltype); + relative to the path z--z + dir(g, 0). + dir(45 + n * 90), where n in N, are common values for 'align'.</documentation></function></asyxml>*/ + perpendicularmark(pic, z, (pair)align, dir(g, 0), size, p, margin, filltype); } -/*<asyxml><function type="void" signature="markrightangle(picture,point,point,point,real,pen,margin,filltype)"><code></asyxml>*/ -void markrightangle(picture pic=currentpicture, point A, point O, - point B, real size=0, pen p=currentpen, - margin margin=NoMargin, - filltype filltype=NoFill) +/*<asyxml><function type = "void" signature = "markrightangle(picture, point, point, point, real, pen, margin, filltype)"><code></asyxml>*/ +void markrightangle(picture pic = currentpicture, point A, point O, + point B, real size = 0, pen p = currentpen, + margin margin = NoMargin, + filltype filltype = NoFill) {/*<asyxml></code><documentation>Mark the angle AOB with a perpendicular symbol.</documentation></function></asyxml>*/ - pair Ap=A, Bp=B, Op=O; - pair dir=Ap-Op; - real a1=degrees(dir); - pair align=rotate(-a1)*unit(dir(Op--Ap,Op--Bp)); + pair Ap = A, Bp = B, Op = O; + pair dir = Ap - Op; + real a1 = degrees(dir); + pair align = rotate(-a1) * unit(dir(Op--Ap, Op--Bp)); if (margin == NoMargin) - margin=TrueMargin(linewidth(currentpen)/2,linewidth(currentpen)/2); - perpendicularmark(pic=pic, z=O, align=align, - dir=dir, size=size, p=p, - margin=margin, filltype=filltype); + margin = TrueMargin(linewidth(currentpen)/2, linewidth(currentpen)/2); + perpendicularmark(pic = pic, z = O, align = align, + dir = dir, size = size, p = p, + margin = margin, filltype = filltype); } -/*<asyxml><function type="bool" signature="simeq(point,point,real)"><code></asyxml>*/ -bool simeq(point A, point B, real fuzz=epsgeo) -{/*<asyxml></code><documentation>Return true iff abs(A-B) < fuzz. +/*<asyxml><function type = "bool" signature = "simeq(point, point, real)"><code></asyxml>*/ +bool simeq(point A, point B, real fuzz = epsgeo) +{/*<asyxml></code><documentation>Return true iff abs(A - B) < fuzz. This routine is used internally to know if two points are equal, in particular by the operator == in 'point == point'.</documentation></function></asyxml>*/ - return (abs(A-B) < fuzz); + return (abs(A - B) < fuzz); } -bool simeq(point a, real b, real fuzz=epsgeo) +bool simeq(point a, real b, real fuzz = epsgeo) { - coordsys R=a.coordsys; - return (abs(a-point(R,((pair)b)/R)) < fuzz); + coordsys R = a.coordsys; + return (abs(a - point(R, ((pair)b)/R)) < fuzz); } -/*<asyxml><function type="pair" signature="attract(pair,path,real)"><code></asyxml>*/ -pair attract(pair m, path g, real fuzz=0) +/*<asyxml><function type = "pair" signature = "attract(pair, path, real)"><code></asyxml>*/ +pair attract(pair m, path g, real fuzz = 0) {/*<asyxml></code><documentation>Return the nearest point (A PAIR) of 'm' which is on the path g. 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/ - if(intersect(m,g,fuzz).length > 0) return m; + if(intersect(m, g, fuzz).length > 0) return m; pair p; - real step=1, r=0; + real step = 1, r = 0; real[] t; - static real eps=sqrt(realEpsilon); + static real eps = sqrt(realEpsilon); do {// Find a radius for intersection - r+=step; - t=intersect(shift(m)*scale(r)*unitcircle,g); + r += step; + t = intersect(shift(m) * scale(r) * unitcircle, g); } while(t.length <= 0); - p=point(g,t[1]); - real rm=0, rM=r; - while(rM-rm > eps) { - r=(rm+rM)/2; - t=intersect(shift(m)*scale(r)*unitcircle,g,fuzz); + p = point(g, t[1]); + real rm = 0, rM = r; + while(rM - rm > eps) { + r = (rm + rM)/2; + t = intersect(shift(m) * scale(r) * unitcircle, g, fuzz); if(t.length <= 0) { - rm=r; + rm = r; } else { - rM=r; - p=point(g,t[1]); + rM = r; + p = point(g, t[1]); } } return p; } -/*<asyxml><function type="point" signature="attract(point,path,real)"><code></asyxml>*/ -point attract(point M, path g, real fuzz=0) +/*<asyxml><function type = "point" signature = "attract(point, path, real)"><code></asyxml>*/ +point attract(point M, path g, real fuzz = 0) {/*<asyxml></code><documentation>Return the nearest point (A POINT) of 'M' which is on the path g. 'fuzz' is the argument 'fuzz' of 'intersect'.</documentation></function></asyxml>*/ - return point(M.coordsys, attract(locate(M),g)/M.coordsys); + return point(M.coordsys, attract(locate(M), g)/M.coordsys); } -/*<asyxml><function type="real[]" signature="intersect(path,explicit pair)"><code></asyxml>*/ -real[] intersect(path g, explicit pair p, real fuzz=0) +/*<asyxml><function type = "real[]" signature = "intersect(path, explicit pair)"><code></asyxml>*/ +real[] intersect(path g, explicit pair p, real fuzz = 0) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - fuzz=fuzz <= 0 ? sqrt(realEpsilon) : fuzz; + fuzz = fuzz <= 0 ? sqrt(realEpsilon) : fuzz; real[] or; - real r=realEpsilon; + real r = realEpsilon; do{ - or=intersect(g,shift(p)*scale(r)*unitcircle,fuzz); + or = intersect(g, shift(p) * scale(r) * unitcircle, fuzz); r *= 2; } while(or.length == 0); return or; } -/*<asyxml><function type="real[]" signature="intersect(path,explicit point)"><code></asyxml>*/ -real[] intersect(path g, explicit point P, real fuzz=epsgeo) +/*<asyxml><function type = "real[]" signature = "intersect(path, explicit point)"><code></asyxml>*/ +real[] intersect(path g, explicit point P, real fuzz = epsgeo) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersect(g,locate(P),fuzz); + return intersect(g, locate(P), fuzz); } // *.........................BASES.........................* // *=======================================================* // *=======================================================* // *.........................LINES.........................* -/*<asyxml><struct signature="line"><code></asyxml>*/ +/*<asyxml><struct signature = "line"><code></asyxml>*/ struct line -{/*<asyxml></code><documentation>This structure provides the objects line, semi-line and segment oriented from A to B. +{/*<asyxml></code><documentation>This structure provides the objects line, semi - line and segment oriented from A to B. All the calculus with this structure will be as exact as Asymptote can do. For a full precision, you must not cast 'line' to 'path' excepted for drawing routines.</documentation></asyxml>*/ - /*<asyxml><property type="point" signature="A,B"><code></asyxml>*/ - restricted point A,B;/*<asyxml></code><documentation>Two line's points with same coordinate system.</documentation></property><property type="bool" signature="extendA,extendB"><code></asyxml>*/ - bool extendA,extendB;/*<asyxml></code><documentation>If true, extend 'l' in direction of A (resp. B).</documentation></property><property type="vector" signature="u,v"><code></asyxml>*/ - restricted vector u,v;/*<asyxml></code><documentation>u=unit(AB)=direction vector, v=normal vector.</documentation></property><property type="real" signature="a,b,c"><code></asyxml>*/ - restricted real a,b,c;/*<asyxml></code><documentation>Coefficients of the equation ax+by+c=0 in the coordinate system of 'A'.</documentation></property><property type="real" signature="slope,origin"><code></asyxml>*/ - restricted real slope,origin;/*<asyxml></code><documentation>Slope and ordinate at the origin.</documentation></property></asyxml>*/ - /*<asyxml><method type="line" signature="copy()"><code></asyxml>*/ + /*<asyxml><property type = "point" signature = "A, B"><code></asyxml>*/ + restricted point A, B;/*<asyxml></code><documentation>Two line's points with same coordinate system.</documentation></property><property type = "bool" signature = "extendA, extendB"><code></asyxml>*/ + bool extendA, extendB;/*<asyxml></code><documentation>If true, extend 'l' in direction of A (resp. B).</documentation></property><property type = "vector" signature = "u, v"><code></asyxml>*/ + restricted vector u, v;/*<asyxml></code><documentation>u = unit(AB) = direction vector, v = normal vector.</documentation></property><property type = "real" signature = "a, b, c"><code></asyxml>*/ + restricted real a, b, c;/*<asyxml></code><documentation>Coefficients of the equation ax + by + c = 0 in the coordinate system of 'A'.</documentation></property><property type = "real" signature = "slope, origin"><code></asyxml>*/ + restricted real slope, origin;/*<asyxml></code><documentation>Slope and ordinate at the origin.</documentation></property></asyxml>*/ + /*<asyxml><method type = "line" signature = "copy()"><code></asyxml>*/ line copy() {/*<asyxml></code><documentation>Copy a line in a new instance.</documentation></method></asyxml>*/ - line l=new line; - l.A=A; - l.B=B; - l.a=a; - l.b=b; - l.c=c; - l.slope=slope; - l.origin=origin; - l.u=u; - l.v=v; - l.extendA=extendA; - l.extendB=extendB; + line l = new line; + l.A = A; + l.B = B; + l.a = a; + l.b = b; + l.c = c; + l.slope = slope; + l.origin = origin; + l.u = u; + l.v = v; + l.extendA = extendA; + l.extendB = extendB; return l; } - /*<asyxml><method type="void" signature="init(point,bool,point,bool)"><code></asyxml>*/ - void init(point A, bool extendA=true, point B, bool extendB=true) + /*<asyxml><method type = "void" signature = "init(point, bool, point, bool)"><code></asyxml>*/ + void init(point A, bool extendA = true, point B, bool extendB = true) {/*<asyxml></code><documentation>Initialize line. If 'extendA' is true, the "line" is infinite in the direction of A.</documentation></method></asyxml>*/ - point[] P=standardizecoordsys(A,B); - this.A=P[0]; - this.B=P[1]; - this.a=B.y-A.y; - this.b=A.x-B.x; - this.c=A.y*B.x-A.x*B.y; + point[] P = standardizecoordsys(A, B); + this.A = P[0]; + this.B = P[1]; + this.a = B.y - A.y; + this.b = A.x - B.x; + this.c = A.y * B.x - A.x * B.y; this.slope= (this.b == 0) ? infinity : -this.a/this.b; - this.origin=(this.b == 0) ? (this.c==0) ? 0:infinity : -this.c/this.b; - this.u=unit(P[1]-P[0]); - // int tmp=sgnd(this.slope); - // this.u=(dot((pair)this.u,N) >= 0) ? tmp*this.u : -tmp*this.u; - this.v=rotate(90,point(P[0].coordsys,(0,0)))*this.u; - this.extendA=extendA; - this.extendB=extendB; + this.origin = (this.b == 0) ? (this.c == 0) ? 0:infinity : -this.c/this.b; + this.u = unit(P[1]-P[0]); + // int tmp = sgnd(this.slope); + // this.u = (dot((pair)this.u, N) >= 0) ? tmp * this.u : -tmp * this.u; + this.v = rotate(90, point(P[0].coordsys, (0, 0))) * this.u; + this.extendA = extendA; + this.extendB = extendB; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="line" signature="line(point,bool,point,bool)"><code></asyxml>*/ -line line(point A, bool extendA=true, point B, bool extendB=true) +/*<asyxml><function type = "line" signature = "line(point, bool, point, bool)"><code></asyxml>*/ +line line(point A, bool extendA = true, point B, bool extendB = true) {/*<asyxml></code><documentation>Return the line passing through 'A' and 'B'. If 'extendA' is true, the "line" is infinite in the direction of A. A "line" can be half-line or segment.</documentation></function></asyxml>*/ if (A == B) abort("line: the points must be distinct."); line l; - l.init(A,extendA,B,extendB); + l.init(A, extendA, B, extendB); return l; } -/*<asyxml><struct signature="segment"><code></asyxml>*/ +/*<asyxml><struct signature = "segment"><code></asyxml>*/ struct segment -{/*<asyxml></code><documentation><look href="struct line"/>.</documentation></asyxml>*/ - restricted point A,B;// Extremity. - restricted vector u,v;// u=direction vector, v=normal vector. - restricted real a,b,c;// Coefficients of the équation ax+by+c=0 - restricted real slope,origin; +{/*<asyxml></code><documentation><look href = "struct line"/>.</documentation></asyxml>*/ + restricted point A, B;// Extremity. + restricted vector u, v;// u = direction vector, v = normal vector. + restricted real a, b, c;// Coefficients of the équation ax + by + c = 0 + restricted real slope, origin; segment copy() { - segment s=new segment; - s.A=A; - s.B=B; - s.a=a; - s.b=b; - s.c=c; - s.slope=slope; - s.origin=origin; - s.u=u; - s.v=v; + segment s = new segment; + s.A = A; + s.B = B; + s.a = a; + s.b = b; + s.c = c; + s.slope = slope; + s.origin = origin; + s.u = u; + s.v = v; return s; } void init(point A, point B) { line l; - l.init(A,B); - this.A=l.A; this.B=l.B; - this.a=l.a; this.b=l.b; this.c=l.c; - this.slope=l.slope; this.origin=l.origin; - this.u=l.u; this.v=l.v; + l.init(A, B); + this.A = l.A; this.B = l.B; + this.a = l.a; this.b = l.b; this.c = l.c; + this.slope = l.slope; this.origin = l.origin; + this.u = l.u; this.v = l.v; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="segment" signature="segment(point,point)"><code></asyxml>*/ +/*<asyxml><function type = "segment" signature = "segment(point, point)"><code></asyxml>*/ segment segment(point A, point B) {/*<asyxml></code><documentation>Return the segment whose the extremities are A and B.</documentation></function></asyxml>*/ segment s; - s.init(A,B); + s.init(A, B); return s; } -/*<asyxml><function type="real" signature="length(segment)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "length(segment)"><code></asyxml>*/ real length(segment s) {/*<asyxml></code><documentation>Return the length of 's'.</documentation></function></asyxml>*/ - return abs(s.A-s.B); + return abs(s.A - s.B); } -/*<asyxml><operator type="line" signature="cast(segment)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "cast(segment)"><code></asyxml>*/ line operator cast(segment s) {/*<asyxml></code><documentation>A segment is casted to a "finite line".</documentation></operator></asyxml>*/ - return line(s.A,false,s.B,false); + return line(s.A, false, s.B, false); } -/*<asyxml><operator type="segment" signature="cast(line)"><code></asyxml>*/ +/*<asyxml><operator type = "segment" signature = "cast(line)"><code></asyxml>*/ segment operator cast(line l) {/*<asyxml></code><documentation>Cast line 'l' to segment [l.A l.B].</documentation></operator></asyxml>*/ - return segment(l.A,l.B); + return segment(l.A, l.B); } -/*<asyxml><operator type="line" signature="*(transform,line)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "*(transform, line)"><code></asyxml>*/ line operator *(transform t, line l) -{/*<asyxml></code><documentation>Provide transform*line</documentation></operator></asyxml>*/ - return line(t*l.A,l.extendA,t*l.B,l.extendB); +{/*<asyxml></code><documentation>Provide transform * line</documentation></operator></asyxml>*/ + return line(t * l.A, l.extendA, t * l.B, l.extendB); } -/*<asyxml><operator type="line" signature="/(line,real)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "/(line, real)"><code></asyxml>*/ line operator /(line l, real x) {/*<asyxml></code><documentation>Provide l/x. Return the line passing through l.A/x and l.B/x.</documentation></operator></asyxml>*/ - return line(l.A/x,l.extendA,l.B/x,l.extendB); + return line(l.A/x, l.extendA, l.B/x, l.extendB); } -line operator /(line l, int x){return line(l.A/x,l.B/x);} -/*<asyxml><operator type="line" signature="*(real,line)"><code></asyxml>*/ +line operator /(line l, int x){return line(l.A/x, l.B/x);} +/*<asyxml><operator type = "line" signature = "*(real, line)"><code></asyxml>*/ line operator *(real x, line l) -{/*<asyxml></code><documentation>Provide x*l. - Return the line passing through x*l.A and x*l.B.</documentation></operator></asyxml>*/ - return line(x*l.A,l.extendA,x*l.B,l.extendB); +{/*<asyxml></code><documentation>Provide x * l. + Return the line passing through x * l.A and x * l.B.</documentation></operator></asyxml>*/ + return line(x * l.A, l.extendA, x * l.B, l.extendB); } -line operator *(int x, line l){return line(x*l.A,l.extendA,x*l.B,l.extendB);} +line operator *(int x, line l){return line(x * l.A, l.extendA, x * l.B, l.extendB);} -/*<asyxml><operator type="line" signature="*(point,line)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "*(point, line)"><code></asyxml>*/ line operator *(point M, line l) -{/*<asyxml></code><documentation>Provide point*line. - Return the line passing through unit(M)*l.A and unit(M)*l.B.</documentation></operator></asyxml>*/ - return line(unit(M)*l.A,l.extendA,unit(M)*l.B,l.extendB); +{/*<asyxml></code><documentation>Provide point * line. + Return the line passing through unit(M) * l.A and unit(M) * l.B.</documentation></operator></asyxml>*/ + return line(unit(M) * l.A, l.extendA, unit(M) * l.B, l.extendB); } -/*<asyxml><operator type="line" signature="+(line,point)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "+(line, point)"><code></asyxml>*/ line operator +(line l, vector u) -{/*<asyxml></code><documentation>Provide line+vector (and so line+point). +{/*<asyxml></code><documentation>Provide line + vector (and so line + point). Return the line 'l' shifted by 'u'.</documentation></operator></asyxml>*/ - return line(l.A+u,l.extendA,l.B+u,l.extendB); + return line(l.A + u, l.extendA, l.B + u, l.extendB); } -/*<asyxml><operator type="line" signature="-(line,vector)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "-(line, vector)"><code></asyxml>*/ line operator -(line l, vector u) {/*<asyxml></code><documentation>Provide line - vector (and so line - point). Return the line 'l' shifted by '-u'.</documentation></operator></asyxml>*/ - return line(l.A-u,l.extendA,l.B-u,l.extendB); + return line(l.A - u, l.extendA, l.B - u, l.extendB); } -/*<asyxml><operator type="line[]" signature="^^(line,line)"><code></asyxml>*/ +/*<asyxml><operator type = "line[]" signature = "^^(line, line)"><code></asyxml>*/ line[] operator ^^(line l1, line l2) {/*<asyxml></code><documentation>Provide line^^line. - Return the line array {l1,l2}.</documentation></operator></asyxml>*/ + Return the line array {l1, l2}.</documentation></operator></asyxml>*/ line[] ol; ol.push(l1); ol.push(l2); return ol; } -/*<asyxml><operator type="line[]" signature="^^(line,line[])"><code></asyxml>*/ +/*<asyxml><operator type = "line[]" signature = "^^(line, line[])"><code></asyxml>*/ line[] operator ^^(line l1, line[] l2) {/*<asyxml></code><documentation>Provide line^^line[]. Return the line array {l1, l2[0], l2[1]...}. line[]^^line is also defined.</documentation></operator></asyxml>*/ line[] ol; ol.push(l1); - for (int i=0; i<l2.length; ++i) { + for (int i = 0; i < l2.length; ++i) { ol.push(l2[i]); } return ol; } line[] operator ^^(line[] l2, line l1) { - line[] ol=l2; + line[] ol = l2; ol.push(l1); return ol; } -/*<asyxml><operator type="line[]" signature="^^(line,line[])"><code></asyxml>*/ +/*<asyxml><operator type = "line[]" signature = "^^(line, line[])"><code></asyxml>*/ line[] operator ^^(line l1[], line[] l2) {/*<asyxml></code><documentation>Provide line[]^^line[]. - Return the line array {l1[0], l1[1],..., l2[0], l2[1],...}.</documentation></operator></asyxml>*/ - line[] ol=l1; - for (int i=0; i<l2.length; ++i) { + Return the line array {l1[0], l1[1], ..., l2[0], l2[1], ...}.</documentation></operator></asyxml>*/ + line[] ol = l1; + for (int i = 0; i < l2.length; ++i) { ol.push(l2[i]); } return ol; } -/*<asyxml><function type="bool" signature="sameside(point,point,line)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "sameside(point, point, line)"><code></asyxml>*/ bool sameside(point M, point P, line l) {/*<asyxml></code><documentation>Return 'true' iff 'M' and 'N' are same side of the line (or on the line) 'l'.</documentation></function></asyxml>*/ - pair A=l.A, B=l.B, m=M, p=P; - pair mil=(A+B)/2; - pair mA=rotate(90,mil)*A; - pair mB=rotate(-90,mil)*A; - return (abs(m-mA) <= abs(m-mB)) == (abs(p-mA) <= abs(p-mB)); - // transform proj=projection(l.A,l.B); - // point Mp=proj*M; - // point Pp=proj*P; + pair A = l.A, B = l.B, m = M, p = P; + pair mil = (A + B)/2; + pair mA = rotate(90, mil) * A; + pair mB = rotate(-90, mil) * A; + return (abs(m - mA) <= abs(m - mB)) == (abs(p - mA) <= abs(p - mB)); + // transform proj = projection(l.A, l.B); + // point Mp = proj * M; + // point Pp = proj * P; // dot(Mp);dot(Pp); - // return dot(locate(Mp-M),locate(Pp-P)) >= 0; + // return dot(locate(Mp - M), locate(Pp - P)) >= 0; } -/*<asyxml><function type="line" signature="line(segment)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "line(segment)"><code></asyxml>*/ line line(segment s) {/*<asyxml></code><documentation>Return the line passing through 's.A' and 's.B'.</documentation></function></asyxml>*/ - return line(s.A,s.B); + return line(s.A, s.B); } -/*<asyxml><function type="segment" signature="segment(line)"><code></asyxml>*/ +/*<asyxml><function type = "segment" signature = "segment(line)"><code></asyxml>*/ segment segment(line l) {/*<asyxml></code><documentation>Return the segment whose extremities are 'l.A' and 'l.B'.</documentation></function></asyxml>*/ - return segment(l.A,l.B); + return segment(l.A, l.B); } -/*<asyxml><function type="point" signature="midpoint(segment)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "midpoint(segment)"><code></asyxml>*/ point midpoint(segment s) {/*<asyxml></code><documentation>Return the midpoint of 's'.</documentation></function></asyxml>*/ - return 0.5*(s.A+s.B); + return 0.5 * (s.A + s.B); } -/*<asyxml><function type="void" signature="write(line)"><code></asyxml>*/ +/*<asyxml><function type = "void" signature = "write(line)"><code></asyxml>*/ void write(explicit line l) {/*<asyxml></code><documentation>Write some informations about 'l'.</documentation></function></asyxml>*/ - write("A="+(string)((pair)l.A)); - write("Extend A="+(l.extendA ? "true" : "false")); - write("B="+(string)((pair)l.B)); - write("Extend B="+(l.extendB ? "true" : "false")); - write("u="+(string)((pair)l.u)); - write("v="+(string)((pair)l.v)); - write("a="+(string) l.a); - write("b="+(string) l.b); - write("c="+(string) l.c); - write("slope="+(string) l.slope); - write("origin="+(string) l.origin); -} - -/*<asyxml><function type="void" signature="write(explicit segment)"><code></asyxml>*/ + write("A = "+(string)((pair)l.A)); + write("Extend A = "+(l.extendA ? "true" : "false")); + write("B = "+(string)((pair)l.B)); + write("Extend B = "+(l.extendB ? "true" : "false")); + write("u = "+(string)((pair)l.u)); + write("v = "+(string)((pair)l.v)); + write("a = "+(string) l.a); + write("b = "+(string) l.b); + write("c = "+(string) l.c); + write("slope = "+(string) l.slope); + write("origin = "+(string) l.origin); +} + +/*<asyxml><function type = "void" signature = "write(explicit segment)"><code></asyxml>*/ void write(explicit segment s) {/*<asyxml></code><documentation>Write some informations about 's'.</documentation></function></asyxml>*/ - write("A="+(string)((pair)s.A)); - write("B="+(string)((pair)s.B)); - write("u="+(string)((pair)s.u)); - write("v="+(string)((pair)s.v)); - write("a="+(string) s.a); - write("b="+(string) s.b); - write("c="+(string) s.c); - write("slope="+(string) s.slope); - write("origin="+(string) s.origin); -} - -/*<asyxml><operator type="bool" signature="==(line,line)"><code></asyxml>*/ + write("A = "+(string)((pair)s.A)); + write("B = "+(string)((pair)s.B)); + write("u = "+(string)((pair)s.u)); + write("v = "+(string)((pair)s.v)); + write("a = "+(string) s.a); + write("b = "+(string) s.b); + write("c = "+(string) s.c); + write("slope = "+(string) s.slope); + write("origin = "+(string) s.origin); +} + +/*<asyxml><operator type = "bool" signature = "==(line, line)"><code></asyxml>*/ bool operator ==(line l1, line l2) {/*<asyxml></code><documentation>Provide the test 'line == line'.</documentation></operator></asyxml>*/ - return (collinear(l1.u,l2.u) && - abs(ypart((locate(l1.A)-locate(l1.B))/(locate(l1.A)-locate(l2.B)))) < epsgeo && + return (collinear(l1.u, l2.u) && + abs(ypart((locate(l1.A) - locate(l1.B))/(locate(l1.A) - locate(l2.B)))) < epsgeo && l1.extendA == l2.extendA && l1.extendB == l2.extendB); } -/*<asyxml><operator type="bool" signature="!=(line,line)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "!=(line, line)"><code></asyxml>*/ bool operator !=(line l1, line l2) {/*<asyxml></code><documentation>Provide the test 'line != line'.</documentation></operator></asyxml>*/ return !(l1 == l2); } -/*<asyxml><operator type="bool" signature="@(point,line)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "@(point, line)"><code></asyxml>*/ bool operator @(point m, line l) {/*<asyxml></code><documentation>Provide the test 'point @ line'. Return true iff 'm' is on the 'l'.</documentation></operator></asyxml>*/ - point M=changecoordsys(l.A.coordsys,m); - if (abs(l.a*M.x+l.b*M.y+l.c) >= epsgeo) return false; + point M = changecoordsys(l.A.coordsys, m); + if (abs(l.a * M.x + l.b * M.y + l.c) >= epsgeo) return false; if (l.extendA && l.extendB) return true; - if (!l.extendA && !l.extendB) return between(l.A,M,l.B); - if (l.extendA) return sameside(M,l.A,l.B); - return sameside(M,l.B,l.A); + if (!l.extendA && !l.extendB) return between(l.A, M, l.B); + if (l.extendA) return sameside(M, l.A, l.B); + return sameside(M, l.B, l.A); } -/*<asyxml><function type="coordsys" signature="coordsys(line)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "coordsys(line)"><code></asyxml>*/ coordsys coordsys(line l) {/*<asyxml></code><documentation>Return the coordinate system in which 'l' is defined.</documentation></function></asyxml>*/ return l.A.coordsys; } -/*<asyxml><function type="line" signature="reverse(line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "reverse(line)"><code></asyxml>*/ line reverse(line l) {/*<asyxml></code><documentation>Permute the points 'A' and 'B' of 'l' and so its orientation.</documentation></function></asyxml>*/ - return line(l.B,l.extendB,l.A,l.extendA); + return line(l.B, l.extendB, l.A, l.extendA); } -/*<asyxml><function type="line" signature="extend(line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "extend(line)"><code></asyxml>*/ line extend(line l) {/*<asyxml></code><documentation>Return the infinite line passing through 'l.A' and 'l.B'.</documentation></function></asyxml>*/ - line ol=l.copy(); - ol.extendA=true; - ol.extendB=true; + line ol = l.copy(); + ol.extendA = true; + ol.extendB = true; return ol; } -/*<asyxml><function type="line" signature="complementary(explicit line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "complementary(explicit line)"><code></asyxml>*/ line complementary(explicit line l) {/*<asyxml></code><documentation>Return the complementary of a half-line with respect of the full line 'l'.</documentation></function></asyxml>*/ if (l.extendA && l.extendB) abort("complementary: the parameter is not a half-line."); - point origin=l.extendA ? l.B : l.A; - point ptdir=l.extendA ? - rotate(180,l.B)*l.A : rotate(180,l.A)*l.B; - return line(origin,false,ptdir); + point origin = l.extendA ? l.B : l.A; + point ptdir = l.extendA ? + rotate(180, l.B) * l.A : rotate(180, l.A) * l.B; + return line(origin, false, ptdir); } -/*<asyxml><function type="line[]" signature="complementary(explicit segment)"><code></asyxml>*/ +/*<asyxml><function type = "line[]" signature = "complementary(explicit segment)"><code></asyxml>*/ line[] complementary(explicit segment s) {/*<asyxml></code><documentation>Return the two half-lines of origin 's.A' and 's.B' respectively.</documentation></function></asyxml>*/ - line[] ol=new line[2]; - ol[0]=complementary(line(s.A,false,s.B)); - ol[1]=complementary(line(s.A,s.B,false)); + line[] ol = new line[2]; + ol[0] = complementary(line(s.A, false, s.B)); + ol[1] = complementary(line(s.A, s.B, false)); return ol; } -/*<asyxml><function type="line" signature="Ox(coordsys)"><code></asyxml>*/ -line Ox(coordsys R=currentcoordsys) +/*<asyxml><function type = "line" signature = "Ox(coordsys)"><code></asyxml>*/ +line Ox(coordsys R = currentcoordsys) {/*<asyxml></code><documentation>Return the x-axis of 'R'.</documentation></function></asyxml>*/ - return line(point(R,(0,0)), point(R,E)); + return line(point(R, (0, 0)), point(R, E)); } -/*<asyxml><constant type="line" signature="Ox"><code></asyxml>*/ -restricted line Ox=Ox();/*<asyxml></code><documentation>the x-axis of +/*<asyxml><constant type = "line" signature = "Ox"><code></asyxml>*/ +restricted line Ox = Ox();/*<asyxml></code><documentation>the x-axis of the default coordinate system.</documentation></constant></asyxml>*/ -/*<asyxml><function type="line" signature="Oy(coordsys)"><code></asyxml>*/ -line Oy(coordsys R=currentcoordsys) +/*<asyxml><function type = "line" signature = "Oy(coordsys)"><code></asyxml>*/ +line Oy(coordsys R = currentcoordsys) {/*<asyxml></code><documentation>Return the y-axis of 'R'.</documentation></function></asyxml>*/ - return line(point(R,(0,0)), point(R,N)); + return line(point(R, (0, 0)), point(R, N)); } -/*<asyxml><constant type="line" signature="Oy"><code></asyxml>*/ -restricted line Oy=Oy();/*<asyxml></code><documentation>the y-axis of +/*<asyxml><constant type = "line" signature = "Oy"><code></asyxml>*/ +restricted line Oy = Oy();/*<asyxml></code><documentation>the y-axis of the default coordinate system.</documentation></constant></asyxml>*/ -/*<asyxml><function type="line" signature="line(real,point)"><code></asyxml>*/ -line line(real a, point A=point(currentcoordsys,(0,0))) +/*<asyxml><function type = "line" signature = "line(real, point)"><code></asyxml>*/ +line line(real a, point A = point(currentcoordsys, (0, 0))) {/*<asyxml></code><documentation>Return the line passing through 'A' with an angle (in the coordinate system of A) 'a' in degrees. - line(point,real) is also defined.</documentation></function></asyxml>*/ - return line(A, A+point(A.coordsys,A.coordsys.polar(1,radians(a)))); + line(point, real) is also defined.</documentation></function></asyxml>*/ + return line(A, A + point(A.coordsys, A.coordsys.polar(1, radians(a)))); } -line line(point A=point(currentcoordsys,(0,0)),real a) +line line(point A = point(currentcoordsys, (0, 0)), real a) { - return line(a,A); + return line(a, A); } -line line(int a, point A=point(currentcoordsys,(0,0))) +line line(int a, point A = point(currentcoordsys, (0, 0))) { return line((real)a, A); } -/*<asyxml><function type="line" signature="line(coordsys,real,real)"><code></asyxml>*/ -line line(coordsys R=currentcoordsys, real slope, real origin) +/*<asyxml><function type = "line" signature = "line(coordsys, real, real)"><code></asyxml>*/ +line line(coordsys R = currentcoordsys, real slope, real origin) {/*<asyxml></code><documentation>Return the line defined by slope and y-intercept relative to 'R'.</documentation></function></asyxml>*/ if (slope == infinity || slope == -infinity) abort("The slope is infinite. Please, use the routine 'vline'."); - return line(point(R,(0,origin)), point(R,(1,origin+slope))); + return line(point(R, (0, origin)), point(R, (1, origin + slope))); } -/*<asyxml><function type="line" signature="line(coordsys,real,real,real)"><code></asyxml>*/ -line line(coordsys R=currentcoordsys, real a, real b, real c) +/*<asyxml><function type = "line" signature = "line(coordsys, real, real, real)"><code></asyxml>*/ +line line(coordsys R = currentcoordsys, real a, real b, real c) {/*<asyxml></code><documentation>Retrun the line defined by equation relative to 'R'.</documentation></function></asyxml>*/ if (a == 0 && b == 0) abort("line: inconsistent equation..."); pair M; - M=(a == 0) ? (0,-c/b) : (-c/a,0); - return line(point(R,M), point(R,M+(-b,a))); + M = (a == 0) ? (0, -c/b) : (-c/a, 0); + return line(point(R, M), point(R, M + (-b, a))); } -/*<asyxml><function type="line" signature="vline(coordsys)"><code></asyxml>*/ -line vline(coordsys R=currentcoordsys) +/*<asyxml><function type = "line" signature = "vline(coordsys)"><code></asyxml>*/ +line vline(coordsys R = currentcoordsys) {/*<asyxml></code><documentation>Return a vertical line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/ - point P=point(R,(0,0)); - point PP=point(R,(R.O+N)/R); - return line(P,PP); + point P = point(R, (0, 0)); + point PP = point(R, (R.O + N)/R); + return line(P, PP); } -/*<asyxml><constant type="line" signature="vline"><code></asyxml>*/ -restricted line vline=vline();/*<asyxml></code><documentation>The vertical line in the current coordinate system passing +/*<asyxml><constant type = "line" signature = "vline"><code></asyxml>*/ +restricted line vline = vline();/*<asyxml></code><documentation>The vertical line in the current coordinate system passing through the origin of this system.</documentation></constant></asyxml>*/ -/*<asyxml><function type="line" signature="hline(coordsys)"><code></asyxml>*/ -line hline(coordsys R=currentcoordsys) +/*<asyxml><function type = "line" signature = "hline(coordsys)"><code></asyxml>*/ +line hline(coordsys R = currentcoordsys) {/*<asyxml></code><documentation>Return a horizontal line in 'R' passing through the origin of 'R'.</documentation></function></asyxml>*/ - point P=point(R,(0,0)); - point PP=point(R,(R.O+E)/R); - return line(P,PP); + point P = point(R, (0, 0)); + point PP = point(R, (R.O + E)/R); + return line(P, PP); } -/*<asyxml><constant type="line" signature="hline"><code></asyxml>*/ -line hline=hline();/*<asyxml></code><documentation>The horizontal line in the current coordinate system passing +/*<asyxml><constant type = "line" signature = "hline"><code></asyxml>*/ +line hline = hline();/*<asyxml></code><documentation>The horizontal line in the current coordinate system passing through the origin of this system.</documentation></constant></asyxml>*/ -/*<asyxml><function type="line" signature="changecoordsys(coordsys,line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "changecoordsys(coordsys, line)"><code></asyxml>*/ line changecoordsys(coordsys R, line l) {/*<asyxml></code><documentation>Return the line 'l' in the coordinate system 'R'.</documentation></function></asyxml>*/ - point A=changecoordsys(R,l.A); - point B=changecoordsys(R,l.B); - return line(A,B); + point A = changecoordsys(R, l.A); + point B = changecoordsys(R, l.B); + return line(A, B); } -/*<asyxml><function type="transform" signature="scale(real,line,line,bool)"><code></asyxml>*/ -transform scale(real k, line l1, line l2, bool safe=false) +/*<asyxml><function type = "transform" signature = "scale(real, line, line, bool)"><code></asyxml>*/ +transform scale(real k, line l1, line l2, bool safe = false) {/*<asyxml></code><documentation>Return the dilatation with respect to 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/ - return scale(k,l1.A,l1.B,l2.A,l2.B,safe); + return scale(k, l1.A, l1.B, l2.A, l2.B, safe); } -/*<asyxml><function type="transform" signature="reflect(line)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "reflect(line)"><code></asyxml>*/ transform reflect(line l) {/*<asyxml></code><documentation>Return the reflect about the line 'l'.</documentation></function></asyxml>*/ - return reflect((pair)l.A,(pair)l.B); + return reflect((pair)l.A, (pair)l.B); } -/*<asyxml><function type="transform" signature="reflect(line,line)"><code></asyxml>*/ -transform reflect(line l1, line l2, bool safe=false) +/*<asyxml><function type = "transform" signature = "reflect(line, line)"><code></asyxml>*/ +transform reflect(line l1, line l2, bool safe = false) {/*<asyxml></code><documentation>Return the reflect about the line 'l1' in the direction of 'l2'.</documentation></function></asyxml>*/ - return scale(-1.0,l1,l2,safe); + return scale(-1.0, l1, l2, safe); } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,path)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, path)"><code></asyxml>*/ point[] intersectionpoints(line l, path g) {/*<asyxml></code><documentation>Return all points of intersection of the line 'l' with the path 'g'.</documentation></function></asyxml>*/ // TODO utiliser la version 1.44 de intersections(path g, pair p, pair q) - // real [] t=intersections(g,l.A,l.B); - // coordsys R=coordsys(l); - // return sequence(new point(int n){return point(R,point(g,t[n])/R);}, t.length); + // real [] t = intersections(g, l.A, l.B); + // coordsys R = coordsys(l); + // return sequence(new point(int n){return point(R, point(g, t[n])/R);}, t.length); real [] t; pair[] op; - pair A=l.A; - pair B=l.B; - real dy=B.y-A.y, - dx=A.x-B.x, - lg=length(g); - for (int i=0; i<lg; ++i) + pair A = l.A; + pair B = l.B; + real dy = B.y - A.y, + dx = A.x - B.x, + lg = length(g); + + for (int i = 0; i < lg; ++i) { - pair z0=point(g,i), - z1=point(g,i+1), - c0=postcontrol(g,i), - c1=precontrol(g,i+1), - t3=z1-z0-3*c1+3*c0, - t2=3*z0+3*c1-6*c0, - t1=3*c0-3z0; - real a=dy*t3.x+dx*t3.y, - b=dy*t2.x+dx*t2.y, - c=dy*t1.x+dx*t1.y, - d=dy*z0.x+dx*z0.y+A.y*B.x-A.x*B.y; - t=cubicroots(a,b,c,d); - for (int j=0; j<t.length; ++j) - if (t[j]>=0 && (t[j]<1 || (t[j]==1 && i==lg-1 && !cyclic(g)))) op.push(point(g,i+t[j])); + pair z0 = point(g, i), + z1 = point(g, i + 1), + c0 = postcontrol(g, i), + c1 = precontrol(g, i + 1), + t3 = z1 - z0 - 3 * c1 + 3 * c0, + t2 = 3 * z0 + 3 * c1 - 6 * c0, + t1 = 3 * c0 - 3z0; + real a = dy * t3.x + dx * t3.y, + b = dy * t2.x + dx * t2.y, + c = dy * t1.x + dx * t1.y, + d = dy * z0.x + dx * z0.y + A.y * B.x - A.x * B.y; + + t = cubicroots(a, b, c, d); + for (int j = 0; j < t.length; ++j) + if ( + t[j]>=0 + && ( + t[j]<1 + || ( + t[j] == 1 + && (i == lg - 1) + && !cyclic(g) + ) + ) + ) { + op.push(point(g, i + t[j])); + } } + point[] opp; - for (int i=0; i<op.length; ++i) - opp.push(point(coordsys(l),op[i]/coordsys(l))); + for (int i = 0; i < op.length; ++i) + opp.push(point(coordsys(l), op[i]/coordsys(l))); return opp; } -/*<asyxml><function type="point" signature="intersectionpoint(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "intersectionpoint(line, line)"><code></asyxml>*/ point intersectionpoint(line l1, line l2) {/*<asyxml></code><documentation>Return the point of intersection of line 'l1' with 'l2'. If 'l1' and 'l2' have an infinity or none point of intersection, - this routine return (infinity,infinity).</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(l1.A,l1.B,l2.A,l2.B); - coordsys R=P[0].coordsys; - pair p=extension(P[0],P[1],P[2],P[3]); + this routine return (infinity, infinity).</documentation></function></asyxml>*/ + point[] P = standardizecoordsys(l1.A, l1.B, l2.A, l2.B); + coordsys R = P[0].coordsys; + pair p = extension(P[0], P[1], P[2], P[3]); if(finite(p)){ - point p=point(R,p/R); + point p = point(R, p/R); if (p @ l1 && p @ l2) return p; } - return point(R,(infinity,infinity)); + return point(R, (infinity, infinity)); } -/*<asyxml><function type="line" signature="parallel(point,line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "parallel(point, line)"><code></asyxml>*/ line parallel(point M, line l) {/*<asyxml></code><documentation>Return the line parallel to 'l' passing through 'M'.</documentation></function></asyxml>*/ - point A,B; + point A, B; if (M.coordsys != coordsys(l)) { - A=changecoordsys(M.coordsys,l.A); - B=changecoordsys(M.coordsys,l.B); - } else {A=l.A;B=l.B;} - return line(M,M-A+B); + A = changecoordsys(M.coordsys, l.A); + B = changecoordsys(M.coordsys, l.B); + } else {A = l.A;B = l.B;} + return line(M, M - A + B); } -/*<asyxml><function type="line" signature="parallel(point,explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "parallel(point, explicit vector)"><code></asyxml>*/ line parallel(point M, explicit vector dir) {/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/ - return line(M,M+locate(dir)); + return line(M, M + locate(dir)); } -/*<asyxml><function type="line" signature="parallel(point,explicit pair)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "parallel(point, explicit pair)"><code></asyxml>*/ line parallel(point M, explicit pair dir) {/*<asyxml></code><documentation>Return the line of direction 'dir' and passing through 'M'.</documentation></function></asyxml>*/ - return line(M,M+vector(currentcoordsys,dir)); + return line(M, M + vector(currentcoordsys, dir)); } -/*<asyxml><function type="bool" signature="parallel(line,line)"><code></asyxml>*/ -bool parallel(line l1, line l2, bool strictly=false) +/*<asyxml><function type = "bool" signature = "parallel(line, line)"><code></asyxml>*/ +bool parallel(line l1, line l2, bool strictly = false) {/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are (strictly ?) parallel.</documentation></function></asyxml>*/ - bool coll=collinear(l1.u,l2.u); + bool coll = collinear(l1.u, l2.u); return strictly ? coll && (l1 != l2) : coll; } -/*<asyxml><function type="bool" signature="concurrent(...line[])"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "concurrent(...line[])"><code></asyxml>*/ bool concurrent(... line[] l) {/*<asyxml></code><documentation>Returns true if all the lines 'l' are concurrent.</documentation></function></asyxml>*/ if (l.length < 3) abort("'concurrent' needs at least for three lines ..."); - pair point=intersectionpoint(l[0],l[1]); + pair point = intersectionpoint(l[0], l[1]); bool conc; - for (int i=2; i < l.length; ++i) { - pair pt=intersectionpoint(l[i-1],l[i]); - conc=simeq(pt, point); + for (int i = 2; i < l.length; ++i) { + pair pt = intersectionpoint(l[i - 1], l[i]); + conc = simeq(pt, point); if (!conc) break; } return conc; } -/*<asyxml><function type="transform" signature="projection(line)"><code></asyxml>*/ +/*<asyxml><function type = "transform" signature = "projection(line)"><code></asyxml>*/ transform projection(line l) {/*<asyxml></code><documentation>Return the orthogonal projection on 'l'.</documentation></function></asyxml>*/ - return projection(l.A,l.B); + return projection(l.A, l.B); } -/*<asyxml><function type="transform" signature="projection(line,line,bool)"><code></asyxml>*/ -transform projection(line l1, line l2, bool safe=false) +/*<asyxml><function type = "transform" signature = "projection(line, line, bool)"><code></asyxml>*/ +transform projection(line l1, line l2, bool safe = false) {/*<asyxml></code><documentation>Return the projection on (AB) in parallel of (CD). - If 'safe=true' and (l1)//(l2) return the identity. - If 'safe=false' and (l1)//(l2) return a infinity scaling.</documentation></function></asyxml>*/ - return projection(l1.A,l1.B,l2.A,l2.B,safe); + If 'safe = true' and (l1)//(l2) return the identity. + If 'safe = false' and (l1)//(l2) return a infinity scaling.</documentation></function></asyxml>*/ + return projection(l1.A, l1.B, l2.A, l2.B, safe); } -/*<asyxml><function type="transform" signature="vprojection(line,bool)"><code></asyxml>*/ -transform vprojection(line l, bool safe=false) +/*<asyxml><function type = "transform" signature = "vprojection(line, bool)"><code></asyxml>*/ +transform vprojection(line l, bool safe = false) {/*<asyxml></code><documentation>Return the projection on 'l' in parallel of N--S. If 'safe' is 'true' the projected point keeps the same place if 'l' is vertical.</documentation></function></asyxml>*/ - coordsys R=defaultcoordsys; - return projection(l, line(point(R,N),point(R,S)), safe); + coordsys R = defaultcoordsys; + return projection(l, line(point(R, N), point(R, S)), safe); } -/*<asyxml><function type="transform" signature="hprojection(line,bool)"><code></asyxml>*/ -transform hprojection(line l, bool safe=false) +/*<asyxml><function type = "transform" signature = "hprojection(line, bool)"><code></asyxml>*/ +transform hprojection(line l, bool safe = false) {/*<asyxml></code><documentation>Return the projection on 'l' in parallel of E--W. If 'safe' is 'true' the projected point keeps the same place if 'l' is horizontal.</documentation></function></asyxml>*/ - coordsys R=defaultcoordsys; - return projection(l, line(point(R,E),point(R,W)), safe); + coordsys R = defaultcoordsys; + return projection(l, line(point(R, E), point(R, W)), safe); } -/*<asyxml><function type="line" signature="perpendicular(point,line)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "perpendicular(point, line)"><code></asyxml>*/ line perpendicular(point M, line l) {/*<asyxml></code><documentation>Return the perpendicular line of 'l' passing through 'M'.</documentation></function></asyxml>*/ - point Mp=projection(l)*M; - point A=Mp == l.A ? l.B : l.A; - return line(Mp, rotate(90,Mp)*A); + point Mp = projection(l) * M; + point A = Mp == l.A ? l.B : l.A; + return line(Mp, rotate(90, Mp) * A); } -/*<asyxml><function type="line" signature="perpendicular(point,explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "perpendicular(point, explicit vector)"><code></asyxml>*/ line perpendicular(point M, explicit vector normal) {/*<asyxml></code><documentation>Return the line passing through 'M' whose normal is \param{normal}.</documentation></function></asyxml>*/ - return perpendicular(M,line(M,M+locate(normal))); + return perpendicular(M, line(M, M + locate(normal))); } -/*<asyxml><function type="line" signature="perpendicular(point,explicit pair)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "perpendicular(point, explicit pair)"><code></asyxml>*/ line perpendicular(point M, explicit pair normal) {/*<asyxml></code><documentation>Return the line passing through 'M' whose normal is \param{normal} (given in the currentcoordsys).</documentation></function></asyxml>*/ - return perpendicular(M,line(M,M+vector(currentcoordsys,normal))); + return perpendicular(M, line(M, M + vector(currentcoordsys, normal))); } -/*<asyxml><function type="bool" signature="perpendicular(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "perpendicular(line, line)"><code></asyxml>*/ bool perpendicular(line l1, line l2) {/*<asyxml></code><documentation>Return 'true' if 'l1' and 'l2' are perpendicular.</documentation></function></asyxml>*/ - return abs(dot(locate(l1.u),locate(l2.u))) < epsgeo ; + return abs(dot(locate(l1.u), locate(l2.u))) < epsgeo ; } -/*<asyxml><function type="real" signature="angle(line,coordsys)"><code></asyxml>*/ -real angle(line l, coordsys R=coordsys(l)) +/*<asyxml><function type = "real" signature = "angle(line, coordsys)"><code></asyxml>*/ +real angle(line l, coordsys R = coordsys(l)) {/*<asyxml></code><documentation>Return the angle of the oriented line 'l', - in radian, in the interval ]-pi,pi] and relatively to 'R'.</documentation></function></asyxml>*/ + in radian, in the interval ]-pi, pi] and relatively to 'R'.</documentation></function></asyxml>*/ return angle(l.u, R, false); } -/*<asyxml><function type="real" signature="degrees(line,coordsys,bool)"><code></asyxml>*/ -real degrees(line l, coordsys R=coordsys(l)) +/*<asyxml><function type = "real" signature = "degrees(line, coordsys, bool)"><code></asyxml>*/ +real degrees(line l, coordsys R = coordsys(l)) {/*<asyxml></code><documentation>Returns the angle of the oriented line 'l' in degrees, - in the interval [0,360[ and relatively to 'R'.</documentation></function></asyxml>*/ + in the interval [0, 360[ and relatively to 'R'.</documentation></function></asyxml>*/ return degrees(angle(l, R)); } -/*<asyxml><function type="real" signature="sharpangle(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "sharpangle(line, line)"><code></asyxml>*/ real sharpangle(line l1, line l2) {/*<asyxml></code><documentation>Return the measure in radians of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/ - vector u1=l1.u; - vector u2=(dot(l1.u,l2.u) < 0) ? -l2.u : l2.u; - real a12=angle(locate(u2))-angle(locate(u1)); - a12=a12%(sgnd(a12)*pi); - if (a12 <= -pi/2) a12 += pi; else if (a12 > pi/2) a12 -= pi; + vector u1 = l1.u; + vector u2 = (dot(l1.u, l2.u) < 0) ? -l2.u : l2.u; + real a12 = angle(locate(u2)) - angle(locate(u1)); + a12 = a12%(sgnd(a12) * pi); + if (a12 <= -pi/2) { + a12 += pi; + } else if (a12 > pi/2) { + a12 -= pi; + } return a12; } -/*<asyxml><function type="real" signature="angle(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "angle(line, line)"><code></asyxml>*/ real angle(line l1, line l2) -{/*<asyxml></code><documentation>Return the measure in radians of oriented angle (l1.u,l2.u).</documentation></function></asyxml>*/ - return angle(locate(l2.u))-angle(locate(l1.u)); +{/*<asyxml></code><documentation>Return the measure in radians of oriented angle (l1.u, l2.u).</documentation></function></asyxml>*/ + return angle(locate(l2.u)) - angle(locate(l1.u)); } -/*<asyxml><function type="real" signature="degrees(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "degrees(line, line)"><code></asyxml>*/ real degrees(line l1, line l2) {/*<asyxml></code><documentation>Return the measure in degrees of the angle formed by the oriented lines 'l1' and 'l2'.</documentation></function></asyxml>*/ - return degrees(angle(l1,l2)); + return degrees(angle(l1, l2)); } -/*<asyxml><function type="real" signature="sharpdegrees(line,line)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "sharpdegrees(line, line)"><code></asyxml>*/ real sharpdegrees(line l1, line l2) {/*<asyxml></code><documentation>Return the measure in degrees of the sharp angle formed by 'l1' and 'l2'.</documentation></function></asyxml>*/ - return degrees(sharpangle(l1,l2)); + return degrees(sharpangle(l1, l2)); } -/*<asyxml><function type="line" signature="bisector(line,line,real,bool)"><code></asyxml>*/ -line bisector(line l1, line l2, real angle=0, bool sharp=true) +/*<asyxml><function type = "line" signature = "bisector(line, line, real, bool)"><code></asyxml>*/ +line bisector(line l1, line l2, real angle = 0, bool sharp = true) {/*<asyxml></code><documentation>Return the bisector of the angle formed by 'l1' and 'l2' rotated by the angle 'angle' (in degrees) around intersection point of 'l1' with 'l2'. If 'sharp' is true (the default), this routine returns the bisector of the sharp angle. Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/ line ol; if (l1 == l2) return l1; - point A=intersectionpoint(l1,l2); + point A = intersectionpoint(l1, l2); if (finite(A)) { - if(sharp) ol=rotate(sharpdegrees(l1,l2)/2+angle,A)*l1; + if(sharp) ol = rotate(sharpdegrees(l1, l2)/2 + angle, A) * l1; else { - coordsys R=coordsys(l1); - pair a=A, b=A+l1.u, c=A+l2.u; - pair pp=extension(a, a+dir(a--b,a--c), b, b+dir(b--a,b--c)); - return rotate(angle,A)*line(A,point(R,pp/R)); + coordsys R = coordsys(l1); + pair a = A, b = A + l1.u, c = A + l2.u; + pair pp = extension(a, a + dir(a--b, a--c), b, b + dir(b--a, b--c)); + return rotate(angle, A) * line(A, point(R, pp/R)); } } else { - ol=l1; + ol = l1; } return ol; } -/*<asyxml><function type="line" signature="sector(int,int,line,line,real,bool)"><code></asyxml>*/ -line sector(int n=2, int p=1, line l1, line l2, real angle=0, bool sharp=true) +/*<asyxml><function type = "line" signature = "sector(int, int, line, line, real, bool)"><code></asyxml>*/ +line sector(int n = 2, int p = 1, line l1, line l2, real angle = 0, bool sharp = true) {/*<asyxml></code><documentation>Return the p-th nth-sector of the angle formed by the oriented line 'l1' and 'l2' rotated by the angle 'angle' (in degrees) around the intersection point of 'l1' with 'l2'. @@ -2086,317 +2105,317 @@ line sector(int n=2, int p=1, line l1, line l2, real angle=0, bool sharp=true) Note that the returned line inherit of coordinate system of 'l1'.</documentation></function></asyxml>*/ line ol; if (l1 == l2) return l1; - point A=intersectionpoint(l1,l2); + point A = intersectionpoint(l1, l2); if (finite(A)) { - if(sharp) ol=rotate(p*sharpdegrees(l1,l2)/n+angle,A)*l1; + if(sharp) ol = rotate(p * sharpdegrees(l1, l2)/n + angle, A) * l1; else { - ol=rotate(p*degrees(l1,l2)/n+angle,A)*l1; + ol = rotate(p * degrees(l1, l2)/n + angle, A) * l1; } } else { - ol=l1; + ol = l1; } return ol; } -/*<asyxml><function type="line" signature="bisector(point,point,point,point,real)"><code></asyxml>*/ -line bisector(point A, point B, point C, point D, real angle=0, bool sharp=true) +/*<asyxml><function type = "line" signature = "bisector(point, point, point, point, real)"><code></asyxml>*/ +line bisector(point A, point B, point C, point D, real angle = 0, bool sharp = true) {/*<asyxml></code><documentation>Return the bisector of the angle formed by the lines (AB) and (CD). - <look href="#bisector(line,line,real,bool)"/>.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B,C,D); - return bisector(line(P[0],P[1]),line(P[2],P[3]),angle,sharp); + <look href = "#bisector(line, line, real, bool)"/>.</documentation></function></asyxml>*/ + point[] P = standardizecoordsys(A, B, C, D); + return bisector(line(P[0], P[1]), line(P[2], P[3]), angle, sharp); } -/*<asyxml><function type="line" signature="bisector(segment,real)"><code></asyxml>*/ -line bisector(segment s, real angle=0) +/*<asyxml><function type = "line" signature = "bisector(segment, real)"><code></asyxml>*/ +line bisector(segment s, real angle = 0) {/*<asyxml></code><documentation>Return the bisector of the segment line 's' rotated by 'angle' (in degrees) around the midpoint of 's'.</documentation></function></asyxml>*/ - coordsys R=coordsys(s); - point m=midpoint(s); - vector dir=rotateO(90)*unit(s.A-m); - return rotate(angle,m)*line(m+dir,m-dir); + coordsys R = coordsys(s); + point m = midpoint(s); + vector dir = rotateO(90) * unit(s.A - m); + return rotate(angle, m) * line(m + dir, m - dir); } -/*<asyxml><function type="line" signature="bisector(point,point,real)"><code></asyxml>*/ -line bisector(point A, point B, real angle=0) +/*<asyxml><function type = "line" signature = "bisector(point, point, real)"><code></asyxml>*/ +line bisector(point A, point B, real angle = 0) {/*<asyxml></code><documentation>Return the bisector of the segment line [AB] rotated by 'angle' (in degrees) around the midpoint of [AB].</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B); - return bisector(segment(P[0],P[1]),angle); + point[] P = standardizecoordsys(A, B); + return bisector(segment(P[0], P[1]), angle); } -/*<asyxml><function type="real" signature="distance(point,line)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "distance(point, line)"><code></asyxml>*/ real distance(point M, line l) {/*<asyxml></code><documentation>Return the distance from 'M' to 'l'. - distance(line,point) is also defined.</documentation></function></asyxml>*/ - point A=changecoordsys(defaultcoordsys,l.A); - point B=changecoordsys(defaultcoordsys,l.B); - line ll=line(A,B); - pair m=locate(M); - return abs(ll.a*m.x+ll.b*m.y+ll.c)/sqrt(ll.a^2+ll.b^2); + distance(line, point) is also defined.</documentation></function></asyxml>*/ + point A = changecoordsys(defaultcoordsys, l.A); + point B = changecoordsys(defaultcoordsys, l.B); + line ll = line(A, B); + pair m = locate(M); + return abs(ll.a * m.x + ll.b * m.y + ll.c)/sqrt(ll.a^2 + ll.b^2); } real distance(line l, point M) { - return distance(M,l); + return distance(M, l); } -/*<asyxml><function type="void" signature="draw(picture,Label,line,bool,bool,align,pen,arrowbar,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="", - line l, bool dirA=l.extendA, bool dirB=l.extendB, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, - Label legend="", marker marker=nomarker, - pathModifier pathModifier=NoModifier) +/*<asyxml><function type = "void" signature = "draw(picture, Label, line, bool, bool, align, pen, arrowbar, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", + line l, bool dirA = l.extendA, bool dirB = l.extendB, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, + Label legend = "", marker marker = nomarker, + pathModifier pathModifier = NoModifier) {/*<asyxml></code><documentation>Draw the line 'l' without altering the size of picture pic. The boolean parameters control the infinite section. The global variable 'linemargin' (default value is 0) allows to modify the bounding box in which the line must be drawn.</documentation></function></asyxml>*/ if(!(dirA || dirB)) draw(l.A--l.B, invisible);// l is a segment. - Drawline(pic, L, l.A, dirP=dirA, l.B, dirQ=dirB, + Drawline(pic, L, l.A, dirP = dirA, l.B, dirQ = dirB, align, p, arrow, legend, marker, pathModifier); } -/*<asyxml><function type="void" signature="draw(picture,Label[],line[],align,pen[],arrowbar,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture,Label[] L=new Label[], line[] l, - align align=NoAlign, pen[] p=new pen[], - arrowbar arrow=None, - Label[] legend=new Label[], marker marker=nomarker, - pathModifier pathModifier=NoModifier) +/*<asyxml><function type = "void" signature = "draw(picture, Label[], line[], align, pen[], arrowbar, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label[] L = new Label[], line[] l, + align align = NoAlign, pen[] p = new pen[], + arrowbar arrow = None, + Label[] legend = new Label[], marker marker = nomarker, + pathModifier pathModifier = NoModifier) {/*<asyxml></code><documentation>Draw each lines with the corresponding pen.</documentation></function></asyxml>*/ - for (int i=0; i < l.length; ++i) { + for (int i = 0; i < l.length; ++i) { draw(pic, L.length>0 ? L[i] : "", l[i], - align, p=p.length>0 ? p[i] : currentpen, + align, p = p.length>0 ? p[i] : currentpen, arrow, legend.length>0 ? legend[i] : "", marker, pathModifier); } } -/*<asyxml><function type="void" signature="draw(picture,Label[],line[],align,pen,arrowbar,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture,Label[] L=new Label[], line[] l, - align align=NoAlign, pen p, - arrowbar arrow=None, - Label[] legend=new Label[], marker marker=nomarker, - pathModifier pathModifier=NoModifier) +/*<asyxml><function type = "void" signature = "draw(picture, Label[], line[], align, pen, arrowbar, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label[] L = new Label[], line[] l, + align align = NoAlign, pen p, + arrowbar arrow = None, + Label[] legend = new Label[], marker marker = nomarker, + pathModifier pathModifier = NoModifier) {/*<asyxml></code><documentation>Draw each lines with the same pen 'p'.</documentation></function></asyxml>*/ - pen[] tp=sequence(new pen(int i){return p;},l.length); + pen[] tp = sequence(new pen(int i){return p;}, l.length); draw(pic, L, l, align, tp, arrow, legend, marker, pathModifier); } -/*<asyxml><function type="void" signature="show(picture,line,pen)"><code></asyxml>*/ -void show(picture pic=currentpicture, line l, pen p=red) +/*<asyxml><function type = "void" signature = "show(picture, line, pen)"><code></asyxml>*/ +void show(picture pic = currentpicture, line l, pen p = red) {/*<asyxml></code><documentation>Draw some informations of 'l'.</documentation></function></asyxml>*/ - dot("$A$",(pair)l.A,align=-locate(l.v),p); - dot("$B$",(pair)l.B,align=-locate(l.v),p); - draw(l,dotted); - draw("$\vec{u}$",locate(l.A)--locate(l.A+l.u),p,Arrow); - draw("$\vec{v}$",locate(l.A)--locate(l.A+l.v),p,Arrow); + dot("$A$", (pair)l.A, align = -locate(l.v), p); + dot("$B$", (pair)l.B, align = -locate(l.v), p); + draw(l, dotted); + draw("$\vec{u}$", locate(l.A)--locate(l.A + l.u), p, Arrow); + draw("$\vec{v}$", locate(l.A)--locate(l.A + l.v), p, Arrow); } -/*<asyxml><function type="point[]" signature="sameside(point,line,line)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "sameside(point, line, line)"><code></asyxml>*/ point[] sameside(point M, line l1, line l2) {/*<asyxml></code><documentation>Return two points on 'l1' and 'l2' respectively. The first point is from the same side of M relatively to 'l2', the second point is from the same side of M relatively to 'l1'.</documentation></function></asyxml>*/ point[] op; - coordsys R1=coordsys(l1); - coordsys R2=coordsys(l2); - if (parallel(l1,l2)) { - op.push(projection(l1)*M); - op.push(projection(l2)*M); + coordsys R1 = coordsys(l1); + coordsys R2 = coordsys(l2); + if (parallel(l1, l2)) { + op.push(projection(l1) * M); + op.push(projection(l2) * M); } else { - point O=intersectionpoint(l1,l2); - if (M @ l2) op.push((sameside(M,O+l1.u,l2)) ? O+l1.u : rotate(180,O)*(O+l1.u)); - else op.push(projection(l1,l2)*M); - if (M @ l1) op.push((sameside(M,O+l2.u,l1)) ? O+l2.u : rotate(180,O)*(O+l2.u)); - else {op.push(projection(l2,l1)*M);} + point O = intersectionpoint(l1, l2); + if (M @ l2) op.push((sameside(M, O + l1.u, l2)) ? O + l1.u : rotate(180, O) * (O + l1.u)); + else op.push(projection(l1, l2) * M); + if (M @ l1) op.push((sameside(M, O + l2.u, l1)) ? O + l2.u : rotate(180, O) * (O + l2.u)); + else {op.push(projection(l2, l1) * M);} } return op; } -// /*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,explicit pair,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/ -// void markangle(picture pic=currentpicture, -// Label L="", int n=1, real radius=0, real space=0, -// line l1, line l2, explicit pair align=dir(1), -// arrowbar arrow=None, pen p=currentpen, -// filltype filltype=NoFill, -// margin margin=NoMargin, marker marker=nomarker) -// {/*<asyxml></code><documentation>Mark the angle (l1,l2) aligned in the direction 'align' relative to 'l1'. +// /*<asyxml><function type = "void" signature = "markangle(picture, Label, int, real, real, line, line, explicit pair, arrowbar, pen, filltype, margin, marker)"><code></asyxml>*/ +// void markangle(picture pic = currentpicture, +// Label L = "", int n = 1, real radius = 0, real space = 0, +// line l1, line l2, explicit pair align = dir(1), +// arrowbar arrow = None, pen p = currentpen, +// filltype filltype = NoFill, +// margin margin = NoMargin, marker marker = nomarker) +// {/*<asyxml></code><documentation>Mark the angle (l1, l2) aligned in the direction 'align' relative to 'l1'. // Commune values for 'align' are dir(real).</documentation></function></asyxml>*/ -// if (parallel(l1,l2,true)) return; -// real al=degrees(l1,defaultcoordsys); -// pair O,A,B; -// if (radius == 0) radius=markangleradius(p); -// real d=degrees(locate(l1.u)); -// align=rotate(d)*align; +// if (parallel(l1, l2, true)) return; +// real al = degrees(l1, defaultcoordsys); +// pair O, A, B; +// if (radius == 0) radius = markangleradius(p); +// real d = degrees(locate(l1.u)); +// align = rotate(d) * align; // if (l1 == l2) { -// O=midpoint(segment(l1.A,l1.B)); -// A=l1.A;B=l1.B; -// if (sameside(rotate(sgn(angle(B-A))*45,O)*A,O+align,l1)) {radius=-radius;} +// O = midpoint(segment(l1.A, l1.B)); +// A = l1.A;B = l1.B; +// if (sameside(rotate(sgn(angle(B-A)) * 45, O) * A, O + align, l1)) {radius = -radius;} // } else { -// O=intersectionpoint(extend(l1),extend(l2)); -// pair R=O+align; -// point [] ss=sameside(point(coordsys(l1),R/coordsys(l1)),l1,l2); -// A=ss[0]; -// B=ss[1]; +// O = intersectionpoint(extend(l1), extend(l2)); +// pair R = O + align; +// point [] ss = sameside(point(coordsys(l1), R/coordsys(l1)), l1, l2); +// A = ss[0]; +// B = ss[1]; // } -// markangle(pic=pic,L=L,n=n,radius=radius,space=space, -// O=O,A=A,B=B, -// arrow=arrow,p=p,filltype=filltype, -// margin=margin,marker=marker); +// markangle(pic = pic, L = L, n = n, radius = radius, space = space, +// O = O, A = A, B = B, +// arrow = arrow, p = p, filltype = filltype, +// margin = margin, marker = marker); // } -// /*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,explicit vector,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/ -// void markangle(picture pic=currentpicture, -// Label L="", int n=1, real radius=0, real space=0, -// line l1, line l2,explicit vector align, -// arrowbar arrow=None, pen p=currentpen, -// filltype filltype=NoFill, -// margin margin=NoMargin, marker marker=nomarker) -// {/*<asyxml></code><documentation>Mark the angle (l1,l2) in the direction 'dir' given relatively to 'l1'.</documentation></function></asyxml>*/ +// /*<asyxml><function type = "void" signature = "markangle(picture, Label, int, real, real, line, line, explicit vector, arrowbar, pen, filltype, margin, marker)"><code></asyxml>*/ +// void markangle(picture pic = currentpicture, +// Label L = "", int n = 1, real radius = 0, real space = 0, +// line l1, line l2, explicit vector align, +// arrowbar arrow = None, pen p = currentpen, +// filltype filltype = NoFill, +// margin margin = NoMargin, marker marker = nomarker) +// {/*<asyxml></code><documentation>Mark the angle (l1, l2) in the direction 'dir' given relatively to 'l1'.</documentation></function></asyxml>*/ // markangle(pic, L, n, radius, space, l1, l2, (pair)align, arrow, // p, filltype, margin, marker); // } -/*<asyxml><function type="void" signature="markangle(picture,Label,int,real,real,line,line,arrowbar,pen,filltype,margin,marker)"><code></asyxml>*/ -void markangle(picture pic=currentpicture, - Label L="", int n=1, real radius=0, real space=0, +/*<asyxml><function type = "void" signature = "markangle(picture, Label, int, real, real, line, line, arrowbar, pen, filltype, margin, marker)"><code></asyxml>*/ +void markangle(picture pic = currentpicture, + Label L = "", int n = 1, real radius = 0, real space = 0, line l1, line l2, - arrowbar arrow=None, pen p=currentpen, - filltype filltype=NoFill, - margin margin=NoMargin, marker marker=nomarker) -{/*<asyxml></code><documentation>Mark the oriented angle (l1,l2).</documentation></function></asyxml>*/ - if (parallel(l1,l2,true)) return; - real al=degrees(l1,defaultcoordsys); - pair O,A,B; - if (radius == 0) radius=markangleradius(p); - real d=degrees(locate(l1.u)); + arrowbar arrow = None, pen p = currentpen, + filltype filltype = NoFill, + margin margin = NoMargin, marker marker = nomarker) +{/*<asyxml></code><documentation>Mark the oriented angle (l1, l2).</documentation></function></asyxml>*/ + if (parallel(l1, l2, true)) return; + real al = degrees(l1, defaultcoordsys); + pair O, A, B; + if (radius == 0) radius = markangleradius(p); + real d = degrees(locate(l1.u)); if (l1 == l2) { - O=midpoint(segment(l1.A,l1.B)); + O = midpoint(segment(l1.A, l1.B)); } else { - O=intersectionpoint(extend(l1),extend(l2)); + O = intersectionpoint(extend(l1), extend(l2)); } - A=O+locate(l1.u); - B=O+locate(l2.u); - markangle(pic=pic,L=L,n=n,radius=radius,space=space, - O=O,A=A,B=B, - arrow=arrow,p=p,filltype=filltype, - margin=margin,marker=marker); -} - -/*<asyxml><function type="void" signature="perpendicularmark(picture,line,line,real,pen,int,margin,filltype)"><code></asyxml>*/ -void perpendicularmark(picture pic=currentpicture, line l1, line l2, - real size=0, pen p=currentpen, int quarter=1, - margin margin=NoMargin, filltype filltype=NoFill) + A = O + locate(l1.u); + B = O + locate(l2.u); + markangle(pic = pic, L = L, n = n, radius = radius, space = space, + O = O, A = A, B = B, + arrow = arrow, p = p, filltype = filltype, + margin = margin, marker = marker); +} + +/*<asyxml><function type = "void" signature = "perpendicularmark(picture, line, line, real, pen, int, margin, filltype)"><code></asyxml>*/ +void perpendicularmark(picture pic = currentpicture, line l1, line l2, + real size = 0, pen p = currentpen, int quarter = 1, + margin margin = NoMargin, filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw a right angle at the intersection point of lines and aligned in the 'quarter' nth quarter of circle formed by 'l1.u' and 'l2.u'.</documentation></function></asyxml>*/ - point P=intersectionpoint(l1,l2); - pair align=rotate(90*(quarter-1))*dir(45); - perpendicularmark(P,align,locate(l1.u),size,p,margin,filltype); + point P = intersectionpoint(l1, l2); + pair align = rotate(90 * (quarter - 1)) * dir(45); + perpendicularmark(P, align, locate(l1.u), size, p, margin, filltype); } // *.........................LINES.........................* // *=======================================================* // *=======================================================* // *........................CONICS.........................* -/*<asyxml><struct signature="bqe"><code></asyxml>*/ +/*<asyxml><struct signature = "bqe"><code></asyxml>*/ struct bqe {/*<asyxml></code><documentation>Bivariate Quadratic Equation.</documentation></asyxml>*/ - /*<asyxml><property type="real[]" signature="a"><code></asyxml>*/ - real[] a;/*<asyxml></code><documentation>a[0]*x^2 + a[1]*x*y + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0</documentation></property><property type="coordsys" signature="coordsys"><code></asyxml>*/ + /*<asyxml><property type = "real[]" signature = "a"><code></asyxml>*/ + real[] a;/*<asyxml></code><documentation>a[0] * x^2 + a[1] * x * y + a[2] * y^2 + a[3] * x + a[4] * y + a[5] = 0</documentation></property><property type = "coordsys" signature = "coordsys"><code></asyxml>*/ coordsys coordsys;/*<asyxml></code></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="bqe" signature="bqe(coordsys,real,real,real,real,real,real)"><code></asyxml>*/ -bqe bqe(coordsys R=currentcoordsys, +/*<asyxml><function type = "bqe" signature = "bqe(coordsys, real, real, real, real, real, real)"><code></asyxml>*/ +bqe bqe(coordsys R = currentcoordsys, real a, real b, real c, real d, real e, real f) {/*<asyxml></code><documentation>Return the bivariate quadratic equation - a[0]*x^2 + a[1]*x*y + a[2]*y^2 + a[3]*x + a[4]*y + a[5]=0 + a[0] * x^2 + a[1] * x * y + a[2] * y^2 + a[3] * x + a[4] * y + a[5] = 0 relatively to the coordinate system R.</documentation></function></asyxml>*/ bqe obqe; - obqe.coordsys=R; - obqe.a=new real[] {a,b,c,d,e,f}; + obqe.coordsys = R; + obqe.a = new real[] {a, b, c, d, e, f}; return obqe; } -/*<asyxml><function type="bqe" signature="changecoordsys(coordsys,bqe)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "changecoordsys(coordsys, bqe)"><code></asyxml>*/ bqe changecoordsys(coordsys R, bqe bqe) {/*<asyxml></code><documentation>Returns the bivariate quadratic equation relatively to 'R'.</documentation></function></asyxml>*/ - pair i=coordinates(changecoordsys(R,vector(defaultcoordsys, + pair i = coordinates(changecoordsys(R, vector(defaultcoordsys, bqe.coordsys.i))); - pair j=coordinates(changecoordsys(R,vector(defaultcoordsys, + pair j = coordinates(changecoordsys(R, vector(defaultcoordsys, bqe.coordsys.j))); - pair O=coordinates(changecoordsys(R,point(defaultcoordsys, + pair O = coordinates(changecoordsys(R, point(defaultcoordsys, bqe.coordsys.O))); - real a=bqe.a[0], b=bqe.a[1], c=bqe.a[2], d=bqe.a[3], f=bqe.a[4], g=bqe.a[5]; - real ux=i.x, uy=i.y; - real vx=j.x, vy=j.y; - real ox=O.x, oy=O.y; - real D=ux*vy-uy*vx; - real ap=(a*vy^2-b*uy*vy+c*uy^2)/D^2; - real bpp=(-2*a*vx*vy+b*ux*vy+b*uy*vx-2*c*ux*uy)/D^2; - real cp=(a*vx^2-b*ux*vx+c*ux^2)/D^2; - real dp=(-2a*ox*vy^2+2a*oy*vx*vy+2b*ox*uy*vy- - b*oy*ux*vy-b*oy*uy*vx-2c*ox*uy^2+2c*oy*uy*ux)/D^2+ - (d*vy-f*uy)/D; - real fp=(2a*ox*vx*vy-b*ox*ux*vy-2a*oy*vx^2- - b*ox*uy*vx+2*b*oy*ux*vx+2c*ox*ux*uy-2c*oy*ux^2)/D^2+ - (f*ux-d*vx)/D; - g=(a*ox^2*vy^2-2a*ox*oy*vx*vy-b*ox^2*uy*vy+b*ox*oy*ux*vy+ - a*oy^2*vx^2+b*ox*oy*uy*vx-b*oy^2*ux*vx+c*ox^2*uy^2- - 2*c*ox*oy*ux*uy+c*oy^2*ux^2)/D^2+ - (d*oy*vx+f*ox*uy-d*ox*vy-f*oy*ux)/D+g; + real a = bqe.a[0], b = bqe.a[1], c = bqe.a[2], d = bqe.a[3], f = bqe.a[4], g = bqe.a[5]; + real ux = i.x, uy = i.y; + real vx = j.x, vy = j.y; + real ox = O.x, oy = O.y; + real D = ux * vy - uy * vx; + real ap = (a * vy^2 - b * uy * vy + c * uy^2)/D^2; + real bpp = (-2 * a * vx * vy + b * ux * vy + b * uy * vx - 2 * c * ux * uy)/D^2; + real cp = (a * vx^2 - b * ux * vx + c * ux^2)/D^2; + real dp = (-2a * ox * vy^2 + 2a * oy * vx * vy + 2b * ox * uy * vy- + b * oy * ux * vy - b * oy * uy * vx - 2c * ox * uy^2 + 2c * oy * uy * ux)/D^2+ + (d * vy - f * uy)/D; + real fp = (2a * ox * vx * vy - b * ox * ux * vy - 2a * oy * vx^2- + b * ox * uy * vx + 2 * b * oy * ux * vx + 2c * ox * ux * uy - 2c * oy * ux^2)/D^2+ + (f * ux - d * vx)/D; + g = (a * ox^2 * vy^2 - 2a * ox * oy * vx * vy - b * ox^2 * uy * vy + b * ox * oy * ux * vy+ + a * oy^2 * vx^2 + b * ox * oy * uy * vx - b * oy^2 * ux * vx + c * ox^2 * uy^2- + 2 * c * ox * oy * ux * uy + c * oy^2 * ux^2)/D^2+ + (d * oy * vx + f * ox * uy - d * ox * vy - f * oy * ux)/D + g; bqe obqe; - obqe.a=approximate(new real[] {ap,bpp,cp,dp,fp,g}); - obqe.coordsys=R; + obqe.a = approximate(new real[] {ap, bpp, cp, dp, fp, g}); + obqe.coordsys = R; return obqe; } -/*<asyxml><function type="bqe" signature="bqe(point,point,point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "bqe(point, point, point, point, point)"><code></asyxml>*/ bqe bqe(point M1, point M2, point M3, point M4, point M5) {/*<asyxml></code><documentation>Return the bqe of conic passing through the five points (if possible).</documentation></function></asyxml>*/ coordsys R; pair[] pts; - if (samecoordsys(M1,M2,M3,M4,M5)) { - R=M1.coordsys; - pts= new pair[] {M1.coordinates,M2.coordinates,M3.coordinates,M4.coordinates,M5.coordinates}; + if (samecoordsys(M1, M2, M3, M4, M5)) { + R = M1.coordsys; + pts= new pair[] {M1.coordinates, M2.coordinates, M3.coordinates, M4.coordinates, M5.coordinates}; } else { - R=defaultcoordsys; - pts= new pair[] {M1,M2,M3,M4,M5}; + R = defaultcoordsys; + pts= new pair[] {M1, M2, M3, M4, M5}; } real[][] M; real[] x; bqe bqe; - bqe.coordsys=R; - for (int i=0; i < 5; ++i) {// Try a=-1 - M[i]=new real[] {pts[i].x*pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1}; - x[i]=pts[i].x^2; + bqe.coordsys = R; + for (int i = 0; i < 5; ++i) {// Try a = -1 + M[i] = new real[] {pts[i].x * pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1}; + x[i] = pts[i].x^2; } - if(abs(determinant(M)) < 1e-5) {// Try c=-1 - for (int i=0; i < 5; ++i) { - M[i]=new real[] {pts[i].x^2, pts[i].x*pts[i].y, pts[i].x, pts[i].y, 1}; - x[i]=pts[i].y^2; + if(abs(determinant(M)) < 1e-5) {// Try c = -1 + for (int i = 0; i < 5; ++i) { + M[i] = new real[] {pts[i].x^2, pts[i].x * pts[i].y, pts[i].x, pts[i].y, 1}; + x[i] = pts[i].y^2; } - real[] coef=solve(M,x); - bqe.a=new real[] {coef[0],coef[1],-1,coef[2],coef[3],coef[4]}; + real[] coef = solve(M, x); + bqe.a = new real[] {coef[0], coef[1], -1, coef[2], coef[3], coef[4]}; } else { - real[] coef=solve(M,x); - bqe.a=new real[] {-1,coef[0],coef[1],coef[2],coef[3],coef[4]}; + real[] coef = solve(M, x); + bqe.a = new real[] {-1, coef[0], coef[1], coef[2], coef[3], coef[4]}; } - bqe.a=approximate(bqe.a); + bqe.a = approximate(bqe.a); return bqe; } -/*<asyxml><function type="bool" signature="samecoordsys(bool...bqe[])"><code></asyxml>*/ -bool samecoordsys(bool warn=true ... bqe[] bqes) +/*<asyxml><function type = "bool" signature = "samecoordsys(bool...bqe[])"><code></asyxml>*/ +bool samecoordsys(bool warn = true ... bqe[] bqes) {/*<asyxml></code><documentation>Return true if all the bivariate quadratic equations have the same coordinate system.</documentation></function></asyxml>*/ - bool ret=true; - coordsys t=bqes[0].coordsys; - for (int i=1; i < bqes.length; ++i) { - ret=(t == bqes[i].coordsys); + bool ret = true; + coordsys t = bqes[0].coordsys; + for (int i = 1; i < bqes.length; ++i) { + ret = (t == bqes[i].coordsys); if(!ret) break; - t=bqes[i].coordsys; + t = bqes[i].coordsys; } if(warn && !ret) warning("coodinatesystem", @@ -2406,43 +2425,43 @@ system."); return ret; } -/*<asyxml><function type="real[]" signature="realquarticroots(real,real,real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "real[]" signature = "realquarticroots(real, real, real, real, real)"><code></asyxml>*/ real[] realquarticroots(real a, real b, real c, real d, real e) {/*<asyxml></code><documentation>Return the real roots of the quartic equation ax^4 + b^x3 + cx^2 + dx = 0.</documentation></function></asyxml>*/ - static real Fuzz=sqrt(realEpsilon); - pair[] zroots=quarticroots(a, b, c, d, e); + static real Fuzz = sqrt(realEpsilon); + pair[] zroots = quarticroots(a, b, c, d, e); real[] roots; - real p(real x){return a*x^4+b*x^3+c*x^2+d*x+e;} - real prime(real x){return 4*a*x^3+3*b*x^2+2*c*x+d;} + real p(real x){return a * x^4 + b * x^3 + c * x^2 + d * x + e;} + real prime(real x){return 4 * a * x^3 + 3 * b * x^2 + 2 * c * x + d;} real x; - bool search=true; + bool search = true; int n; void addroot(real x) { - bool exist=false; - for (int i=0; i < roots.length; ++i) { - if(abs(roots[i]-x) < 1e-5) {exist=true; break;} + bool exist = false; + for (int i = 0; i < roots.length; ++i) { + if(abs(roots[i]-x) < 1e-5) {exist = true; break;} } if(!exist) roots.push(x); } - for(int i=0; i < zroots.length; ++i) { + for(int i = 0; i < zroots.length; ++i) { if(zroots[i].y == 0 || abs(p(zroots[i].x)) < Fuzz) addroot(zroots[i].x); else { if(abs(zroots[i].y) < 1e-3) { - x=zroots[i].x; - search=true; - n=200; + x = zroots[i].x; + search = true; + n = 200; while(search) { - real tx=abs(p(x)) < Fuzz ? x : newton(iterations=n, p, prime, x); + real tx = abs(p(x)) < Fuzz ? x : newton(iterations = n, p, prime, x); if(tx < realMax) { if(abs(p(tx)) < Fuzz) { addroot(tx); - search=false; + search = false; } else if(n < 200) n *=2; else { - search=false; + search = false; } - } else search=false; //It's not a real root. + } else search = false; //It's not a real root. } } } @@ -2450,62 +2469,62 @@ real[] realquarticroots(real a, real b, real c, real d, real e) return roots; } -/*<asyxml><function type="point[]" signature="intersectionpoints(bqe,bqe)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(bqe, bqe)"><code></asyxml>*/ point[] intersectionpoints(bqe bqe1, bqe bqe2) {/*<asyxml></code><documentation>Return the interscetion of the two conic sections whose equations are 'bqe1' and 'bqe2'.</documentation></function></asyxml>*/ - coordsys R=bqe1.coordsys; - bqe lbqe1,lbqe2; + coordsys R = bqe1.coordsys; + bqe lbqe1, lbqe2; real[] a, b; if(R != bqe2.coordsys) { - R=currentcoordsys; - a=changecoordsys(R, bqe1).a; - b=changecoordsys(R, bqe2).a; + R = currentcoordsys; + a = changecoordsys(R, bqe1).a; + b = changecoordsys(R, bqe2).a; } else { - a=bqe1.a; - b=bqe2.a; + a = bqe1.a; + b = bqe2.a; } - static real e=100*sqrt(realEpsilon); - real[] x,y,c; + static real e = 100 * sqrt(realEpsilon); + real[] x, y, c; point[] P; if(abs(a[0]-b[0]) > e || abs(a[1]-b[1]) > e || abs(a[2]-b[2]) > e) { - c=new real[] {-2*a[0]*a[2]*b[0]*b[2]+a[0]*a[2]*b[1]^2-a[0]*a[1]*b[2]*b[1]+a[1]^2*b[0]*b[2]- - a[2]*a[1]*b[0]*b[1]+a[0]^2*b[2]^2+a[2]^2*b[0]^2, - -a[2]*a[1]*b[0]*b[4]-a[2]*a[4]*b[0]*b[1]-a[1]*a[3]*b[2]*b[1]+2*a[0]*a[2]*b[1]*b[4]- - a[0]*a[1]*b[2]*b[4]+a[1]^2*b[2]*b[3]-2*a[2]*a[3]*b[0]*b[2]-2*a[0]*a[2]*b[2]*b[3]+ - a[2]*a[3]*b[1]^2-a[2]*a[1]*b[1]*b[3]+2*a[1]*a[4]*b[0]*b[2]+2*a[2]^2*b[0]*b[3]- - a[0]*a[4]*b[2]*b[1]+2*a[0]*a[3]*b[2]^2, - -a[3]*a[4]*b[2]*b[1]+a[2]*a[5]*b[1]^2-a[1]*a[5]*b[2]*b[1]-a[1]*a[3]*b[2]*b[4]+ - a[1]^2*b[2]*b[5]-2*a[2]*a[3]*b[2]*b[3]+2*a[2]^2*b[0]*b[5]+2*a[0]*a[5]*b[2]^2+a[3]^2*b[2]^2- - 2*a[2]*a[5]*b[0]*b[2]+2*a[1]*a[4]*b[2]*b[3]-a[2]*a[4]*b[1]*b[3]-2*a[0]*a[2]*b[2]*b[5]+ - a[2]^2*b[3]^2+2*a[2]*a[3]*b[1]*b[4]-a[2]*a[4]*b[0]*b[4]+a[4]^2*b[0]*b[2]-a[2]*a[1]*b[3]*b[4]- + c = new real[] {-2 * a[0]*a[2]*b[0]*b[2]+a[0]*a[2]*b[1]^2 - a[0]*a[1]*b[2]*b[1]+a[1]^2 * b[0]*b[2]- + a[2]*a[1]*b[0]*b[1]+a[0]^2 * b[2]^2 + a[2]^2 * b[0]^2, + -a[2]*a[1]*b[0]*b[4]-a[2]*a[4]*b[0]*b[1]-a[1]*a[3]*b[2]*b[1]+2 * a[0]*a[2]*b[1]*b[4]- + a[0]*a[1]*b[2]*b[4]+a[1]^2 * b[2]*b[3]-2 * a[2]*a[3]*b[0]*b[2]-2 * a[0]*a[2]*b[2]*b[3]+ + a[2]*a[3]*b[1]^2 - a[2]*a[1]*b[1]*b[3]+2 * a[1]*a[4]*b[0]*b[2]+2 * a[2]^2 * b[0]*b[3]- + a[0]*a[4]*b[2]*b[1]+2 * a[0]*a[3]*b[2]^2, + -a[3]*a[4]*b[2]*b[1]+a[2]*a[5]*b[1]^2 - a[1]*a[5]*b[2]*b[1]-a[1]*a[3]*b[2]*b[4]+ + a[1]^2 * b[2]*b[5]-2 * a[2]*a[3]*b[2]*b[3]+2 * a[2]^2 * b[0]*b[5]+2 * a[0]*a[5]*b[2]^2 + a[3]^2 * b[2]^2- + 2 * a[2]*a[5]*b[0]*b[2]+2 * a[1]*a[4]*b[2]*b[3]-a[2]*a[4]*b[1]*b[3]-2 * a[0]*a[2]*b[2]*b[5]+ + a[2]^2 * b[3]^2 + 2 * a[2]*a[3]*b[1]*b[4]-a[2]*a[4]*b[0]*b[4]+a[4]^2 * b[0]*b[2]-a[2]*a[1]*b[3]*b[4]- a[2]*a[1]*b[1]*b[5]-a[0]*a[4]*b[2]*b[4]+a[0]*a[2]*b[4]^2, - -a[4]*a[5]*b[2]*b[1]+a[2]*a[3]*b[4]^2+2*a[3]*a[5]*b[2]^2-a[2]*a[1]*b[4]*b[5]- - a[2]*a[4]*b[3]*b[4]+2*a[2]^2*b[3]*b[5]-2*a[2]*a[3]*b[2]*b[5]-a[3]*a[4]*b[2]*b[4]- - 2*a[2]*a[5]*b[2]*b[3]-a[2]*a[4]*b[1]*b[5]+2*a[1]*a[4]*b[2]*b[5]-a[1]*a[5]*b[2]*b[4]+ - a[4]^2*b[2]*b[3]+2*a[2]*a[5]*b[1]*b[4], - -2*a[2]*a[5]*b[2]*b[5]+a[4]^2*b[2]*b[5]+a[5]^2*b[2]^2-a[4]*a[5]*b[2]*b[4]+a[2]*a[5]*b[4]^2+ - a[2]^2*b[5]^2-a[2]*a[4]*b[4]*b[5]}; - x=realquarticroots(c[0],c[1],c[2],c[3],c[4]); + -a[4]*a[5]*b[2]*b[1]+a[2]*a[3]*b[4]^2 + 2 * a[3]*a[5]*b[2]^2 - a[2]*a[1]*b[4]*b[5]- + a[2]*a[4]*b[3]*b[4]+2 * a[2]^2 * b[3]*b[5]-2 * a[2]*a[3]*b[2]*b[5]-a[3]*a[4]*b[2]*b[4]- + 2 * a[2]*a[5]*b[2]*b[3]-a[2]*a[4]*b[1]*b[5]+2 * a[1]*a[4]*b[2]*b[5]-a[1]*a[5]*b[2]*b[4]+ + a[4]^2 * b[2]*b[3]+2 * a[2]*a[5]*b[1]*b[4], + -2 * a[2]*a[5]*b[2]*b[5]+a[4]^2 * b[2]*b[5]+a[5]^2 * b[2]^2 - a[4]*a[5]*b[2]*b[4]+a[2]*a[5]*b[4]^2+ + a[2]^2 * b[5]^2 - a[2]*a[4]*b[4]*b[5]}; + x = realquarticroots(c[0], c[1], c[2], c[3], c[4]); } else { if(abs(b[4]-a[4]) > e){ - real D=(b[4]-a[4])^2; - c=new real[] {(a[0]*b[4]^2+(-a[1]*b[3]-2*a[0]*a[4]+a[1]*a[3])*b[4]+a[2]*b[3]^2+ - (a[1]*a[4]-2*a[2]*a[3])*b[3]+a[0]*a[4]^2-a[1]*a[3]*a[4]+a[2]*a[3]^2)/D, - -((a[1]*b[4]-2*a[2]*b[3]-a[1]*a[4]+2*a[2]*a[3])*b[5]-a[3]*b[4]^2+(a[4]*b[3]-a[1]*a[5]+a[3]*a[4])*b[4]+(2*a[2]*a[5]-a[4]^2)*b[3]+(a[1]*a[4]-2*a[2]*a[3])*a[5])/D, - a[2]*(a[5]-b[5])^2/D+a[4]*(a[5]-b[5])/(b[4]-a[4])+a[5]}; - x=quadraticroots(c[0],c[1],c[2]); + real D = (b[4]-a[4])^2; + c = new real[] {(a[0]*b[4]^2 + (-a[1]*b[3]-2 * a[0]*a[4]+a[1]*a[3]) * b[4]+a[2]*b[3]^2+ + (a[1]*a[4]-2 * a[2]*a[3]) * b[3]+a[0]*a[4]^2 - a[1]*a[3]*a[4]+a[2]*a[3]^2)/D, + -((a[1]*b[4]-2 * a[2]*b[3]-a[1]*a[4]+2 * a[2]*a[3]) * b[5]-a[3]*b[4]^2 + (a[4]*b[3]-a[1]*a[5]+a[3]*a[4]) * b[4]+(2 * a[2]*a[5]-a[4]^2) * b[3]+(a[1]*a[4]-2 * a[2]*a[3]) * a[5])/D, + a[2]*(a[5]-b[5])^2/D + a[4]*(a[5]-b[5])/(b[4]-a[4]) + a[5]}; + x = quadraticroots(c[0], c[1], c[2]); } else { if(abs(a[3]-b[3]) > e) { - real D=b[3]-a[3]; - c=new real[] {a[2], (-a[1]*b[5] + a[4]*b[3] + a[1]*a[5] - a[3]*a[4])/D, - a[0]*(a[5]-b[5])^2/D^2+a[3]*(a[5]-b[5])/D+a[5]}; - y=quadraticroots(c[0],c[1],c[2]); - for (int i=0; i < y.length; ++i) { - c=new real[] {a[0], a[1]*y[i]+a[3], a[2]*y[i]^2+a[4]*y[i]+a[5]}; - x=quadraticroots(c[0],c[1],c[2]); - for (int j=0; j < x.length; ++j) { - if(abs(b[0]*x[j]^2+b[1]*x[j]*y[i]+b[2]*y[i]^2+b[3]*x[j]+b[4]*y[i]+b[5]) < 1e-5) - P.push(point(R, (x[j],y[i]))); + real D = b[3]-a[3]; + c = new real[] {a[2], (-a[1]*b[5] + a[4]*b[3] + a[1]*a[5] - a[3]*a[4])/D, + a[0]*(a[5]-b[5])^2/D^2 + a[3]*(a[5]-b[5])/D + a[5]}; + y = quadraticroots(c[0], c[1], c[2]); + for (int i = 0; i < y.length; ++i) { + c = new real[] {a[0], a[1]*y[i]+a[3], a[2]*y[i]^2 + a[4]*y[i]+a[5]}; + x = quadraticroots(c[0], c[1], c[2]); + for (int j = 0; j < x.length; ++j) { + if(abs(b[0]*x[j]^2 + b[1]*x[j]*y[i]+b[2]*y[i]^2 + b[3]*x[j]+b[4]*y[i]+b[5]) < 1e-5) + P.push(point(R, (x[j], y[i]))); } } return P; @@ -2514,24 +2533,24 @@ point[] intersectionpoints(bqe bqe1, bqe bqe2) } } } - for (int i=0; i < x.length; ++i) { - c=new real[] {a[2], a[1]*x[i]+a[4], a[0]*x[i]^2+a[3]*x[i]+a[5]}; - y=quadraticroots(c[0],c[1],c[2]); - for (int j=0; j < y.length; ++j) { - if(abs(b[0]*x[i]^2+b[1]*x[i]*y[j]+b[2]*y[j]^2+b[3]*x[i]+b[4]*y[j]+b[5]) < 1e-5) - P.push(point(R, (x[i],y[j]))); + for (int i = 0; i < x.length; ++i) { + c = new real[] {a[2], a[1]*x[i]+a[4], a[0]*x[i]^2 + a[3]*x[i]+a[5]}; + y = quadraticroots(c[0], c[1], c[2]); + for (int j = 0; j < y.length; ++j) { + if(abs(b[0]*x[i]^2 + b[1]*x[i]*y[j]+b[2]*y[j]^2 + b[3]*x[i]+b[4]*y[j]+b[5]) < 1e-5) + P.push(point(R, (x[i], y[j]))); } } return P; } -/*<asyxml><struct signature="conic"><code></asyxml>*/ +/*<asyxml><struct signature = "conic"><code></asyxml>*/ struct conic -{/*<asyxml></code><documentation></documentation><property type="real" signature="e, p, h"><code></asyxml>*/ - real e, p, h;/*<asyxml></code><documentation>BE CAREFUL: h=distance(F,D) and p=h*e (http://en.wikipedia.org/wiki/Ellipse) - While http://mathworld.wolfram.com/ takes p=distance(F,D).</documentation></property><property type="point" signature="F"><code></asyxml>*/ - point F;/*<asyxml></code><documentation>Focus.</documentation></property><property type="line" signature="D"><code></asyxml>*/ - line D;/*<asyxml></code><documentation>Directrix.</documentation></property><property type="line" signature="l"><code></asyxml>*/ +{/*<asyxml></code><documentation></documentation><property type = "real" signature = "e, p, h"><code></asyxml>*/ + real e, p, h;/*<asyxml></code><documentation>BE CAREFUL: h = distance(F, D) and p = h * e (http://en.wikipedia.org/wiki/Ellipse) + While http://mathworld.wolfram.com/ takes p = distance(F, D).</documentation></property><property type = "point" signature = "F"><code></asyxml>*/ + point F;/*<asyxml></code><documentation>Focus.</documentation></property><property type = "line" signature = "D"><code></asyxml>*/ + line D;/*<asyxml></code><documentation>Directrix.</documentation></property><property type = "line" signature = "l"><code></asyxml>*/ line[] l;/*<asyxml></code><documentation>Case of degenerated conic (not yet implemented !).</documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ @@ -2540,7 +2559,7 @@ bool degenerate(conic c) return !finite(c.p) || !finite(c.h); } -/*ANCconic conic(point,line,real)ANC*/ +/*ANCconic conic(point, line, real)ANC*/ conic conic(point F, line l, real e) {/*DOC The conic section define by the eccentricity 'e', the focus 'F' @@ -2552,22 +2571,22 @@ conic conic(point F, line l, real e) DOC*/ if(e < 0) abort("conic: 'e' can't be negative."); conic oc; - point[] P=standardizecoordsys(F,l.A,l.B); + point[] P = standardizecoordsys(F, l.A, l.B); line ll; - ll=line(P[1],P[2]); - oc.e=e < epsgeo ? 0 : e; // Handle case of circle. - oc.F=P[0]; - oc.D=ll; - oc.h=distance(P[0],ll); - oc.p=abs(e) < epsgeo ? oc.h : e*oc.h; + ll = line(P[1], P[2]); + oc.e = e < epsgeo ? 0 : e; // Handle case of circle. + oc.F = P[0]; + oc.D = ll; + oc.h = distance(P[0], ll); + oc.p = abs(e) < epsgeo ? oc.h : e * oc.h; return oc; } -/*<asyxml><struct signature="circle"><code></asyxml>*/ +/*<asyxml><struct signature = "circle"><code></asyxml>*/ struct circle {/*<asyxml></code><documentation>All the calculus with this structure will be as exact as Asymptote can do. For a full precision, you must not cast 'circle' to 'path' excepted for drawing routines.</documentation></asyxml>*/ - /*<asyxml><property type="point" signature="C"><code></asyxml>*/ + /*<asyxml><property type = "point" signature = "C"><code></asyxml>*/ point C;/*<asyxml></code><documentation>Center</documentation></property><property><code></asyxml>*/ real r;/*<asyxml></code><documentation>Radius</documentation></property><property><code></asyxml>*/ line l;/*<asyxml></code><documentation>If the radius is infinite, this line is used instead of circle.</documentation></property></asyxml>*/ @@ -2583,39 +2602,39 @@ line line(circle c){ return c.l; } -/*<asyxml><struct signature="ellipse"><code></asyxml>*/ +/*<asyxml><struct signature = "ellipse"><code></asyxml>*/ struct ellipse -{/*<asyxml></code><documentation>Look at <html><a href="http://mathworld.wolfram.com/Ellipse.html">http://mathworld.wolfram.com/Ellipse.html</a></html></documentation></asyxml>*/ - /*<asyxml><property type="point" signature="F1,F2,C"><code></asyxml>*/ - restricted point F1, F2, C;/*<asyxml></code><documentation>Foci and center.</documentation></property><property type="real" signature="a, b, c, e, p"><code></asyxml>*/ - restricted real a, b, c, e, p;/*<asyxml></code></property><property type="real" signature="angle"><code></asyxml>*/ - restricted real angle;/*<asyxml></code><documentation>Value is degrees(F1-F2).</documentation></property><property type="line" signature="D1, D2"><code></asyxml>*/ - restricted line D1, D2;/*<asyxml></code><documentation>Directrices.</documentation></property><property type="line" signature="l"><code></asyxml>*/ +{/*<asyxml></code><documentation>Look at <html><a href = "http://mathworld.wolfram.com/Ellipse.html">http://mathworld.wolfram.com/Ellipse.html</a></html></documentation></asyxml>*/ + /*<asyxml><property type = "point" signature = "F1, F2, C"><code></asyxml>*/ + restricted point F1, F2, C;/*<asyxml></code><documentation>Foci and center.</documentation></property><property type = "real" signature = "a, b, c, e, p"><code></asyxml>*/ + restricted real a, b, c, e, p;/*<asyxml></code></property><property type = "real" signature = "angle"><code></asyxml>*/ + restricted real angle;/*<asyxml></code><documentation>Value is degrees(F1 - F2).</documentation></property><property type = "line" signature = "D1, D2"><code></asyxml>*/ + restricted line D1, D2;/*<asyxml></code><documentation>Directrices.</documentation></property><property type = "line" signature = "l"><code></asyxml>*/ line l;/*<asyxml></code><documentation>If one axis is infinite, this line is used instead of ellipse.</documentation></property></asyxml>*/ - /*<asyxml><method type="void" signature="init(point,point,real)"><code></asyxml>*/ + /*<asyxml><method type = "void" signature = "init(point, point, real)"><code></asyxml>*/ void init(point f1, point f2, real a) {/*<asyxml></code><documentation>Ellipse given by foci and semimajor axis</documentation></method></asyxml>*/ - point[] P=standardizecoordsys(f1,f2); - this.F1=P[0]; - this.F2=P[1]; - this.angle=abs(P[1]-P[0]) < 10*epsgeo ? 0 : degrees(P[1]-P[0]); - this.C=(P[0]+P[1])/2; - this.a=a; + point[] P = standardizecoordsys(f1, f2); + this.F1 = P[0]; + this.F2 = P[1]; + this.angle = abs(P[1]-P[0]) < 10 * epsgeo ? 0 : degrees(P[1]-P[0]); + this.C = (P[0] + P[1])/2; + this.a = a; if(!finite(a)) { - this.l=line(P[0],P[1]); - this.b=infinity; - this.e=0; - this.c=0; + this.l = line(P[0], P[1]); + this.b = infinity; + this.e = 0; + this.c = 0; } else { - this.c=abs(C-P[0]); - this.b=this.c < epsgeo ? a : sqrt(a^2-c^2); // Handle case of circle. - this.e=this.c < epsgeo ? 0 : this.c/a; // Handle case of circle. + this.c = abs(C - P[0]); + this.b = this.c < epsgeo ? a : sqrt(a^2 - c^2); // Handle case of circle. + this.e = this.c < epsgeo ? 0 : this.c/a; // Handle case of circle. if(this.e >= 1) abort("ellipse.init: wrong parameter: e >= 1."); - this.p=a*(1-this.e^2); + this.p = a * (1 - this.e^2); if (this.c != 0) {// directrix is not set for a circle. - point A=this.C+(a^2/this.c)*unit(P[0]-this.C); - this.D1=line(A,A+rotateO(90)*unit(A-this.C)); - this.D2=reverse(rotate(180,C)*D1); + point A = this.C + (a^2/this.c) * unit(P[0]-this.C); + this.D1 = line(A, A + rotateO(90) * unit(A - this.C)); + this.D2 = reverse(rotate(180, C) * D1); } } } @@ -2626,1244 +2645,1266 @@ bool degenerate(ellipse el) return (!finite(el.a) || !finite(el.b)); } -/*<asyxml><struct signature="parabola"><code></asyxml>*/ +/*<asyxml><struct signature = "parabola"><code></asyxml>*/ struct parabola -{/*<asyxml></code><documentation>Look at <html><a href="http://mathworld.wolfram.com/Parabola.html">http://mathworld.wolfram.com/Parabola.html</a></html></documentation><property type="point" signature="F, V"><code></asyxml>*/ - restricted point F, V;/*<asyxml></code><documentation>Focus and vertex</documentation></property><property type="real" signature="a, p, e=1"><code></asyxml>*/ - restricted real a, p, e=1;/*<asyxml></code></property><property type="real" signature="angle"><code></asyxml>*/ - restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (FV).</documentation></property><property type="line" signature="D"><code></asyxml>*/ - restricted line D;/*<asyxml></code><documentation>Directrix</documentation></property><property type="pair" signature="bmin, bmax"><code></asyxml>*/ - pair bmin, bmax;/*<asyxml></code><documentation>The (left,bottom) and (right,top) coordinates of region bounding box for drawing the parabola. +{/*<asyxml></code><documentation>Look at <html><a href = "http://mathworld.wolfram.com/Parabola.html">http://mathworld.wolfram.com/Parabola.html</a></html></documentation><property type = "point" signature = "F, V"><code></asyxml>*/ + restricted point F, V;/*<asyxml></code><documentation>Focus and vertex</documentation></property><property type = "real" signature = "a, p, e = 1"><code></asyxml>*/ + restricted real a, p, e = 1;/*<asyxml></code></property><property type = "real" signature = "angle"><code></asyxml>*/ + restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (FV).</documentation></property><property type = "line" signature = "D"><code></asyxml>*/ + restricted line D;/*<asyxml></code><documentation>Directrix</documentation></property><property type = "pair" signature = "bmin, bmax"><code></asyxml>*/ + pair bmin, bmax;/*<asyxml></code><documentation>The (left, bottom) and (right, top) coordinates of region bounding box for drawing the parabola. If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/ - /*<asyxml><method type="void" signature="init(point,line)"><code></asyxml>*/ + /*<asyxml><method type = "void" signature = "init(point, line)"><code></asyxml>*/ void init(point F, line directrix) {/*<asyxml></code><documentation>Parabola given by focus and directrix.</documentation></method></asyxml>*/ - point[] P=standardizecoordsys(F,directrix.A,directrix.B); - line l=line(P[1],P[2]); - this.F=P[0]; - this.D=l; - this.a=distance(P[0],l)/2; - this.p=2*a; - this.V=0.5*(F+projection(D)*P[0]); - this.angle=degrees(F-V); + point[] P = standardizecoordsys(F, directrix.A, directrix.B); + line l = line(P[1], P[2]); + this.F = P[0]; + this.D = l; + this.a = distance(P[0], l)/2; + this.p = 2 * a; + this.V = 0.5 * (F + projection(D) * P[0]); + this.angle = degrees(F - V); } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><struct signature="hyperbola"><code></asyxml>*/ +/*<asyxml><struct signature = "hyperbola"><code></asyxml>*/ struct hyperbola -{/*<asyxml></code><documentation><html>Look at <a href="http://mathworld.wolfram.com/Hyperbola.html">http://mathworld.wolfram.com/Hyperbola.html</a></html></documentation><property type="point" signature="F1, F2"><code></asyxml>*/ - restricted point F1, F2;/*<asyxml></code><documentation>Foci.</documentation></property><property type="point" signature="C, V1, V2"><code></asyxml>*/ - restricted point C, V1, V2;/*<asyxml></code><documentation>Center and vertices.</documentation></property><property type="real" signature="a, b, c, e, p"><code></asyxml>*/ - restricted real a, b, c, e, p;/*<asyxml></code><documentation></documentation></property><property type="real" signature="angle"><code></asyxml>*/ - restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (F1F2).</documentation></property><property type="line" signature="D1, D2, A1, A2"><code></asyxml>*/ - restricted line D1, D2, A1, A2;/*<asyxml></code><documentation>Directrices and asymptotes.</documentation></property><property type="pair" signature="bmin, bmax"><code></asyxml>*/ - pair bmin, bmax; /*<asyxml></code><documentation>The (left,bottom) and (right,top) coordinates of region bounding box for drawing the hyperbola. +{/*<asyxml></code><documentation><html>Look at <a href = "http://mathworld.wolfram.com/Hyperbola.html">http://mathworld.wolfram.com/Hyperbola.html</a></html></documentation><property type = "point" signature = "F1, F2"><code></asyxml>*/ + restricted point F1, F2;/*<asyxml></code><documentation>Foci.</documentation></property><property type = "point" signature = "C, V1, V2"><code></asyxml>*/ + restricted point C, V1, V2;/*<asyxml></code><documentation>Center and vertices.</documentation></property><property type = "real" signature = "a, b, c, e, p"><code></asyxml>*/ + restricted real a, b, c, e, p;/*<asyxml></code><documentation></documentation></property><property type = "real" signature = "angle"><code></asyxml>*/ + restricted real angle;/*<asyxml></code><documentation>Angle, in degrees, of the line (F1F2).</documentation></property><property type = "line" signature = "D1, D2, A1, A2"><code></asyxml>*/ + restricted line D1, D2, A1, A2;/*<asyxml></code><documentation>Directrices and asymptotes.</documentation></property><property type = "pair" signature = "bmin, bmax"><code></asyxml>*/ + pair bmin, bmax; /*<asyxml></code><documentation>The (left, bottom) and (right, top) coordinates of region bounding box for drawing the hyperbola. If unset the current picture bounding box is used instead.</documentation></property></asyxml>*/ - /*<asyxml><method type="void" signature="init(point,point,real)"><code></asyxml>*/ + /*<asyxml><method type = "void" signature = "init(point, point, real)"><code></asyxml>*/ void init(point f1, point f2, real a) {/*<asyxml></code><documentation>Hyperbola given by foci and semimajor axis.</documentation></method></asyxml>*/ - point[] P=standardizecoordsys(f1,f2); - this.F1=P[0]; - this.F2=P[1]; - this.angle=degrees(F2-F1); - this.a=a; - this.C=(P[0]+P[1])/2; - this.c=abs(C-P[0]); - this.e=this.c/a; + point[] P = standardizecoordsys(f1, f2); + this.F1 = P[0]; + this.F2 = P[1]; + this.angle = degrees(F2 - F1); + this.a = a; + this.C = (P[0] + P[1])/2; + this.c = abs(C - P[0]); + this.e = this.c/a; if(this.e <= 1) abort("hyperbola.init: wrong parameter: e <= 1."); - this.b=a*sqrt(this.e^2-1); - this.p=a*(this.e^2-1); - point A=this.C+(a^2/this.c)*unit(P[0]-this.C); - this.D1=line(A,A+rotateO(90)*unit(A-this.C)); - this.D2=reverse(rotate(180,C)*D1); - this.V1=C+a*unit(F1-C); - this.V2=C+a*unit(F2-C); - this.A1=line(C,V1+b*unit(rotateO(-90)*(C-V1))); - this.A2=line(C,V1+b*unit(rotateO(90)*(C-V1))); + this.b = a * sqrt(this.e^2 - 1); + this.p = a * (this.e^2 - 1); + point A = this.C + (a^2/this.c) * unit(P[0]-this.C); + this.D1 = line(A, A + rotateO(90) * unit(A - this.C)); + this.D2 = reverse(rotate(180, C) * D1); + this.V1 = C + a * unit(F1 - C); + this.V2 = C + a * unit(F2 - C); + this.A1 = line(C, V1 + b * unit(rotateO(-90) * (C - V1))); + this.A2 = line(C, V1 + b * unit(rotateO(90) * (C - V1))); } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><variable type="int" signature="conicnodesfactor"><code></asyxml>*/ -int conicnodesfactor=1;/*<asyxml></code><documentation>Factor for the node number of all conics.</documentation></variable></asyxml>*/ +/*<asyxml><variable type = "int" signature = "conicnodesfactor"><code></asyxml>*/ +int conicnodesfactor = 1;/*<asyxml></code><documentation>Factor for the node number of all conics.</documentation></variable></asyxml>*/ -/*<asyxml><variable type="int" signature="circlenodesnumberfactor"><code></asyxml>*/ -int circlenodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the node number of circles.</documentation></variable></asyxml>*/ -/*<asyxml><function type="int" signature="circlenodesnumber(real)"><code></asyxml>*/ +/*<asyxml><variable type = "int" signature = "circlenodesnumberfactor"><code></asyxml>*/ +int circlenodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the node number of circles.</documentation></variable></asyxml>*/ +/*<asyxml><function type = "int" signature = "circlenodesnumber(real)"><code></asyxml>*/ int circlenodesnumber(real r) {/*<asyxml></code><documentation>Return the number of nodes for drawing a circle of radius 'r'.</documentation></function></asyxml>*/ if (circlenodesnumberfactor < 100) warning("circlenodesnumberfactor", "variable 'circlenodesnumberfactor' may be too small."); - int oi=ceil(circlenodesnumberfactor*abs(r)^0.1); - oi=45*floor(oi/45); - return oi == 0 ? 4 : conicnodesfactor*oi; + int oi = ceil(circlenodesnumberfactor * abs(r)^0.1); + oi = 45 * floor(oi/45); + return oi == 0 ? 4 : conicnodesfactor * oi; } -/*<asyxml><function type="int" signature="circlenodesnumber(real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "int" signature = "circlenodesnumber(real, real, real)"><code></asyxml>*/ int circlenodesnumber(real r, real angle1, real angle2) {/*<asyxml></code><documentation>Return the number of nodes to draw a circle arc.</documentation></function></asyxml>*/ return (r > 0) ? - ceil(circlenodesnumber(r)*abs(angle1-angle2)/360) : - ceil(circlenodesnumber(r)*abs((1-abs(angle1-angle2)/360))); + ceil(circlenodesnumber(r) * abs(angle1 - angle2)/360) : + ceil(circlenodesnumber(r) * abs((1 - abs(angle1 - angle2)/360))); } -/*<asyxml><variable type="int" signature="ellispenodesnumberfactor"><code></asyxml>*/ -int ellipsenodesnumberfactor=250;/*<asyxml></code><documentation>Factor for the node number of ellispe (non-circle).</documentation></variable></asyxml>*/ -/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real)"><code></asyxml>*/ +/*<asyxml><variable type = "int" signature = "ellispenodesnumberfactor"><code></asyxml>*/ +int ellipsenodesnumberfactor = 250;/*<asyxml></code><documentation>Factor for the node number of ellispe (non-circle).</documentation></variable></asyxml>*/ +/*<asyxml><function type = "int" signature = "ellipsenodesnumber(real, real)"><code></asyxml>*/ int ellipsenodesnumber(real a, real b) {/*<asyxml></code><documentation>Return the number of nodes to draw a ellipse of axis 'a' and 'b'.</documentation></function></asyxml>*/ if (ellipsenodesnumberfactor < 250) write("ellipsenodesnumberfactor", "variable 'ellipsenodesnumberfactor' maybe too small."); - int tmp=circlenodesnumberfactor; - circlenodesnumberfactor=ellipsenodesnumberfactor; - int oi=circlenodesnumber(max(abs(a),abs(b))/min(abs(a),abs(b))); - circlenodesnumberfactor=tmp; - return conicnodesfactor*oi; + int tmp = circlenodesnumberfactor; + circlenodesnumberfactor = ellipsenodesnumberfactor; + int oi = circlenodesnumber(max(abs(a), abs(b))/min(abs(a), abs(b))); + circlenodesnumberfactor = tmp; + return conicnodesfactor * oi; } -/*<asyxml><function type="int" signature="ellipsenodesnumber(real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "int" signature = "ellipsenodesnumber(real, real, real)"><code></asyxml>*/ int ellipsenodesnumber(real a, real b, real angle1, real angle2, bool dir) {/*<asyxml></code><documentation>Return the number of nodes to draw an ellipse arc.</documentation></function></asyxml>*/ real d; - real da=angle2-angle1; + real da = angle2 - angle1; if(dir) { - d=angle1 < angle2 ? da : 360+da; + d = angle1 < angle2 ? da : 360 + da; } else { - d=angle1 < angle2 ? -360+da : da; + d = angle1 < angle2 ? -360 + da : da; } - int n=floor(ellipsenodesnumber(a,b)*abs(d)/360); + int n = floor(ellipsenodesnumber(a, b) * abs(d)/360); return n < 5 ? 5 : n; } -/*<asyxml><variable type="int" signature="parabolanodesnumberfactor"><code></asyxml>*/ -int parabolanodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the number of nodes of parabolas.</documentation></variable></asyxml>*/ -/*<asyxml><function type="int" signature="parabolanodesnumber(parabola,real,real)"><code></asyxml>*/ +/*<asyxml><variable type = "int" signature = "parabolanodesnumberfactor"><code></asyxml>*/ +int parabolanodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the number of nodes of parabolas.</documentation></variable></asyxml>*/ +/*<asyxml><function type = "int" signature = "parabolanodesnumber(parabola, real, real)"><code></asyxml>*/ int parabolanodesnumber(parabola p, real angle1, real angle2) {/*<asyxml></code><documentation>Return the number of nodes for drawing a parabola.</documentation></function></asyxml>*/ - return conicnodesfactor*floor(0.01*parabolanodesnumberfactor*abs(angle1-angle2)); + return conicnodesfactor * floor(0.01 * parabolanodesnumberfactor * abs(angle1 - angle2)); } -/*<asyxml><variable type="int" signature="hyperbolanodesnumberfactor"><code></asyxml>*/ -int hyperbolanodesnumberfactor=100;/*<asyxml></code><documentation>Factor for the number of nodes of hyperbolas.</documentation></variable></asyxml>*/ -/*<asyxml><function type="int" signature="hyperbolanodesnumber(hyperbola,real,real)"><code></asyxml>*/ +/*<asyxml><variable type = "int" signature = "hyperbolanodesnumberfactor"><code></asyxml>*/ +int hyperbolanodesnumberfactor = 100;/*<asyxml></code><documentation>Factor for the number of nodes of hyperbolas.</documentation></variable></asyxml>*/ +/*<asyxml><function type = "int" signature = "hyperbolanodesnumber(hyperbola, real, real)"><code></asyxml>*/ int hyperbolanodesnumber(hyperbola h, real angle1, real angle2) {/*<asyxml></code><documentation>Return the number of nodes for drawing an hyperbola.</documentation></function></asyxml>*/ - return conicnodesfactor*floor(0.01*hyperbolanodesnumberfactor*abs(angle1-angle2)/h.e); + return conicnodesfactor * floor(0.01 * hyperbolanodesnumberfactor * abs(angle1 - angle2)/h.e); } -/*<asyxml><operator type="conic" signature="+(conic,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "+(conic, explicit point)"><code></asyxml>*/ conic operator +(conic c, explicit point M) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return conic(c.F+M,c.D+M,c.e); + return conic(c.F + M, c.D + M, c.e); } -/*<asyxml><operator type="conic" signature="-(conic,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "-(conic, explicit point)"><code></asyxml>*/ conic operator -(conic c, explicit point M) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return conic(c.F-M,c.D-M,c.e); + return conic(c.F - M, c.D - M, c.e); } -/*<asyxml><operator type="conic" signature="+(conic,explicit pair)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "+(conic, explicit pair)"><code></asyxml>*/ conic operator +(conic c, explicit pair m) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - point M=point(c.F.coordsys,m); - return conic(c.F+M,c.D+M,c.e); + point M = point(c.F.coordsys, m); + return conic(c.F + M, c.D + M, c.e); } -/*<asyxml><operator type="conic" signature="-(conic,explicit pair)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "-(conic, explicit pair)"><code></asyxml>*/ conic operator -(conic c, explicit pair m) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - point M=point(c.F.coordsys,m); - return conic(c.F-M,c.D-M,c.e); + point M = point(c.F.coordsys, m); + return conic(c.F - M, c.D - M, c.e); } -/*<asyxml><operator type="conic" signature="+(conic,vector)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "+(conic, vector)"><code></asyxml>*/ conic operator +(conic c, vector v) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return conic(c.F+v,c.D+v,c.e); + return conic(c.F + v, c.D + v, c.e); } -/*<asyxml><operator type="conic" signature="-(conic,vector)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "-(conic, vector)"><code></asyxml>*/ conic operator -(conic c, vector v) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return conic(c.F-v,c.D-v,c.e); + return conic(c.F - v, c.D - v, c.e); } -/*<asyxml><function type="coordsys" signature="coordsys(conic)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "coordsys(conic)"><code></asyxml>*/ coordsys coordsys(conic co) {/*<asyxml></code><documentation>Return the coordinate system of 'co'.</documentation></function></asyxml>*/ return co.F.coordsys; } -/*<asyxml><function type="conic" signature="changecoordsys(coordsys,conic)"><code></asyxml>*/ +/*<asyxml><function type = "conic" signature = "changecoordsys(coordsys, conic)"><code></asyxml>*/ conic changecoordsys(coordsys R, conic co) {/*<asyxml></code><documentation>Change the coordinate system of 'co' to 'R'</documentation></function></asyxml>*/ - line l=changecoordsys(R,co.D); - point F=changecoordsys(R,co.F); - return conic(F,l,co.e); + line l = changecoordsys(R, co.D); + point F = changecoordsys(R, co.F); + return conic(F, l, co.e); } -/*<asyxml><typedef type="polarconicroutine" return="path" params="conic,real,real,int,bool"><code></asyxml>*/ +/*<asyxml><typedef type = "polarconicroutine" return = "path" params = "conic, real, real, int, bool"><code></asyxml>*/ typedef path polarconicroutine(conic co, real angle1, real angle2, int n, bool direction);/*<asyxml></code><documentation>Routine type used to draw conics from 'angle1' to 'angle2'</documentation></typedef></asyxml>*/ -/*<asyxml><function type="path" signature="arcfromfocus(conic,real,real,int,bool)"><code></asyxml>*/ -path arcfromfocus(conic co, real angle1, real angle2, int n=400, bool direction=CCW) +/*<asyxml><function type = "path" signature = "arcfromfocus(conic, real, real, int, bool)"><code></asyxml>*/ +path arcfromfocus(conic co, real angle1, real angle2, int n = 400, bool direction = CCW) {/*<asyxml></code><documentation>Return the path of the conic section 'co' from angle1 to angle2 in degrees, drawing in the given direction, with n nodes.</documentation></function></asyxml>*/ guide op; if (n < 1) return op; if (angle1 > angle2) { - path g=arcfromfocus(co,angle2,angle1,n,!direction); + path g = arcfromfocus(co, angle2, angle1, n, !direction); return g == nullpath ? g : reverse(g); } - point O=projection(co.D)*co.F; - pair i=unit(locate(co.F)-locate(O)); - pair j=rotate(90)*i; - coordsys Rp=cartesiansystem(co.F,i,j); - real a1=direction ? radians(angle1) : radians(angle2); - real a2=direction ? radians(angle2) : radians(angle1)+2*pi; - real step=n == 1 ? 0 : (a2-a1)/(n-1); - real a,r; - for (int i=0; i < n; ++i) { - a=a1+i*step; + point O = projection(co.D) * co.F; + pair i = unit(locate(co.F) - locate(O)); + pair j = rotate(90) * i; + coordsys Rp = cartesiansystem(co.F, i, j); + real a1 = direction ? radians(angle1) : radians(angle2); + real a2 = direction ? radians(angle2) : radians(angle1) + 2 * pi; + real step = n == 1 ? 0 : (a2 - a1)/(n - 1); + real a, r; + for (int i = 0; i < n; ++i) { + a = a1 + i * step; if(co.e >= 1) { - r=1-co.e*cos(a); + r = 1 - co.e * cos(a); if(r > epsgeo) { - r=co.p/r; - op=op--Rp*Rp.polar(r,a); + r = co.p/r; + op = op--Rp * Rp.polar(r, a); } } else { - r=co.p/(1-co.e*cos(a)); - op=op..Rp*Rp.polar(r,a); + r = co.p/(1 - co.e * cos(a)); + op = op..Rp * Rp.polar(r, a); } } - if(co.e < 1 && abs(abs(a2-a1)-2*pi) < epsgeo) op=(path)op..cycle; + if(co.e < 1 && abs(abs(a2 - a1) - 2 * pi) < epsgeo) op = (path)op..cycle; return (direction ? op : op == nullpath ? op :reverse(op)); } -/*<asyxml><variable type="polarconicroutine" signature="currentpolarconicroutine"><code></asyxml>*/ -polarconicroutine currentpolarconicroutine=arcfromfocus;/*<asyxml></code><documentation>Default routine used to cast conic section to path.</documentation></variable></asyxml>*/ +/*<asyxml><variable type = "polarconicroutine" signature = "currentpolarconicroutine"><code></asyxml>*/ +polarconicroutine currentpolarconicroutine = arcfromfocus;/*<asyxml></code><documentation>Default routine used to cast conic section to path.</documentation></variable></asyxml>*/ -/*<asyxml><function type="point" signature="angpoint(conic,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(conic, real)"><code></asyxml>*/ point angpoint(conic co, real angle) {/*<asyxml></code><documentation>Return the point of 'co' whose the angular (in degrees) coordinate is 'angle' (mesured from the focus of 'co', relatively to its 'natural coordinate system').</documentation></function></asyxml>*/ - coordsys R=coordsys(co); - return point(R,point(arcfromfocus(co,angle,angle,1,CCW),0)/R); + coordsys R = coordsys(co); + return point(R, point(arcfromfocus(co, angle, angle, 1, CCW), 0)/R); } -/*<asyxml><operator type="bool" signature="@(point,conic)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "@(point, conic)"><code></asyxml>*/ bool operator @(point M, conic co) {/*<asyxml></code><documentation>Return true iff 'M' on 'co'.</documentation></operator></asyxml>*/ - if(co.e == 0) return abs(abs(co.F-M)-co.p) < 10*epsgeo; - return abs(co.e*distance(M,co.D)-abs(co.F-M)) < 10*epsgeo; + if(co.e == 0) return abs(abs(co.F - M) - co.p) < 10 * epsgeo; + return abs(co.e * distance(M, co.D) - abs(co.F - M)) < 10 * epsgeo; } -/*<asyxml><function type="coordsys" signature="coordsys(ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "coordsys(ellipse)"><code></asyxml>*/ coordsys coordsys(ellipse el) {/*<asyxml></code><documentation>Return the coordinate system of 'el'.</documentation></function></asyxml>*/ return el.F1.coordsys; } -/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "canonicalcartesiansystem(ellipse)"><code></asyxml>*/ coordsys canonicalcartesiansystem(ellipse el) {/*<asyxml></code><documentation>Return the canonical cartesian system of the ellipse 'el'.</documentation></function></asyxml>*/ - if(degenerate(el)) return cartesiansystem(el.l.A,el.l.u,el.l.v); - pair O=locate(el.C); - pair i=el.e == 0 ? el.C.coordsys.i : unit(locate(el.F1)-O); - pair j=rotate(90)*i; - return cartesiansystem(O,i,j); + if(degenerate(el)) return cartesiansystem(el.l.A, el.l.u, el.l.v); + pair O = locate(el.C); + pair i = el.e == 0 ? el.C.coordsys.i : unit(locate(el.F1) - O); + pair j = rotate(90) * i; + return cartesiansystem(O, i, j); } -/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(parabola)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "canonicalcartesiansystem(parabola)"><code></asyxml>*/ coordsys canonicalcartesiansystem(parabola p) {/*<asyxml></code><documentation>Return the canonical cartesian system of a parabola, - so that Origin = vertex of 'p' and directrix: x=-a.</documentation></function></asyxml>*/ - point A=projection(p.D)*p.F; - pair O=locate((A+p.F)/2); - pair i=unit(locate(p.F)-O); - pair j=rotate(90)*i; - return cartesiansystem(O,i,j); + so that Origin = vertex of 'p' and directrix: x = -a.</documentation></function></asyxml>*/ + point A = projection(p.D) * p.F; + pair O = locate((A + p.F)/2); + pair i = unit(locate(p.F) - O); + pair j = rotate(90) * i; + return cartesiansystem(O, i, j); } -/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "canonicalcartesiansystem(hyperbola)"><code></asyxml>*/ coordsys canonicalcartesiansystem(hyperbola h) {/*<asyxml></code><documentation>Return the canonical cartesian system of an hyperbola.</documentation></function></asyxml>*/ - pair O=locate(h.C); - pair i=unit(locate(h.F2)-O); - pair j=rotate(90)*i; - return cartesiansystem(O,i,j); + pair O = locate(h.C); + pair i = unit(locate(h.F2) - O); + pair j = rotate(90) * i; + return cartesiansystem(O, i, j); } -/*<asyxml><function type="ellipse" signature="ellipse(point,point,real)"><code></asyxml>*/ +/*<asyxml><function type = "ellipse" signature = "ellipse(point, point, real)"><code></asyxml>*/ ellipse ellipse(point F1, point F2, real a) {/*<asyxml></code><documentation>Return the ellipse whose the foci are 'F1' and 'F2' and the semimajor axis is 'a'.</documentation></function></asyxml>*/ ellipse oe; - oe.init(F1,F2,a); + oe.init(F1, F2, a); return oe; } -/*<asyxml><constant type="bool" signature="byfoci, byvertices"><code></asyxml>*/ -restricted bool byfoci=true, byvertices=false;/*<asyxml></code><documentation>Constants useful for the routine 'hyperbola(point P1, point P2, real ae, bool byfoci=byfoci)'</documentation></constant></asyxml>*/ +/*<asyxml><constant type = "bool" signature = "byfoci, byvertices"><code></asyxml>*/ +restricted bool byfoci = true, byvertices = false;/*<asyxml></code><documentation>Constants useful for the routine 'hyperbola(point P1, point P2, real ae, bool byfoci = byfoci)'</documentation></constant></asyxml>*/ -/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,real,bool)"><code></asyxml>*/ -hyperbola hyperbola(point P1, point P2, real ae, bool byfoci=byfoci) -{/*<asyxml></code><documentation>if 'byfoci=true': +/*<asyxml><function type = "hyperbola" signature = "hyperbola(point, point, real, bool)"><code></asyxml>*/ +hyperbola hyperbola(point P1, point P2, real ae, bool byfoci = byfoci) +{/*<asyxml></code><documentation>if 'byfoci = true': return the hyperbola whose the foci are 'P1' and 'P2' and the semimajor axis is 'ae'. else return the hyperbola whose vertexes are 'P1' and 'P2' with eccentricity 'ae'.</documentation></function></asyxml>*/ hyperbola oh; - point[] P=standardizecoordsys(P1,P2); + point[] P = standardizecoordsys(P1, P2); if(byfoci) { - oh.init(P[0],P[1],ae); + oh.init(P[0], P[1], ae); } else { - real a=abs(P[0]-P[1])/2; - vector V=unit(P[0]-P[1]); - point F1=P[0]+a*(ae-1)*V; - point F2=P[1]-a*(ae-1)*V; - oh.init(F1,F2,a); + real a = abs(P[0]-P[1])/2; + vector V = unit(P[0]-P[1]); + point F1 = P[0] + a * (ae - 1) * V; + point F2 = P[1]-a * (ae - 1) * V; + oh.init(F1, F2, a); } return oh; } -/*<asyxml><function type="ellipse" signature="ellipse(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "ellipse" signature = "ellipse(point, point, point)"><code></asyxml>*/ ellipse ellipse(point F1, point F2, point M) {/*<asyxml></code><documentation>Return the ellipse passing through 'M' whose the foci are 'F1' and 'F2'.</documentation></function></asyxml>*/ - point P[]=standardizecoordsys(false,F1,F2,M); - real a=abs(F1-M)+abs(F2-M); - return ellipse(F1,F2,finite(a) ? a/2 : a); + point P[] = standardizecoordsys(false, F1, F2, M); + real a = abs(F1 - M) + abs(F2 - M); + return ellipse(F1, F2, finite(a) ? a/2 : a); } -/*<asyxml><function type="ellipse" signature="ellipse(point,real,real,real)"><code></asyxml>*/ -ellipse ellipse(point C, real a, real b, real angle=0) -{/*<asyxml></code><documentation>Return the ellipse centered at 'C' with semimajor axis 'a' along C--C+dir(angle), +/*<asyxml><function type = "ellipse" signature = "ellipse(point, real, real, real)"><code></asyxml>*/ +ellipse ellipse(point C, real a, real b, real angle = 0) +{/*<asyxml></code><documentation>Return the ellipse centered at 'C' with semimajor axis 'a' along C--C + dir(angle), semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/ ellipse oe; - coordsys R=C.coordsys; - angle+=degrees(R.i); - if(a < b) {angle += 90; real tmp=a; a=b; b=tmp;} + coordsys R = C.coordsys; + angle += degrees(R.i); + if(a < b) {angle += 90; real tmp = a; a = b; b = tmp;} if(finite(a) && finite(b)) { - real c=sqrt(abs(a^2-b^2)); + real c = sqrt(abs(a^2 - b^2)); point f1, f2; - if(abs(a-b) < epsgeo) { - f1=C; f2=C; + if(abs(a - b) < epsgeo) { + f1 = C; f2 = C; } else { - f1=point(R,(locate(C)+rotate(angle)*(-c,0))/R); - f2=point(R,(locate(C)+rotate(angle)*(c,0))/R); + f1 = point(R, (locate(C) + rotate(angle) * (-c, 0))/R); + f2 = point(R, (locate(C) + rotate(angle) * (c, 0))/R); } - oe.init(f1,f2,a); + oe.init(f1, f2, a); } else { - if(finite(b) || !finite(a)) oe.init(C,C+R.polar(1,angle),infinity); - else oe.init(C,C+R.polar(1,90+angle),infinity); + if(finite(b) || !finite(a)) oe.init(C, C + R.polar(1, angle), infinity); + else oe.init(C, C + R.polar(1, 90 + angle), infinity); } return oe; } -/*<asyxml><function type="ellipse" signature="ellipse(bqe)"><code></asyxml>*/ +/*<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 - given in the coordinate system of 'bqe' with a[i]=bque.a[i]. - <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/> - <url href="http://mathworld.wolfram.com/Ellipse.html"/>.</documentation></function></asyxml>*/ - bqe lbqe=changecoordsys(defaultcoordsys,bqe); - real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5]; - coordsys R=bqe.coordsys; - string message="ellipse: the given equation is not an equation of an ellipse."; - real u=b^2*g + d^2*c + f^2*a; - real delta=a*c*g + b*f*d + d*b*f - u; +{/*<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 + given in the coordinate system of 'bqe' with a[i] = bque.a[i]. + <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/> + <url href = "http://mathworld.wolfram.com/Ellipse.html"/>.</documentation></function></asyxml>*/ + bqe lbqe = changecoordsys(defaultcoordsys, bqe); + real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5]; + coordsys R = bqe.coordsys; + string message = "ellipse: the given equation is not an equation of an ellipse."; + real u = b^2 * g + d^2 * c + f^2 * a; + real delta = a * c * g + b * f * d + d * b * f - u; if(abs(delta) < epsgeo) abort(message); - real j=b^2-a*c; - real i=a+c; - real dd=j*(sgnd(c-a)*sqrt((a-c)^2+4*(b^2))-c-a); - real ddd=j*(-sgnd(c-a)*sqrt((a-c)^2+4*(b^2))-c-a); + real j = b^2 - a * c; + real i = a + c; + real dd = j * (sgnd(c - a) * sqrt((a - c)^2 + 4 * (b^2)) - c-a); + real ddd = j * (-sgnd(c - a) * sqrt((a - c)^2 + 4 * (b^2)) - c-a); if(abs(ddd) < epsgeo || abs(dd) < epsgeo || j >= -epsgeo || delta/sgnd(i) > 0) abort(message); - real x=(c*d-b*f)/j, y=(a*f-b*d)/j; - // real dir=abs(b) < epsgeo ? 0 : pi/2-0.5*acot(0.5*(c-a)/b); - real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b); - if(dir*(c-a)*b < 0) dir=dir < 0 ? dir+pi/2 : dir-pi/2; - real cd=cos(dir), sd=sin(dir); - real t=a*cd^2-2*b*cd*sd+c*sd^2; - real tt=a*sd^2+2*b*cd*sd+c*cd^2; - real gg=-g+((d*cd-f*sd)^2)/t+((d*sd+f*cd)^2)/tt; - t=t/gg; tt=tt/gg; - // The equation of the ellipse is t*(x-center.x)^2+tt*(y-center.y)^2=1; + real x = (c * d - b * f)/j, y = (a * f - b * d)/j; + // real dir = abs(b) < epsgeo ? 0 : pi/2-0.5 * acot(0.5 * (c-a)/b); + real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b); + if(dir * (c - a) * b < 0) dir = dir < 0 ? dir + pi/2 : dir - pi/2; + real cd = cos(dir), sd = sin(dir); + real t = a * cd^2 - 2 * b * cd * sd + c * sd^2; + real tt = a * sd^2 + 2 * b * cd * sd + c * cd^2; + real gg = -g + ((d * cd - f * sd)^2)/t + ((d * sd + f * cd)^2)/tt; + t = t/gg; tt = tt/gg; + // The equation of the ellipse is t * (x - center.x)^2 + tt * (y - center.y)^2 = 1; real aa, bb; - aa=sqrt(2*(u-2*b*d*f-a*c*g)/dd); - bb=sqrt(2*(u-2*b*d*f-a*c*g)/ddd); - a=t > tt ? max(aa,bb) : min(aa,bb); - b=t > tt ? min(aa,bb) : max(aa,bb); - return ellipse(point(R,(x,y)/R), - a,b,degrees(pi/2-dir-angle(R.i))); + aa = sqrt(2 * (u - 2 * b * d * f - a * c * g)/dd); + bb = sqrt(2 * (u - 2 * b * d * f - a * c * g)/ddd); + a = t > tt ? max(aa, bb) : min(aa, bb); + b = t > tt ? min(aa, bb) : max(aa, bb); + return ellipse(point(R, (x, y)/R), + a, b, degrees(pi/2 - dir - angle(R.i))); } -/*<asyxml><function type="ellipse" signature="ellipse(point,point,point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "ellipse" signature = "ellipse(point, point, point, point, point)"><code></asyxml>*/ ellipse ellipse(point M1, point M2, point M3, point M4, point M5) {/*<asyxml></code><documentation>Return the ellipse passing through the five points (if possible)</documentation></function></asyxml>*/ - return ellipse(bqe(M1,M2,M3,M4,M5)); + return ellipse(bqe(M1, M2, M3, M4, M5)); } -/*<asyxml><function type="bool" signature="inside(ellipse,point)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "inside(ellipse, point)"><code></asyxml>*/ bool inside(ellipse el, point M) {/*<asyxml></code><documentation>Return 'true' iff 'M' is inside 'el'.</documentation></function></asyxml>*/ - return abs(el.F1-M)+abs(el.F2-M)-2*el.a < -epsgeo; + return abs(el.F1 - M) + abs(el.F2 - M) - 2 * el.a < -epsgeo; } -/*<asyxml><function type="bool" signature="inside(parabola,point)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "inside(parabola, point)"><code></asyxml>*/ bool inside(parabola p, point M) {/*<asyxml></code><documentation>Return 'true' if 'M' is inside 'p'.</documentation></function></asyxml>*/ - return distance(p.D,M) - abs(p.F-M) > epsgeo; + return distance(p.D, M) - abs(p.F - M) > epsgeo; } -/*<asyxml><function type="parabola" signature="parabola(point,line)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(point, line)"><code></asyxml>*/ parabola parabola(point F, line l) {/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and directrix is 'l'.</documentation></function></asyxml>*/ parabola op; - op.init(F,l); + op.init(F, l); return op; } -/*<asyxml><function type="parabola" signature="parabola(point,point)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(point, point)"><code></asyxml>*/ parabola parabola(point F, point vertex) {/*<asyxml></code><documentation>Return the parabola whose focus is 'F' and vertex is 'vertex'.</documentation></function></asyxml>*/ parabola op; - point[] P=standardizecoordsys(F,vertex); - point A=rotate(180,P[1])*P[0]; - point B=A+rotateO(90)*unit(P[1]-A); - op.init(P[0],line(A,B)); + point[] P = standardizecoordsys(F, vertex); + point A = rotate(180, P[1]) * P[0]; + point B = A + rotateO(90) * unit(P[1]-A); + op.init(P[0], line(A, B)); return op; } -/*<asyxml><function type="parabola" signature="parabola(point,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(point, real, real)"><code></asyxml>*/ parabola parabola(point F, real a, real angle) {/*<asyxml></code><documentation>Return the parabola whose focus is F, latus rectum is 4a and the angle of the axis of symmetry (in the coordinate system of F) is 'angle'.</documentation></function></asyxml>*/ parabola op; - coordsys R=F.coordsys; - point A=F-point(R,R.polar(2a,radians(angle))); - point B=A+point(R,R.polar(1,radians(90+angle))); - op.init(F,line(A,B)); + coordsys R = F.coordsys; + point A = F - point(R, R.polar(2a, radians(angle))); + point B = A + point(R, R.polar(1, radians(90 + angle))); + op.init(F, line(A, B)); return op; } -/*<asyxml><function type="bool" signature="isparabola(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "bool" signature = "isparabola(bqe)"><code></asyxml>*/ bool isparabola(bqe bqe) {/*<asyxml></code><documentation>Return true iff 'bqe' is the equation of a parabola.</documentation></function></asyxml>*/ - bqe lbqe=changecoordsys(defaultcoordsys,bqe); - real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5]; - real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a); - return (abs(delta) > epsgeo && abs(b^2-a*c) < epsgeo); + bqe lbqe = changecoordsys(defaultcoordsys, bqe); + real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5]; + real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a); + return (abs(delta) > epsgeo && abs(b^2 - a * c) < epsgeo); } -/*<asyxml><function type="parabola" signature="parabola(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(bqe)"><code></asyxml>*/ parabola parabola(bqe bqe) -{/*<asyxml></code><documentation>Return the parabola a[0]x^2+a[1]xy+a[2]y^2+a[3]x+a[4]y+a[5]]=0 (a[n] means bqe.a[n]). - <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/> - <url href="http://mathworld.wolfram.com/Parabola.html"/></documentation></function></asyxml>*/ - bqe lbqe=changecoordsys(defaultcoordsys,bqe); - real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5]; - string message="parabola: the given equation is not an equation of a parabola."; - real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a); - if(abs(delta) < 10*epsgeo || abs(b^2-a*c) > 10*epsgeo) abort(message); - real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b); - if(dir*(c-a)*b < 0) dir=dir < 0 ? dir+pi/2 : dir-pi/2; - real cd=cos(dir), sd=sin(dir); - real ap=a*cd^2-2*b*cd*sd+c*sd^2; - real cp=a*sd^2+2*b*cd*sd+c*cd^2; - real dp=d*cd-f*sd; - real fp=d*sd+f*cd; - real gp=g; +{/*<asyxml></code><documentation>Return the parabola a[0]x^2 + a[1]xy + a[2]y^2 + a[3]x + a[4]y + a[5]] = 0 (a[n] means bqe.a[n]). + <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/> + <url href = "http://mathworld.wolfram.com/Parabola.html"/></documentation></function></asyxml>*/ + bqe lbqe = changecoordsys(defaultcoordsys, bqe); + real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5]; + string message = "parabola: the given equation is not an equation of a parabola."; + real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a); + if(abs(delta) < 10 * epsgeo || abs(b^2 - a * c) > 10 * epsgeo) abort(message); + real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b); + if(dir * (c - a) * b < 0) dir = dir < 0 ? dir + pi/2 : dir - pi/2; + real cd = cos(dir), sd = sin(dir); + real ap = a * cd^2 - 2 * b * cd * sd + c * sd^2; + real cp = a * sd^2 + 2 * b * cd * sd + c * cd^2; + real dp = d * cd - f * sd; + real fp = d * sd + f * cd; + real gp = g; parabola op; - coordsys R=bqe.coordsys; - // The equation of the parabola is ap*x'^2+cp*y'^2+2dp*x'+2fp*y'+gp=0 + coordsys R = bqe.coordsys; + // The equation of the parabola is ap * x'^2 + cp * y'^2 + 2dp * x'+2fp * y'+gp = 0 if (abs(ap) < epsgeo) {/* directrix parallel to the rotated(dir) y-axis - equation: (y-vertex.y)^2=4*a*(x-vertex) + equation: (y-vertex.y)^2 = 4 * a * (x-vertex) */ - pair pvertex=rotate(degrees(-dir))*(0.5(-gp+fp^2/cp)/dp,-fp/cp); - real a=-0.5*dp/cp; - point vertex=point(R,pvertex/R); - point focus=point(R,(pvertex+a*expi(-dir))/R); - op=parabola(focus,vertex); + pair pvertex = rotate(degrees(-dir)) * (0.5(-gp + fp^2/cp)/dp, -fp/cp); + real a = -0.5 * dp/cp; + point vertex = point(R, pvertex/R); + point focus = point(R, (pvertex + a * expi(-dir))/R); + op = parabola(focus, vertex); } else {/* directrix parallel to the rotated(dir) x-axis - equation: (x-vertex)^2=4*a*(y-vertex.y) + equation: (x-vertex)^2 = 4 * a * (y-vertex.y) */ - pair pvertex=rotate(degrees(-dir))*(-dp/ap,0.5*(-gp+dp^2/ap)/fp); - real a=-0.5*fp/ap; - point vertex=point(R,pvertex/R); - point focus=point(R,(pvertex+a*expi(pi/2-dir))/R); - op=parabola(focus,vertex); + pair pvertex = rotate(degrees(-dir)) * (-dp/ap, 0.5 * (-gp + dp^2/ap)/fp); + real a = -0.5 * fp/ap; + point vertex = point(R, pvertex/R); + point focus = point(R, (pvertex + a * expi(pi/2 - dir))/R); + op = parabola(focus, vertex); } return op; } -/*<asyxml><function type="parabola" signature="parabola(point,point,point,line)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(point, point, point, line)"><code></asyxml>*/ parabola parabola(point M1, point M2, point M3, line l) {/*<asyxml></code><documentation>Return the parabola passing through the three points with its directix parallel to the line 'l'.</documentation></function></asyxml>*/ coordsys R; pair[] pts; - if (samecoordsys(M1,M2,M3)) { - R=M1.coordsys; + if (samecoordsys(M1, M2, M3)) { + R = M1.coordsys; } else { - R=defaultcoordsys; + R = defaultcoordsys; } - real gle=degrees(l); - coordsys Rp=cartesiansystem(R.O,rotate(gle)*R.i,rotate(gle)*R.j); - pts=new pair[] {coordinates(changecoordsys(Rp,M1)), - coordinates(changecoordsys(Rp,M2)), - coordinates(changecoordsys(Rp,M3))}; + real gle = degrees(l); + coordsys Rp = cartesiansystem(R.O, rotate(gle) * R.i, rotate(gle) * R.j); + pts = new pair[] {coordinates(changecoordsys(Rp, M1)), + coordinates(changecoordsys(Rp, M2)), + coordinates(changecoordsys(Rp, M3))}; real[][] M; real[] x; - for (int i=0; i < 3; ++i) { - M[i]=new real[] {pts[i].x,pts[i].y,1}; - x[i]=-pts[i].x^2; + for (int i = 0; i < 3; ++i) { + M[i] = new real[] {pts[i].x, pts[i].y, 1}; + x[i] = -pts[i].x^2; } - real[] coef=solve(M,x); - return parabola(changecoordsys(R,bqe(Rp,1,0,0,coef[0],coef[1],coef[2]))); + real[] coef = solve(M, x); + return parabola(changecoordsys(R, bqe(Rp, 1, 0, 0, coef[0], coef[1], coef[2]))); } -/*<asyxml><function type="parabola" signature="parabola(point,point,point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "parabola" signature = "parabola(point, point, point, point, point)"><code></asyxml>*/ parabola parabola(point M1, point M2, point M3, point M4, point M5) {/*<asyxml></code><documentation>Return the parabola passing through the five points.</documentation></function></asyxml>*/ - return parabola(bqe(M1,M2,M3,M4,M5)); + return parabola(bqe(M1, M2, M3, M4, M5)); } -/*<asyxml><function type="hyperbola" signature="hyperbola(point,real,real,real)"><code></asyxml>*/ -hyperbola hyperbola(point C, real a, real b, real angle=0) -{/*<asyxml></code><documentation>Return the hyperbola centered at 'C' with semimajor axis 'a' along C--C+dir(angle), +/*<asyxml><function type = "hyperbola" signature = "hyperbola(point, real, real, real)"><code></asyxml>*/ +hyperbola hyperbola(point C, real a, real b, real angle = 0) +{/*<asyxml></code><documentation>Return the hyperbola centered at 'C' with semimajor axis 'a' along C--C + dir(angle), semiminor axis 'b' along the perpendicular.</documentation></function></asyxml>*/ hyperbola oh; - coordsys R=C.coordsys; - angle+=degrees(R.i); - real c=sqrt(a^2+b^2); - point f1=point(R,(locate(C)+rotate(angle)*(-c,0))/R); - point f2=point(R,(locate(C)+rotate(angle)*(c,0))/R); - oh.init(f1,f2,a); + coordsys R = C.coordsys; + angle += degrees(R.i); + real c = sqrt(a^2 + b^2); + point f1 = point(R, (locate(C) + rotate(angle) * (-c, 0))/R); + point f2 = point(R, (locate(C) + rotate(angle) * (c, 0))/R); + oh.init(f1, f2, a); return oh; } -/*<asyxml><function type="hyperbola" signature="hyperbola(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "hyperbola" signature = "hyperbola(bqe)"><code></asyxml>*/ hyperbola hyperbola(bqe bqe) -{/*<asyxml></code><documentation>Return the hyperbola a[0]x^2+a[1]xy+a[2]y^2+a[3]x+a[4]y+a[5]]=0 (a[n] means bqe.a[n]). - <url href="http://mathworld.wolfram.com/QuadraticCurve.html"/> - <url href="http://mathworld.wolfram.com/Hyperbola.html"/></documentation></function></asyxml>*/ - bqe lbqe=changecoordsys(defaultcoordsys,bqe); - real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5]; - string message="hyperbola: the given equation is not an equation of a hyperbola."; - real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a); - if(abs(delta) < 10*epsgeo || abs(b^2-a*c) < 0) abort(message); - real dir=abs(b) < epsgeo ? 0 : 0.5*acot(0.5*(c-a)/b); - real cd=cos(dir), sd=sin(dir); - real ap=a*cd^2-2*b*cd*sd+c*sd^2; - real cp=a*sd^2+2*b*cd*sd+c*cd^2; - real dp=d*cd-f*sd; - real fp=d*sd+f*cd; - real gp=-g+dp^2/ap+fp^2/cp; +{/*<asyxml></code><documentation>Return the hyperbola a[0]x^2 + a[1]xy + a[2]y^2 + a[3]x + a[4]y + a[5]] = 0 (a[n] means bqe.a[n]). + <url href = "http://mathworld.wolfram.com/QuadraticCurve.html"/> + <url href = "http://mathworld.wolfram.com/Hyperbola.html"/></documentation></function></asyxml>*/ + bqe lbqe = changecoordsys(defaultcoordsys, bqe); + real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5]; + string message = "hyperbola: the given equation is not an equation of a hyperbola."; + real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a); + if(abs(delta) < 10 * epsgeo || abs(b^2 - a * c) < 0) abort(message); + real dir = abs(b) < epsgeo ? 0 : 0.5 * acot(0.5 * (c - a)/b); + real cd = cos(dir), sd = sin(dir); + real ap = a * cd^2 - 2 * b * cd * sd + c * sd^2; + real cp = a * sd^2 + 2 * b * cd * sd + c * cd^2; + real dp = d * cd - f * sd; + real fp = d * sd + f * cd; + real gp = -g + dp^2/ap + fp^2/cp; hyperbola op; - coordsys R=bqe.coordsys; - real j=b^2-a*c; - point C=point(R,((c*d-b*f)/j,(a*f-b*d)/j)/R); - real aa=gp/ap, bb=gp/cp; - real a=sqrt(abs(aa)), b=sqrt(abs(bb)); - if(aa < 0) {dir -= pi/2; aa=a; a=b; b=aa;} - return hyperbola(C,a,b,degrees(-dir-angle(R.i))); + coordsys R = bqe.coordsys; + real j = b^2 - a * c; + point C = point(R, ((c * d - b * f)/j, (a * f - b * d)/j)/R); + real aa = gp/ap, bb = gp/cp; + real a = sqrt(abs(aa)), b = sqrt(abs(bb)); + if(aa < 0) {dir -= pi/2; aa = a; a = b; b = aa;} + return hyperbola(C, a, b, degrees(-dir - angle(R.i))); } -/*<asyxml><function type="hyperbola" signature="hyperbola(point,point,point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "hyperbola" signature = "hyperbola(point, point, point, point, point)"><code></asyxml>*/ hyperbola hyperbola(point M1, point M2, point M3, point M4, point M5) {/*<asyxml></code><documentation>Return the hyperbola passing through the five points (if possible).</documentation></function></asyxml>*/ - return hyperbola(bqe(M1,M2,M3,M4,M5)); + return hyperbola(bqe(M1, M2, M3, M4, M5)); } -/*<asyxml><function type="hyperbola" signature="conj(hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "hyperbola" signature = "conj(hyperbola)"><code></asyxml>*/ hyperbola conj(hyperbola h) {/*<asyxml></code><documentation>Conjugate.</documentation></function></asyxml>*/ - return hyperbola(h.C, h.b, h.a, 90+h.angle); + return hyperbola(h.C, h.b, h.a, 90 + h.angle); } -/*<asyxml><function type="circle" signature="circle(explicit point,real)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circle(explicit point, real)"><code></asyxml>*/ circle circle(explicit point C, real r) {/*<asyxml></code><documentation>Circle given by center and radius.</documentation></function></asyxml>*/ - circle oc=new circle; - oc.C=C; - oc.r=r; - if(!finite(r)) oc.l=line(C,C+vector(C.coordsys,(1,0))); + circle oc = new circle; + oc.C = C; + oc.r = r; + if(!finite(r)) oc.l = line(C, C + vector(C.coordsys, (1, 0))); return oc; } -/*<asyxml><function type="circle" signature="circle(point,point)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circle(point, point)"><code></asyxml>*/ circle circle(point A, point B) {/*<asyxml></code><documentation>Return the circle of diameter AB.</documentation></function></asyxml>*/ real r; circle oc; - real a=abs(A), b=abs(B); + real a = abs(A), b = abs(B); if(finite(a) && finite(b)) { - oc=circle((A+B)/2,abs(A-B)/2); + oc = circle((A + B)/2, abs(A - B)/2); } else { - oc.r=infinity; - if(finite(abs(A))) oc.l=line(A,A+unit(B)); + oc.r = infinity; + if(finite(abs(A))) oc.l = line(A, A + unit(B)); else { - if(finite(abs(B))) oc.l=line(B,B+unit(A)); - else if(finite(abs(A-B)/2)) oc=circle((A+B)/2,abs(A-B)/2); else - oc.l=line(A,B); + if(finite(abs(B))) oc.l = line(B, B + unit(A)); + else if(finite(abs(A - B)/2)) oc = circle((A + B)/2, abs(A - B)/2); else + oc.l = line(A, B); } } return oc; } -/*<asyxml><function type="circle" signature="circle(segment)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circle(segment)"><code></asyxml>*/ circle circle(segment s) {/*<asyxml></code><documentation>Return the circle of diameter 's'.</documentation></function></asyxml>*/ - return circle(s.A,s.B); + return circle(s.A, s.B); } -/*<asyxml><function type="point" signature="circumcenter(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "circumcenter(point, point, point)"><code></asyxml>*/ point circumcenter(point A, point B, point C) {/*<asyxml></code><documentation>Return the circumcenter of triangle ABC.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B,C); - coordsys R=P[0].coordsys; - pair a=A, b=B, c=C; - pair mAB=(a+b)/2; - pair mAC=(a+c)/2; - pair pp=extension(mAB, rotate(90,mAB)*a, mAC, rotate(90,mAC)*c); - return point(R,pp/R); + point[] P = standardizecoordsys(A, B, C); + coordsys R = P[0].coordsys; + pair a = A, b = B, c = C; + pair mAB = (a + b)/2; + pair mAC = (a + c)/2; + pair pp = extension(mAB, rotate(90, mAB) * a, mAC, rotate(90, mAC) * c); + return point(R, pp/R); } -/*<asyxml><function type="circle" signature="circle(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circle(point, point, point)"><code></asyxml>*/ circle circle(point A, point B, point C) {/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/ - if(collinear(A-B,A-C)) { + if(collinear(A - B, A - C)) { circle oc; - oc.r=infinity; - oc.C=(A+B+C)/3; - oc.l=line(oc.C, oc.C == A ? B : A); + oc.r = infinity; + oc.C = (A + B + C)/3; + oc.l = line(oc.C, oc.C == A ? B : A); return oc; } - point c=circumcenter(A, B, C); - return circle(c,abs(c-A)); + point c = circumcenter(A, B, C); + return circle(c, abs(c - A)); } -/*<asyxml><function type="circle" signature="circumcircle(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circumcircle(point, point, point)"><code></asyxml>*/ circle circumcircle(point A, point B, point C) {/*<asyxml></code><documentation>Return the circumcircle of the triangle ABC.</documentation></function></asyxml>*/ - return circle(A,B,C); + return circle(A, B, C); } -/*<asyxml><operator type="circle" signature="*(real,explicit circle)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "*(real, explicit circle)"><code></asyxml>*/ circle operator *(real x, explicit circle c) {/*<asyxml></code><documentation>Multiply the radius of 'c'.</documentation></operator></asyxml>*/ - return finite(c.r) ? circle(c.C,x*c.r) : c; + return finite(c.r) ? circle(c.C, x * c.r) : c; } circle operator *(int x, explicit circle c) { - return finite(c.r) ? circle(c.C,x*c.r) : c; + return finite(c.r) ? circle(c.C, x * c.r) : c; } -/*<asyxml><operator type="circle" signature="/(explicit circle,real)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "/(explicit circle, real)"><code></asyxml>*/ circle operator /(explicit circle c, real x) {/*<asyxml></code><documentation>Divide the radius of 'c'</documentation></operator></asyxml>*/ - return finite(c.r) ? circle(c.C,c.r/x) : c; + return finite(c.r) ? circle(c.C, c.r/x) : c; } -circle operator /(explicit circle c,int x) +circle operator /(explicit circle c, int x) { - return finite(c.r) ? circle(c.C,c.r/x) : c; + return finite(c.r) ? circle(c.C, c.r/x) : c; } -/*<asyxml><operator type="circle" signature="+(explicit circle,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "+(explicit circle, explicit point)"><code></asyxml>*/ circle operator +(explicit circle c, explicit point M) {/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/ - return circle(c.C+M,c.r); + return circle(c.C + M, c.r); } -/*<asyxml><operator type="circle" signature="-(explicit circle,explicit point)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "-(explicit circle, explicit point)"><code></asyxml>*/ circle operator -(explicit circle c, explicit point M) {/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/ - return circle(c.C-M,c.r); + return circle(c.C - M, c.r); } -/*<asyxml><operator type="circle" signature="+(explicit circle,pair)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "+(explicit circle, pair)"><code></asyxml>*/ circle operator +(explicit circle c, pair m) {/*<asyxml></code><documentation>Translation of 'c'. 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/ - return circle(c.C+m,c.r); + return circle(c.C + m, c.r); } -/*<asyxml><operator type="circle" signature="-(explicit circle,pair)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "-(explicit circle, pair)"><code></asyxml>*/ circle operator -(explicit circle c, pair m) {/*<asyxml></code><documentation>Translation of 'c'. 'm' represent coordinates in the coordinate system where 'c' is defined.</documentation></operator></asyxml>*/ - return circle(c.C-m,c.r); + return circle(c.C - m, c.r); } -/*<asyxml><operator type="circle" signature="+(explicit circle,vector)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "+(explicit circle, vector)"><code></asyxml>*/ circle operator +(explicit circle c, vector m) {/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/ - return circle(c.C+m,c.r); + return circle(c.C + m, c.r); } -/*<asyxml><operator type="circle" signature="-(explicit circle,vector)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "-(explicit circle, vector)"><code></asyxml>*/ circle operator -(explicit circle c, vector m) {/*<asyxml></code><documentation>Translation of 'c'.</documentation></operator></asyxml>*/ - return circle(c.C-m,c.r); + return circle(c.C - m, c.r); } -/*<asyxml><operator type="real" signature="^(point,explicit circle)"><code></asyxml>*/ +/*<asyxml><operator type = "real" signature = "^(point, explicit circle)"><code></asyxml>*/ real operator ^(point M, explicit circle c) {/*<asyxml></code><documentation>The power of 'M' with respect to the circle 'c'</documentation></operator></asyxml>*/ - return xpart((abs(locate(M)-locate(c.C)),c.r)^2); + return xpart((abs(locate(M) - locate(c.C)), c.r)^2); } -/*<asyxml><operator type="bool" signature="@(point,explicit circle)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "@(point, explicit circle)"><code></asyxml>*/ bool operator @(point M, explicit circle c) {/*<asyxml></code><documentation>Return true iff 'M' is on the circle 'c'.</documentation></operator></asyxml>*/ return finite(c.r) ? - abs(abs(locate(M)-locate(c.C))-abs(c.r)) <= 10*epsgeo : + abs(abs(locate(M) - locate(c.C)) - abs(c.r)) <= 10 * epsgeo : M @ c.l; } -/*<asyxml><operator type="ellipse" signature="cast(circle)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "cast(circle)"><code></asyxml>*/ ellipse operator cast(circle c) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ - return finite(c.r) ? ellipse(c.C,c.r,c.r,0) : ellipse(c.l.A,c.l.B,infinity); + return finite(c.r) ? ellipse(c.C, c.r, c.r, 0) : ellipse(c.l.A, c.l.B, infinity); } -/*<asyxml><operator type="circle" signature="cast(ellipse)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "cast(ellipse)"><code></asyxml>*/ circle operator cast(ellipse el) {/*<asyxml></code><documentation></documentation></operator></asyxml>*/ circle oc; - bool infb=(!finite(el.a) || !finite(el.b)); - if(!infb && abs(el.a-el.b) > epsgeo) + bool infb = (!finite(el.a) || !finite(el.b)); + if(!infb && abs(el.a - el.b) > epsgeo) abort("Can not cast ellipse with different axis values to circle"); - oc=circle(el.C,infb ? infinity : el.a); - oc.l=el.l.copy(); + oc = circle(el.C, infb ? infinity : el.a); + oc.l = el.l.copy(); return oc; } -/*<asyxml><operator type="ellipse" signature="cast(conic)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "cast(conic)"><code></asyxml>*/ ellipse operator cast(conic co) {/*<asyxml></code><documentation>Cast a conic to an ellipse (can be a circle).</documentation></operator></asyxml>*/ - if(degenerate(co) && co.e < 1) return ellipse(co.l[0].A, co.l[0].B,infinity); + if(degenerate(co) && co.e < 1) return ellipse(co.l[0].A, co.l[0].B, infinity); ellipse oe; if(co.e < 1) { - real a=co.p/(1-co.e^2); - real c=co.e*a; - vector v=co.D.v; - if(!sameside(co.D.A+v,co.F,co.D)) v=-v; - point f2=co.F+2*c*v; - f2=changecoordsys(co.F.coordsys,f2); - oe=a == 0 ? ellipse(co.F,co.p,co.p,0) : ellipse(co.F,f2,a); + real a = co.p/(1 - co.e^2); + real c = co.e * a; + vector v = co.D.v; + if(!sameside(co.D.A + v, co.F, co.D)) v = -v; + point f2 = co.F + 2 * c * v; + f2 = changecoordsys(co.F.coordsys, f2); + oe = a == 0 ? ellipse(co.F, co.p, co.p, 0) : ellipse(co.F, f2, a); } else abort("casting: The conic section is not an ellipse."); return oe; } -/*<asyxml><operator type="parabola" signature="cast(conic)"><code></asyxml>*/ +/*<asyxml><operator type = "parabola" signature = "cast(conic)"><code></asyxml>*/ parabola operator cast(conic co) {/*<asyxml></code><documentation>Cast a conic to a parabola.</documentation></operator></asyxml>*/ parabola op; - if(abs(co.e-1) > epsgeo) abort("casting: The conic section is not a parabola."); - op.init(co.F,co.D); + if(abs(co.e - 1) > epsgeo) abort("casting: The conic section is not a parabola."); + op.init(co.F, co.D); return op; } -/*<asyxml><operator type="conic" signature="cast(parabola)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "cast(parabola)"><code></asyxml>*/ conic operator cast(parabola p) {/*<asyxml></code><documentation>Cast a parabola to a conic section.</documentation></operator></asyxml>*/ - return conic(p.F,p.D,1); + return conic(p.F, p.D, 1); } -/*<asyxml><operator type="hyperbola" signature="cast(conic)"><code></asyxml>*/ +/*<asyxml><operator type = "hyperbola" signature = "cast(conic)"><code></asyxml>*/ hyperbola operator cast(conic co) {/*<asyxml></code><documentation>Cast a conic section to an hyperbola.</documentation></operator></asyxml>*/ hyperbola oh; if(co.e > 1) { - real a=co.p/(co.e^2-1); - real c=co.e*a; - vector v=co.D.v; - if(sameside(co.D.A+v,co.F,co.D)) v=-v; - point f2=co.F+2*c*v; - f2=changecoordsys(co.F.coordsys,f2); - oh=hyperbola(co.F,f2,a); + real a = co.p/(co.e^2 - 1); + real c = co.e * a; + vector v = co.D.v; + if(sameside(co.D.A + v, co.F, co.D)) v = -v; + point f2 = co.F + 2 * c * v; + f2 = changecoordsys(co.F.coordsys, f2); + oh = hyperbola(co.F, f2, a); } else abort("casting: The conic section is not an hyperbola."); return oh; } -/*<asyxml><operator type="conic" signature="cast(hyperbola)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "cast(hyperbola)"><code></asyxml>*/ conic operator cast(hyperbola h) {/*<asyxml></code><documentation>Hyperbola to conic section.</documentation></operator></asyxml>*/ - return conic(h.F1,h.D1,h.e); + return conic(h.F1, h.D1, h.e); } -/*<asyxml><operator type="conic" signature="cast(ellipse)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "cast(ellipse)"><code></asyxml>*/ conic operator cast(ellipse el) {/*<asyxml></code><documentation>Ellipse to conic section.</documentation></operator></asyxml>*/ conic oc; if(abs(el.c) > epsgeo) { - real x=el.a^2/el.c; - point O=(el.F1+el.F2)/2; - point A=O+x*unit(el.F1-el.F2); - oc=conic(el.F1,perpendicular(A,line(el.F1,el.F2)),el.e); + real x = el.a^2/el.c; + point O = (el.F1 + el.F2)/2; + point A = O + x * unit(el.F1 - el.F2); + oc = conic(el.F1, perpendicular(A, line(el.F1, el.F2)), el.e); } else {//The ellipse is a circle - coordsys R=coordsys(el); - point M=el.F1+point(R,R.polar(el.a,0)); - line l=line(rotate(90,M)*el.F1,M); - oc=conic(el.F1,l,0); + coordsys R = coordsys(el); + point M = el.F1 + point(R, R.polar(el.a, 0)); + line l = line(rotate(90, M) * el.F1, M); + oc = conic(el.F1, l, 0); } if(degenerate(el)) { - oc.p=infinity; - oc.h=infinity; - oc.l=new line[]{el.l}; + oc.p = infinity; + oc.h = infinity; + oc.l = new line[]{el.l}; } return oc; } -/*<asyxml><operator type="conic" signature="cast(circle)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "cast(circle)"><code></asyxml>*/ conic operator cast(circle c) {/*<asyxml></code><documentation>Circle to conic section.</documentation></operator></asyxml>*/ return (conic)((ellipse)c); } -/*<asyxml><operator type="circle" signature="cast(conic)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "cast(conic)"><code></asyxml>*/ circle operator cast(conic c) {/*<asyxml></code><documentation>Conic section to circle.</documentation></operator></asyxml>*/ - ellipse el=(ellipse)c; + ellipse el = (ellipse)c; circle oc; - if(abs(el.a-el.b) < epsgeo) { - oc=circle(el.C,el.a); - if(degenerate(c)) oc.l=c.l[0]; + if(abs(el.a - el.b) < epsgeo) { + oc = circle(el.C, el.a); + if(degenerate(c)) oc.l = c.l[0]; } else abort("Can not cast this conic to a circle"); return oc; } -/*<asyxml><operator type="ellipse" signature="*(transform,ellipse)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "*(transform, ellipse)"><code></asyxml>*/ ellipse operator *(transform t, ellipse el) -{/*<asyxml></code><documentation>Provide transform*ellipse.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide transform * ellipse.</documentation></operator></asyxml>*/ if(!degenerate(el)) { point[] ep; - for (int i=0; i<360; i+=72) { - ep.push(t*angpoint(el,i)); + for (int i = 0; i < 360; i += 72) { + ep.push(t * angpoint(el, i)); } - ellipse oe=ellipse(ep[0],ep[1],ep[2],ep[3],ep[4]); - if(angpoint(oe,0) != ep[0]) return ellipse(oe.F2,oe.F1,oe.a); + ellipse oe = ellipse(ep[0], ep[1], ep[2], ep[3], ep[4]); + if(angpoint(oe, 0) != ep[0]) return ellipse(oe.F2, oe.F1, oe.a); return oe; } - return ellipse(t*el.l.A,t*el.l.B,infinity); + return ellipse(t * el.l.A, t * el.l.B, infinity); } -/*<asyxml><operator type="parabola" signature="*(transform,parabola)"><code></asyxml>*/ +/*<asyxml><operator type = "parabola" signature = "*(transform, parabola)"><code></asyxml>*/ parabola operator *(transform t, parabola p) -{/*<asyxml></code><documentation>Provide transform*parabola.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide transform * parabola.</documentation></operator></asyxml>*/ point[] P; - P.push(t*angpoint(p,45)); - P.push(t*angpoint(p,-45)); - P.push(t*angpoint(p,180)); - return parabola(P[0],P[1],P[2],t*p.D); + P.push(t * angpoint(p, 45)); + P.push(t * angpoint(p, -45)); + P.push(t * angpoint(p, 180)); + parabola op = parabola(P[0], P[1], P[2], t * p.D); + op.bmin = p.bmin; + op.bmax = p.bmax; + + return op; } -/*<asyxml><operator type="ellipse" signature="*(transform,circle)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "*(transform, circle)"><code></asyxml>*/ ellipse operator *(transform t, circle c) -{/*<asyxml></code><documentation>Provide transform*circle. - For example, 'circle C=scale(2)*circle' and 'ellipse E=xscale(2)*circle' are valid - but 'circle C=xscale(2)*circle' is invalid.</documentation></operator></asyxml>*/ - return t*((ellipse)c); +{/*<asyxml></code><documentation>Provide transform * circle. + For example, 'circle C = scale(2) * circle' and 'ellipse E = xscale(2) * circle' are valid + but 'circle C = xscale(2) * circle' is invalid.</documentation></operator></asyxml>*/ + return t * ((ellipse)c); } -/*<asyxml><operator type="hyperbola" signature="*(transform,hyperbola)"><code></asyxml>*/ +/*<asyxml><operator type = "hyperbola" signature = "*(transform, hyperbola)"><code></asyxml>*/ hyperbola operator *(transform t, hyperbola h) -{/*<asyxml></code><documentation>Provide transform*hyperbola.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide transform * hyperbola.</documentation></operator></asyxml>*/ + if (t == identity()) { + return h; + } + point[] ep; - for (int i=90; i<=270; i+=45) { - ep.push(t*angpoint(h,i)); + for (int i = 90; i <= 270; i += 45) { + ep.push(t * angpoint(h, i)); + } + + hyperbola oe = hyperbola(ep[0], ep[1], ep[2], ep[3], ep[4]); + if(angpoint(oe, 90) != ep[0]) { + oe = hyperbola(oe.F2, oe.F1, oe.a); } - hyperbola oe=hyperbola(ep[0],ep[1],ep[2],ep[3],ep[4]); - if(angpoint(oe,90) != ep[0]) return hyperbola(oe.F2,oe.F1,oe.a); + + oe.bmin = h.bmin; + oe.bmax = h.bmax; + return oe; } -/*<asyxml><operator type="conic" signature="*(transform,conic)"><code></asyxml>*/ +/*<asyxml><operator type = "conic" signature = "*(transform, conic)"><code></asyxml>*/ conic operator *(transform t, conic co) -{/*<asyxml></code><documentation>Provide transform*conic.</documentation></operator></asyxml>*/ - if(co.e < 1) return (t*((ellipse)co)); - if(co.e == 1) return (t*((parabola)co)); - return (t*((hyperbola)co)); +{/*<asyxml></code><documentation>Provide transform * conic.</documentation></operator></asyxml>*/ + if(co.e < 1) return (t * ((ellipse)co)); + if(co.e == 1) return (t * ((parabola)co)); + return (t * ((hyperbola)co)); } -/*<asyxml><operator type="ellipse" signature="*(real,ellipse)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "*(real, ellipse)"><code></asyxml>*/ ellipse operator *(real x, ellipse el) -{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(x,el.C)*el'.</documentation></operator></asyxml>*/ - return degenerate(el) ? el : ellipse(el.C,x*el.a,x*el.b,el.angle); +{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(x, el.C) * el'.</documentation></operator></asyxml>*/ + return degenerate(el) ? el : ellipse(el.C, x * el.a, x * el.b, el.angle); } -/*<asyxml><operator type="ellipse" signature="/(ellipse,real)"><code></asyxml>*/ +/*<asyxml><operator type = "ellipse" signature = "/(ellipse, real)"><code></asyxml>*/ ellipse operator /(ellipse el, real x) -{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(1/x,el.C)*el'.</documentation></operator></asyxml>*/ - return degenerate(el) ? el : ellipse(el.C,el.a/x,el.b/x,el.angle); +{/*<asyxml></code><documentation>Identical but more efficient (rapid) than 'scale(1/x, el.C) * el'.</documentation></operator></asyxml>*/ + return degenerate(el) ? el : ellipse(el.C, el.a/x, el.b/x, el.angle); } -/*<asyxml><function type="path" signature="arcfromcenter(ellipse,real,real,int,bool)"><code></asyxml>*/ +/*<asyxml><function type = "path" signature = "arcfromcenter(ellipse, real, real, int, bool)"><code></asyxml>*/ path arcfromcenter(ellipse el, real angle1, real angle2, - bool direction=CCW, - int n=ellipsenodesnumber(el.a,el.b,angle1,angle2,direction)) + bool direction = CCW, + int n = ellipsenodesnumber(el.a, el.b, angle1, angle2, direction)) {/*<asyxml></code><documentation>Return the path of the ellipse 'el' from angle1 to angle2 in degrees, drawing in the given direction, with n nodes. - The angles are mesured relatively to the axis (C,x-axis) where C is + 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."); if (angle1 > angle2) - return reverse(arcfromcenter(el,angle2,angle1,!direction,n)); + return reverse(arcfromcenter(el, angle2, angle1, !direction, n)); path op; - coordsys Rp=coordsys(el); + 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 --; + 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=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); + 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 = 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); } - return shift(el.C.x*Rp.i+el.C.y*Rp.j)*(direction ? op : reverse(op)); + return shift(el.C.x * Rp.i + el.C.y * Rp.j) * (direction ? op : reverse(op)); } -/*<asyxml><function type="path" signature="arcfromcenter(hyperbola,real,real,int,bool)"><code></asyxml>*/ +/*<asyxml><function type = "path" signature = "arcfromcenter(hyperbola, real, real, int, bool)"><code></asyxml>*/ path arcfromcenter(hyperbola h, real angle1, real angle2, - int n=hyperbolanodesnumber(h,angle1,angle2), - bool direction=CCW) + int n = hyperbolanodesnumber(h, angle1, angle2), + bool direction = CCW) {/*<asyxml></code><documentation>Return the path of the hyperbola 'h' from angle1 to angle2 in degrees, drawing in the given direction, with n nodes. - The angles are mesured relatively to the axis (C,x-axis) where C is + The angles are mesured relatively to the axis (C, x-axis) where C is the center of the hyperbola.</documentation></function></asyxml>*/ guide op; - coordsys Rp=coordsys(h); + coordsys Rp = coordsys(h); if (n < 1) return op; if (angle1 > angle2) { - path g=reverse(arcfromcenter(h,angle2,angle1,n,!direction)); + path g = reverse(arcfromcenter(h, angle2, angle1, n, !direction)); return g == nullpath ? g : reverse(g); } - 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 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; typedef guide interpolate(... guide[]); - interpolate join=operator ..; - real da=radians(h.angle); - for (int i=0; i < n; ++i) { - a=a1+i*step; - r=(h.b*cos(a))^2-(h.a*sin(a))^2; + interpolate join = operator ..; + real da = radians(h.angle); + for (int i = 0; i < n; ++i) { + a = a1 + i * step; + r = (h.b * cos(a))^2 - (h.a * sin(a))^2; if(r > epsgeo) { - r=sqrt(h.a^2*h.b^2/r); - op=join(op,Rp*Rp.polar(r,a+da)); - join=operator ..; - } else join=operator --; + r = sqrt(h.a^2 * h.b^2/r); + op = join(op, Rp * Rp.polar(r, a + da)); + join = operator ..; + } else join = operator --; } - return shift(h.C.x*Rp.i+h.C.y*Rp.j)* + return shift(h.C.x * Rp.i + h.C.y * Rp.j)* (direction ? op : op == nullpath ? op : reverse(op)); } -/*<asyxml><function type="path" signature="arcfromcenter(explicit conic,real,real,int,bool)"><code></asyxml>*/ +/*<asyxml><function type = "path" signature = "arcfromcenter(explicit conic, real, real, int, bool)"><code></asyxml>*/ path arcfromcenter(explicit conic co, real angle1, real angle2, - int n, bool direction=CCW) -{/*<asyxml></code><documentation>Use arcfromcenter(ellipse,...) or arcfromcenter(hyperbola,...) depending of + int n, bool direction = CCW) +{/*<asyxml></code><documentation>Use arcfromcenter(ellipse, ...) or arcfromcenter(hyperbola, ...) depending of the eccentricity of 'co'.</documentation></function></asyxml>*/ path g; if(co.e < 1) - g=arcfromcenter((ellipse)co,angle1, - angle2,direction,n); + g = arcfromcenter((ellipse)co, angle1, + angle2, direction, n); else if(co.e > 1) - g=arcfromcenter((hyperbola)co,angle1, - angle2,n,direction); + g = arcfromcenter((hyperbola)co, angle1, + angle2, n, direction); else abort("arcfromcenter: does not exist for a parabola."); return g; } -/*<asyxml><constant type="polarconicroutine" signature="fromCenter"><code></asyxml>*/ -restricted polarconicroutine fromCenter=arcfromcenter;/*<asyxml></code><documentation></documentation></constant></asyxml>*/ -/*<asyxml><constant type="polarconicroutine" signature="fromFocus"><code></asyxml>*/ -restricted polarconicroutine fromFocus=arcfromfocus;/*<asyxml></code><documentation></documentation></constant></asyxml>*/ +/*<asyxml><constant type = "polarconicroutine" signature = "fromCenter"><code></asyxml>*/ +restricted polarconicroutine fromCenter = arcfromcenter;/*<asyxml></code><documentation></documentation></constant></asyxml>*/ +/*<asyxml><constant type = "polarconicroutine" signature = "fromFocus"><code></asyxml>*/ +restricted polarconicroutine fromFocus = arcfromfocus;/*<asyxml></code><documentation></documentation></constant></asyxml>*/ -/*<asyxml><function type="bqe" signature="equation(ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "equation(ellipse)"><code></asyxml>*/ bqe equation(ellipse el) {/*<asyxml></code><documentation>Return the coefficients of the equation of the ellipse in its coordinate system: - bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0. + bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0. One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/ pair[] pts; - for (int i=0; i<360; i+=72) - pts.push(locate(angpoint(el,i))); + for (int i = 0; i < 360; i += 72) + pts.push(locate(angpoint(el, i))); real[][] M; real[] x; - for (int i=0; i < 5; ++i) { - M[i]=new real[] {pts[i].x*pts[i].y,pts[i].y^2,pts[i].x,pts[i].y,1}; - x[i]=-pts[i].x^2; + for (int i = 0; i < 5; ++i) { + M[i] = new real[] {pts[i].x * pts[i].y, pts[i].y^2, pts[i].x, pts[i].y, 1}; + x[i] = -pts[i].x^2; } - real[] coef=solve(M,x); - bqe bqe=changecoordsys(coordsys(el), + real[] coef = solve(M, x); + bqe bqe = changecoordsys(coordsys(el), bqe(defaultcoordsys, - 1,coef[0],coef[1],coef[2],coef[3],coef[4])); - bqe.a=approximate(bqe.a); + 1, coef[0], coef[1], coef[2], coef[3], coef[4])); + bqe.a = approximate(bqe.a); return bqe; } -/*<asyxml><function type="bqe" signature="equation(parabola)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "equation(parabola)"><code></asyxml>*/ bqe equation(parabola p) {/*<asyxml></code><documentation>Return the coefficients of the equation of the parabola in its coordinate system. - bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0 + bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0 One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/ - coordsys R=canonicalcartesiansystem(p); - parabola tp=changecoordsys(R,p); - point A=projection(tp.D)*point(R,(0,0)); - real a=abs(A); + coordsys R = canonicalcartesiansystem(p); + parabola tp = changecoordsys(R, p); + point A = projection(tp.D) * point(R, (0, 0)); + real a = abs(A); return changecoordsys(coordsys(p), - bqe(R,0,0,1,-4*a,0,0)); + bqe(R, 0, 0, 1, -4 * a, 0, 0)); } -/*<asyxml><function type="bqe" signature="equation(hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "equation(hyperbola)"><code></asyxml>*/ bqe equation(hyperbola h) {/*<asyxml></code><documentation>Return the coefficients of the equation of the hyperbola in its coordinate system. - bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0 + bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0 One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/ - coordsys R=canonicalcartesiansystem(h); + coordsys R = canonicalcartesiansystem(h); return changecoordsys(coordsys(h), - bqe(R,1/h.a^2,0,-1/h.b^2,0,0,-1)); + bqe(R, 1/h.a^2, 0, -1/h.b^2, 0, 0, -1)); } -/*<asyxml><operator type="path" signature="cast(ellipse)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(ellipse)"><code></asyxml>*/ path operator cast(ellipse el) {/*<asyxml></code><documentation>Cast ellipse to path.</documentation></operator></asyxml>*/ if(degenerate(el)) abort("Casting degenerated ellipse to path is not possible."); - int n=el.e == 0 ? circlenodesnumber(el.a) : ellipsenodesnumber(el.a,el.b); - return arcfromcenter(el,0.0,360,CCW,n)&cycle; + int n = el.e == 0 ? circlenodesnumber(el.a) : ellipsenodesnumber(el.a, el.b); + return arcfromcenter(el, 0.0, 360, CCW, n)&cycle; } -/*<asyxml><operator type="path" signature="cast(circle)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(circle)"><code></asyxml>*/ path operator cast(circle c) {/*<asyxml></code><documentation>Cast circle to path.</documentation></operator></asyxml>*/ return (path)((ellipse)c); } -/*<asyxml><function type="real[]" signature="bangles(picture,parabola)"><code></asyxml>*/ -real[] bangles(picture pic=currentpicture, parabola p) +/*<asyxml><function type = "real[]" signature = "bangles(picture, parabola)"><code></asyxml>*/ +real[] bangles(picture pic = currentpicture, parabola p) {/*<asyxml></code><documentation>Return the array {ma, Ma} where 'ma' and 'Ma' are respectively the smaller and the larger angles for which the parabola 'p' is included in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/ - pair bmin,bmax; + pair bmin, bmax; pair[] b; if (p.bmin == p.bmax) { - bmin=pic.userMin(); - bmax=pic.userMax(); + bmin = pic.userMin(); + bmax = pic.userMax(); } else { - bmin=p.bmin;bmax=p.bmax; + bmin = p.bmin;bmax = p.bmax; } if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax))) - return new real[] {0,0}; - b[0]=bmin; - b[1]=(bmax.x,bmin.y); - b[2]=bmax; - b[3]=(bmin.x,bmax.y); - real[] eq=changecoordsys(defaultcoordsys,equation(p)).a; + return new real[] {0, 0}; + b[0] = bmin; + b[1] = (bmax.x, bmin.y); + b[2] = bmax; + b[3] = (bmin.x, bmax.y); + real[] eq = changecoordsys(defaultcoordsys, equation(p)).a; pair[] inter; - for (int i=0; i < 4; ++i) { - pair[] tmp=intersectionpoints(b[i],b[(i+1)%4],eq); - for (int j=0; j < tmp.length; ++j) { - if(dot(b[i]-tmp[j],b[(i+1)%4]-tmp[j]) <= epsgeo) + for (int i = 0; i < 4; ++i) { + pair[] tmp = intersectionpoints(b[i], b[(i + 1)%4], eq); + for (int j = 0; j < tmp.length; ++j) { + if(dot(b[i]-tmp[j], b[(i + 1)%4]-tmp[j]) <= epsgeo) inter.push(tmp[j]); } } - pair F=p.F, V=p.V; - real d=degrees(F-V); - real[] a=sequence(new real(int n){ - return (360-d+degrees(inter[n]-F))%360; + pair F = p.F, V = p.V; + real d = degrees(F - V); + real[] a = sequence(new real(int n){ + return (360 - d + degrees(inter[n]-F))%360; }, inter.length); - real ma=a.length != 0 ? min(a) : 0, Ma= a.length != 0 ? max(a) : 0; - return new real[] {ma,Ma}; + real ma = a.length != 0 ? min(a) : 0, Ma= a.length != 0 ? max(a) : 0; + return new real[] {ma, Ma}; } -/*<asyxml><function type="real[][]" signature="bangles(picture,hyperbola)"><code></asyxml>*/ -real[][] bangles(picture pic=currentpicture, hyperbola h) +/*<asyxml><function type = "real[][]" signature = "bangles(picture, hyperbola)"><code></asyxml>*/ +real[][] bangles(picture pic = currentpicture, hyperbola h) {/*<asyxml></code><documentation>Return the array {{ma1, Ma1}, {ma2, Ma2}} where 'maX' and 'MaX' are respectively the smaller and the bigger angles (from h.FX) for which the hyperbola 'h' is included in the bounding box of the picture 'pic'.</documentation></function></asyxml>*/ - pair bmin,bmax; + pair bmin, bmax; pair[] b; if (h.bmin == h.bmax) { - bmin=pic.userMin(); - bmax=pic.userMax(); + bmin = pic.userMin(); + bmax = pic.userMax(); } else { - bmin=h.bmin;bmax=h.bmax; + bmin = h.bmin;bmax = h.bmax; } if(bmin.x == bmax.x || bmin.y == bmax.y || !finite(abs(bmin)) || !finite(abs(bmax))) - return new real[][] {{0,0}, {0,0}}; - b[0]=bmin; - b[1]=(bmax.x,bmin.y); - b[2]=bmax; - b[3]=(bmin.x,bmax.y); - real[] eq=changecoordsys(defaultcoordsys,equation(h)).a; - pair[] inter0,inter1; - pair C=locate(h.C); - pair F1=h.F1; - for (int i=0; i < 4; ++i) { - pair[] tmp=intersectionpoints(b[i],b[(i+1)%4],eq); - for (int j=0; j < tmp.length; ++j) { - if(dot(b[i]-tmp[j],b[(i+1)%4]-tmp[j]) <= epsgeo) { - if(dot(F1-C,tmp[j]-C) > 0) inter0.push(tmp[j]); + return new real[][] {{0, 0}, {0, 0}}; + b[0] = bmin; + b[1] = (bmax.x, bmin.y); + b[2] = bmax; + b[3] = (bmin.x, bmax.y); + real[] eq = changecoordsys(defaultcoordsys, equation(h)).a; + pair[] inter0, inter1; + pair C = locate(h.C); + pair F1 = h.F1; + for (int i = 0; i < 4; ++i) { + pair[] tmp = intersectionpoints(b[i], b[(i + 1)%4], eq); + for (int j = 0; j < tmp.length; ++j) { + if(dot(b[i]-tmp[j], b[(i + 1)%4]-tmp[j]) <= epsgeo) { + if(dot(F1 - C, tmp[j]-C) > 0) inter0.push(tmp[j]); else inter1.push(tmp[j]); } } } - real d=degrees(F1-C); + real d = degrees(F1 - C); real[] ma, Ma; - pair[][] inter=new pair[][] {inter0, inter1}; - for (int i=0; i < 2; ++i) { - real[] a=sequence(new real(int n){ - return (360-d+degrees(inter[i][n]-F1))%360; - },inter[i].length); - ma[i]=a.length != 0 ? min(a) : 0; - Ma[i]= a.length != 0 ? max(a) : 0; + pair[][] inter = new pair[][] {inter0, inter1}; + for (int i = 0; i < 2; ++i) { + real[] a = sequence(new real(int n){ + return (360 - d + degrees(inter[i][n]-F1))%360; + }, inter[i].length); + ma[i] = a.length != 0 ? min(a) : 0; + Ma[i] = a.length != 0 ? max(a) : 0; } - return new real[][] {{ma[0],Ma[0]}, {ma[1],Ma[1]}}; + return new real[][] {{ma[0], Ma[0]}, {ma[1], Ma[1]}}; } -/*<asyxml><operator type="path" signature="cast(parabola)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(parabola)"><code></asyxml>*/ path operator cast(parabola p) {/*<asyxml></code><documentation>Cast parabola to path. If possible, the returned path is restricted to the actual bounding box of the current picture if the variables 'p.bmin' and 'p.bmax' are not set else the bounding box of box(p.bmin, p.bmax) is used instead.</documentation></operator></asyxml>*/ - real[] bangles=bangles(p); - int n=parabolanodesnumber(p,bangles[0],bangles[1]); - return arcfromfocus(p,bangles[0],bangles[1],n,CCW); + real[] bangles = bangles(p); + int n = parabolanodesnumber(p, bangles[0], bangles[1]); + return arcfromfocus(p, bangles[0], bangles[1], n, CCW); } -/*<asyxml><function type="void" signature="draw(picture,Label,circle,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="",circle c, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, Label, circle, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", circle c, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + margin margin = NoMargin, Label legend = "", marker marker = nomarker) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - if(degenerate(c)) draw(pic,L,c.l,align,p,arrow,legend,marker); - else draw(pic,L,(path)c,align,p,arrow,bar,margin,legend,marker); + if(degenerate(c)) draw(pic, L, c.l, align, p, arrow, legend, marker); + else draw(pic, L, (path)c, align, p, arrow, bar, margin, legend, marker); } -/*<asyxml><function type="void" signature="draw(picture,Label,ellipse,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="",ellipse el, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, Label, ellipse, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", ellipse el, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + margin margin = NoMargin, Label legend = "", marker marker = nomarker) {/*<asyxml></code><documentation></documentation>Draw the ellipse 'el' if it is not degenerated else draw 'el.l'.</function></asyxml>*/ - if(degenerate(el)) draw(pic,L,el.l,align,p,arrow,legend,marker); - else draw(pic,L,(path)el,align,p,arrow,bar,margin,legend,marker); + if(degenerate(el)) draw(pic, L, el.l, align, p, arrow, legend, marker); + else draw(pic, L, (path)el, align, p, arrow, bar, margin, legend, marker); } -/*<asyxml><function type="void" signature="draw(picture,Label,parabola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="",parabola parabola, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, Label, parabola, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", parabola parabola, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + 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 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; + parabola.bmin = inverse(t) * m; + parabola.bmax = inverse(t) * M; picture tmp; - draw(tmp,L,t*T*(path) parabola,align,p,arrow,bar,NoMargin,legend,marker); - add(f,tmp.fit()); - }); - pair m=pic.userMin(); - pair M=pic.userMax(); - if(m != M) + draw(tmp, L, t * ((path) (T * parabola)), align, p, arrow, bar, NoMargin, legend, marker); + add(f, tmp.fit()); + }, true); + + pair m = pic.userMin(), M = pic.userMax(); + if(m != M) { pic.addBox(truepoint(SW), truepoint(NE)); + } } -/*<asyxml><operator type="path" signature="cast(hyperbola)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(hyperbola)"><code></asyxml>*/ path operator cast(hyperbola h) {/*<asyxml></code><documentation>Cast hyperbola to path. If possible, the returned path is restricted to the actual bounding box of the current picture unless the variables 'h.bmin' and 'h.bmax' are set; in this case the bounding box of box(h.bmin, h.bmax) is used instead. Only the branch on the side of 'h.F1' is considered.</documentation></operator></asyxml>*/ - real[][] bangles=bangles(h); - int n=hyperbolanodesnumber(h,bangles[0][0],bangles[0][1]); - return arcfromfocus(h,bangles[0][0],bangles[0][1],n,CCW); + real[][] bangles = bangles(h); + int n = hyperbolanodesnumber(h, bangles[0][0], bangles[0][1]); + return arcfromfocus(h, bangles[0][0], bangles[0][1], n, CCW); } -/*<asyxml><function type="void" signature="draw(picture,Label,hyperbola,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="", hyperbola h, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, Label, hyperbola, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", hyperbola h, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + 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 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; + h.bmin = inverse(t) * m; + h.bmax = inverse(t) * M; + picture tmp; - 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,"",tT*(path) ht,align,p,arrow,bar,NoMargin,marker); - add(f,tmp.fit()); - }); - pair m=pic.userMin(); - pair M=pic.userMax(); + draw(tmp, L, t * ((path) (T * h)), align, p, arrow, bar, NoMargin, legend, marker); + + hyperbola ht = hyperbola(h.F2, h.F1, h.a); + ht.bmin = h.bmin; + ht.bmax = h.bmax; + + draw(tmp, "", t * ((path) (T * ht)), align, p, arrow, bar, NoMargin, marker); + + add(f, tmp.fit()); + }, true); + + pair m = pic.userMin(), M = pic.userMax(); if(m != M) pic.addBox(truepoint(SW), truepoint(NE)); } -/*<asyxml><function type="void" signature="draw(picture,Label,explicit conic,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="", explicit conic co, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, - margin margin=NoMargin, Label legend="", marker marker=nomarker) -{/*<asyxml></code><documentation>Use one of the routine 'draw(ellipse,...)', - 'draw(parabola,...)' or 'draw(hyperbola,...)' depending of the value of eccentricity of 'co'.</documentation></function></asyxml>*/ +/*<asyxml><function type = "void" signature = "draw(picture, Label, explicit conic, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", explicit conic co, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, + margin margin = NoMargin, Label legend = "", marker marker = nomarker) +{/*<asyxml></code><documentation>Use one of the routine 'draw(ellipse, ...)', + 'draw(parabola, ...)' or 'draw(hyperbola, ...)' depending of the value of eccentricity of 'co'.</documentation></function></asyxml>*/ if(co.e == 0) - draw(pic,L,(circle)co,align,p,arrow,bar,margin,legend,marker); + draw(pic, L, (circle)co, align, p, arrow, bar, margin, legend, marker); else - if(co.e < 1) draw(pic,L,(ellipse)co,align,p,arrow,bar,margin,legend,marker); + if(co.e < 1) draw(pic, L, (ellipse)co, align, p, arrow, bar, margin, legend, marker); else - if(co.e == 1) draw(pic,L,(parabola)co,align,p,arrow,bar,margin,legend,marker); + if(co.e == 1) draw(pic, L, (parabola)co, align, p, arrow, bar, margin, legend, marker); else - if(co.e > 1) draw(pic,L,(hyperbola)co,align,p,arrow,bar,margin,legend,marker); + if(co.e > 1) draw(pic, L, (hyperbola)co, align, p, arrow, bar, margin, legend, marker); else abort("draw: unknown conic."); } -/*<asyxml><function type="int" signature="conicnodesnumber(conic,real,real)"><code></asyxml>*/ -int conicnodesnumber(conic co, real angle1, real angle2, bool dir=CCW) +/*<asyxml><function type = "int" signature = "conicnodesnumber(conic, real, real)"><code></asyxml>*/ +int conicnodesnumber(conic co, real angle1, real angle2, bool dir = CCW) {/*<asyxml></code><documentation>Return the number of node to draw a conic arc.</documentation></function></asyxml>*/ int oi; if(co.e == 0) { - circle c=(circle)co; - oi=circlenodesnumber(c.r,angle1,angle2); + circle c = (circle)co; + oi = circlenodesnumber(c.r, angle1, angle2); } else if(co.e < 1) { - ellipse el=(ellipse)co; - oi=ellipsenodesnumber(el.a,el.b,angle1,angle2,dir); + ellipse el = (ellipse)co; + oi = ellipsenodesnumber(el.a, el.b, angle1, angle2, dir); } else if(co.e == 1) { - parabola p=(parabola)co; - oi=parabolanodesnumber(p, angle1, angle2); + parabola p = (parabola)co; + oi = parabolanodesnumber(p, angle1, angle2); } else { - hyperbola h=(hyperbola)co; - oi=hyperbolanodesnumber(h, angle1, angle2); + hyperbola h = (hyperbola)co; + oi = hyperbolanodesnumber(h, angle1, angle2); } return oi; } -/*<asyxml><operator type="path" signature="cast(conic)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(conic)"><code></asyxml>*/ path operator cast(conic co) {/*<asyxml></code><documentation>Cast conic section to path.</documentation></operator></asyxml>*/ if(co.e < 1) return (path)((ellipse)co); @@ -3871,56 +3912,56 @@ path operator cast(conic co) return (path)((hyperbola)co); } -/*<asyxml><function type="bqe" signature="equation(explicit conic)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "equation(explicit conic)"><code></asyxml>*/ bqe equation(explicit conic co) {/*<asyxml></code><documentation>Return the coefficients of the equation of conic section in its coordinate system: - bqe.a[0]*x^2 + bqe.a[1]*x*y + bqe.a[2]*y^2 + bqe.a[3]*x + bqe.a[4]*y + bqe.a[5]=0. + bqe.a[0] * x^2 + bqe.a[1] * x * y + bqe.a[2] * y^2 + bqe.a[3] * x + bqe.a[4] * y + bqe.a[5] = 0. One can change the coordinate system of 'bqe' using the routine 'changecoordsys'.</documentation></function></asyxml>*/ bqe obqe; if(co.e == 0) - obqe=equation((circle)co); + obqe = equation((circle)co); else - if(co.e < 1) obqe=equation((ellipse)co); + if(co.e < 1) obqe = equation((ellipse)co); else - if(co.e == 1) obqe=equation((parabola)co); + if(co.e == 1) obqe = equation((parabola)co); else - if(co.e > 1) obqe=equation((hyperbola)co); + if(co.e > 1) obqe = equation((hyperbola)co); else abort("draw: unknown conic."); return obqe; } -/*<asyxml><function type="string" signature="conictype(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "string" signature = "conictype(bqe)"><code></asyxml>*/ string conictype(bqe bqe) {/*<asyxml></code><documentation>Returned values are "ellipse" or "parabola" or "hyperbola" depending of the conic section represented by 'bqe'.</documentation></function></asyxml>*/ - bqe lbqe=changecoordsys(defaultcoordsys,bqe); - string os="degenerated"; - real a=lbqe.a[0], b=lbqe.a[1]/2, c=lbqe.a[2], d=lbqe.a[3]/2, f=lbqe.a[4]/2, g=lbqe.a[5]; - real delta=a*c*g + b*f*d + d*b*f - (b^2*g + d^2*c + f^2*a); - if(abs(delta) < 10*epsgeo) return os; - real J=a*c-b^2; - real I=a+c; + bqe lbqe = changecoordsys(defaultcoordsys, bqe); + string os = "degenerated"; + real a = lbqe.a[0], b = lbqe.a[1]/2, c = lbqe.a[2], d = lbqe.a[3]/2, f = lbqe.a[4]/2, g = lbqe.a[5]; + real delta = a * c * g + b * f * d + d * b * f - (b^2 * g + d^2 * c + f^2 * a); + if(abs(delta) < 10 * epsgeo) return os; + real J = a * c - b^2; + real I = a + c; if(J > epsgeo) { if(delta/I < -epsgeo); - os="ellipse"; + os = "ellipse"; } else { - if(abs(J) < epsgeo) os="parabola"; else os="hyperbola"; + if(abs(J) < epsgeo) os = "parabola"; else os = "hyperbola"; } return os; } -/*<asyxml><function type="conic" signature="conic(point,point,point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "conic" signature = "conic(point, point, point, point, point)"><code></asyxml>*/ conic conic(point M1, point M2, point M3, point M4, point M5) {/*<asyxml></code><documentation>Return the conic passing through 'M1', 'M2', 'M3', 'M4' and 'M5' if the conic is not degenerated.</documentation></function></asyxml>*/ - bqe bqe=bqe(M1,M2,M3,M4,M5); - string ct=conictype(bqe); + bqe bqe = bqe(M1, M2, M3, M4, M5); + string ct = conictype(bqe); if(ct == "degenerated") abort("conic: degenerated conic passing through five points."); if(ct == "ellipse") return ellipse(bqe); if(ct == "parabola") return parabola(bqe); return hyperbola(bqe); } -/*<asyxml><function type="coordsys" signature="canonicalcartesiansystem(hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "coordsys" signature = "canonicalcartesiansystem(hyperbola)"><code></asyxml>*/ coordsys canonicalcartesiansystem(explicit conic co) {/*<asyxml></code><documentation>Return the canonical cartesian system of the conic 'co'.</documentation></function></asyxml>*/ if(co.e < 1) return canonicalcartesiansystem((ellipse)co); @@ -3928,287 +3969,287 @@ coordsys canonicalcartesiansystem(explicit conic co) return canonicalcartesiansystem((hyperbola)co); } -/*<asyxml><function type="bqe" signature="canonical(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "bqe" signature = "canonical(bqe)"><code></asyxml>*/ bqe canonical(bqe bqe) {/*<asyxml></code><documentation>Return the bivariate quadratic equation relative to the canonical coordinate system of the conic section represented by 'bqe'.</documentation></function></asyxml>*/ - string type=conictype(bqe); + string type = conictype(bqe); if(type == "") abort("canonical: the equation can not be performed."); bqe obqe; if(type == "ellipse") { - ellipse el=ellipse(bqe); - obqe=changecoordsys(canonicalcartesiansystem(el),equation(el)); + ellipse el = ellipse(bqe); + obqe = changecoordsys(canonicalcartesiansystem(el), equation(el)); } else { if(type == "parabola") { - parabola p=parabola(bqe); - obqe=changecoordsys(canonicalcartesiansystem(p),equation(p)); + parabola p = parabola(bqe); + obqe = changecoordsys(canonicalcartesiansystem(p), equation(p)); } else { - hyperbola h=hyperbola(bqe); - obqe=changecoordsys(canonicalcartesiansystem(h),equation(h)); + hyperbola h = hyperbola(bqe); + obqe = changecoordsys(canonicalcartesiansystem(h), equation(h)); } } return obqe; } -/*<asyxml><function type="conic" signature="conic(bqe)"><code></asyxml>*/ +/*<asyxml><function type = "conic" signature = "conic(bqe)"><code></asyxml>*/ conic conic(bqe bqe) {/*<asyxml></code><documentation>Return the conic section represented by the bivariate quartic equation 'bqe'.</documentation></function></asyxml>*/ - string type=conictype(bqe); + string type = conictype(bqe); if(type == "") abort("canonical: the equation can not be performed."); conic oc; if(type == "ellipse") { - oc=ellipse(bqe); + oc = ellipse(bqe); } else { - if(type == "parabola") oc=parabola(bqe); else oc=hyperbola(bqe); + if(type == "parabola") oc = parabola(bqe); else oc = hyperbola(bqe); } return oc; } -/*<asyxml><function type="real" signature="arclength(circle)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(circle)"><code></asyxml>*/ real arclength(circle c) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return c.r*2*pi; + return c.r * 2 * pi; } -/*<asyxml><function type="real" signature="focusToCenter(ellipse,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "focusToCenter(ellipse, real)"><code></asyxml>*/ real focusToCenter(ellipse el, real a) {/*<asyxml></code><documentation>Return the angle relatively to the center of 'el' for the angle 'a' given relatively to the focus of 'el'.</documentation></function></asyxml>*/ - pair p=point(fromFocus(el,a,a,1,CCW),0); - pair c=locate(el.C); - real d=degrees(p-c)-el.angle; - d=abs(d) < epsgeo ? 0 : d; // Avoid -1e-15 - return d%(sgnd(a)*360); + pair p = point(fromFocus(el, a, a, 1, CCW), 0); + pair c = locate(el.C); + real d = degrees(p - c) - el.angle; + d = abs(d) < epsgeo ? 0 : d; // Avoid -1e-15 + return d%(sgnd(a) * 360); } -/*<asyxml><function type="real" signature="centerToFocus(ellipse,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "centerToFocus(ellipse, real)"><code></asyxml>*/ real centerToFocus(ellipse el, real a) {/*<asyxml></code><documentation>Return the angle relatively to the focus of 'el' for the angle 'a' given relatively to the center of 'el'.</documentation></function></asyxml>*/ - pair P=point(fromCenter(el,a,a,1,CCW),0); - pair F1=locate(el.F1); - pair F2=locate(el.F2); - real d=degrees(P-F1)-degrees(F2-F1); - d=abs(d) < epsgeo ? 0 : d; // Avoid -1e-15 - return d%(sgnd(a)*360); + pair P = point(fromCenter(el, a, a, 1, CCW), 0); + pair F1 = locate(el.F1); + pair F2 = locate(el.F2); + real d = degrees(P - F1) - degrees(F2 - F1); + d = abs(d) < epsgeo ? 0 : d; // Avoid -1e-15 + return d%(sgnd(a) * 360); } -/*<asyxml><function type="real" signature="arclength(ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(ellipse)"><code></asyxml>*/ real arclength(ellipse el) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return degenerate(el) ? infinity : 4*el.a*elle(pi/2,el.e); + return degenerate(el) ? infinity : 4 * el.a * elle(pi/2, el.e); } -/*<asyxml><function type="real" signature="arclength(ellipse,real,real,bool,polarconicroutine)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(ellipse, real, real, bool, polarconicroutine)"><code></asyxml>*/ real arclength(ellipse el, real angle1, real angle2, - bool direction=CCW, - polarconicroutine polarconicroutine=currentpolarconicroutine) + bool direction = CCW, + polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return the length of the arc of the ellipse between 'angle1' and 'angle2'. - 'angle1' and 'angle2' must be in the interval ]-360;+oo[ if polarconicroutine=fromFocus, - ]-oo;+oo[ if polarconicroutine=fromCenter.</documentation></function></asyxml>*/ + 'angle1' and 'angle2' must be in the interval ]-360;+oo[ if polarconicroutine = fromFocus, + ]-oo;+oo[ if polarconicroutine = fromCenter.</documentation></function></asyxml>*/ if(degenerate(el)) return infinity; - if(angle1 > angle2) return arclength(el,angle2,angle1,!direction,polarconicroutine); - // path g;int n=1000; - // if(el.e == 0) g=arcfromcenter(el,angle1,angle2,n,direction); - // if(el.e != 1) g=polarconicroutine(el,angle1,angle2,n,direction); - // write("with path=",arclength(g)); + if(angle1 > angle2) return arclength(el, angle2, angle1, !direction, polarconicroutine); + // path g;int n = 1000; + // if(el.e == 0) g = arcfromcenter(el, angle1, angle2, n, direction); + // if(el.e != 1) g = polarconicroutine(el, angle1, angle2, n, direction); + // write("with path = ", arclength(g)); if(polarconicroutine == fromFocus) { - // dot(point(fromFocus(el,angle1,angle1,1,CCW),0),2mm+blue); - // dot(point(fromFocus(el,angle2,angle2,1,CCW),0),2mm+blue); - // write("fromfocus1=",angle1); - // write("fromfocus2=",angle2); - real gle1=focusToCenter(el,angle1); - real gle2=focusToCenter(el,angle2); - if((gle1-gle2)*(angle1-angle2) > 0) { - angle1=gle1; angle2=gle2; + // dot(point(fromFocus(el, angle1, angle1, 1, CCW), 0), 2mm + blue); + // dot(point(fromFocus(el, angle2, angle2, 1, CCW), 0), 2mm + blue); + // write("fromfocus1 = ", angle1); + // write("fromfocus2 = ", angle2); + real gle1 = focusToCenter(el, angle1); + real gle2 = focusToCenter(el, angle2); + if((gle1 - gle2) * (angle1 - angle2) > 0) { + angle1 = gle1; angle2 = gle2; } else { - angle1=gle2; angle2=gle1; + angle1 = gle2; angle2 = gle1; } - // dot(point(fromCenter(el,angle1,angle1,1,CCW),0),1mm+red); - // dot(point(fromCenter(el,angle2,angle2,1,CCW),0),1mm+red); - // write("fromcenter1=",angle1); - // write("fromcenter2=",angle2); + // dot(point(fromCenter(el, angle1, angle1, 1, CCW), 0), 1mm + red); + // dot(point(fromCenter(el, angle2, angle2, 1, CCW), 0), 1mm + red); + // write("fromcenter1 = ", angle1); + // write("fromcenter2 = ", angle2); } - if(angle1 < 0 || angle2 < 0) return arclength(el,180+angle1,180+angle2,direction,fromCenter); - real a1=direction ? angle1 : angle2; - real a2=direction ? angle2 : angle1+360; - real elleq=el.a*elle(pi/2,el.e); + if(angle1 < 0 || angle2 < 0) return arclength(el, 180 + angle1, 180 + angle2, direction, fromCenter); + real a1 = direction ? angle1 : angle2; + real a2 = direction ? angle2 : angle1 + 360; + real elleq = el.a * elle(pi/2, el.e); real S(real a) {//Return the arclength from 0 to the angle 'a' (in degrees) // given form the center of the ellipse. - real gle=atan(el.a*Tan(a)/el.b)+ - pi*(((a%90 == 0 && a != 0) ? floor(a/90)-1 : floor(a/90)) - + real gle = atan(el.a * Tan(a)/el.b)+ + pi * (((a%90 == 0 && a != 0) ? floor(a/90) - 1 : floor(a/90)) - ((a%180 == 0) ? 0 : floor(a/180)) - (a%360 == 0 ? floor(a/(360)) : 0)); /* // Uncomment to visualize the used branches - unitsize(2cm,1cm); + unitsize(2cm, 1cm); import graph; - real xmin=0, xmax=3pi; + real xmin = 0, xmax = 3pi; - xlimits( xmin,xmax); - ylimits( 0,10); - yaxis( "y" ,LeftRight(),RightTicks(pTick=.8red,ptick=lightgrey,extend=true)); - xaxis( "x-value",BottomTop(),Ticks(Label("$%.2f$",red),Step=pi/2,step=pi/4,pTick=.8red,ptick=lightgrey,extend=true)); + xlimits( xmin, xmax); + ylimits( 0, 10); + yaxis( "y" , LeftRight(), RightTicks(pTick=.8red, ptick = lightgrey, extend = true)); + xaxis( "x - value", BottomTop(), Ticks(Label("$%.2f$", red), Step = pi/2, step = pi/4, pTick=.8red, ptick = lightgrey, extend = true)); - real p2=pi/2; + real p2 = pi/2; real f(real t) { - return atan(0.6*tan(t))+ - pi*((t%p2 == 0 && t != 0) ? floor(t/p2)-1 : floor(t/p2)) - - ((t%pi == 0) ? 0 : pi*floor(t/pi)) - (t%(2pi) == 0 ? pi*floor(t/(2*pi)) : 0); + return atan(0.6 * tan(t))+ + pi * ((t%p2 == 0 && t != 0) ? floor(t/p2) - 1 : floor(t/p2)) - + ((t%pi == 0) ? 0 : pi * floor(t/pi)) - (t%(2pi) == 0 ? pi * floor(t/(2 * pi)) : 0); } - draw(graph(f,xmin,xmax,100)); + draw(graph(f, xmin, xmax, 100)); write(degrees(f(pi/2))); write(degrees(f(pi))); write(degrees(f(3pi/2))); write(degrees(f(2pi))); - draw(graph(new real(real t){return t;},xmin,xmax,3)); + draw(graph(new real(real t){return t;}, xmin, xmax, 3)); */ - return elleq-el.a*elle(pi/2-gle,el.e); + return elleq - el.a * elle(pi/2 - gle, el.e); } - return S(a2)-S(a1); + return S(a2) - S(a1); } -/*<asyxml><function type="real" signature="arclength(parabola,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(parabola, real)"><code></asyxml>*/ real arclength(parabola p, real angle) {/*<asyxml></code><documentation>Return the arclength from 180 to 'angle' given from focus in the canonical coordinate system of 'p'.</documentation></function></asyxml>*/ - real a=p.a; /* In canonicalcartesiansystem(p) the equation of p - is x=y^2/(4a) */ - // integrate(sqrt(1+(x/(2*a))^2),x); - real S(real t){return 0.5*t*sqrt(1+t^2/(4*a^2))+a*asinh(t/(2*a));} - real R(real gle){return 2*a/(1-Cos(gle));} - real t=Sin(angle)*R(angle); + real a = p.a; /* In canonicalcartesiansystem(p) the equation of p + is x = y^2/(4a) */ + // integrate(sqrt(1 + (x/(2 * a))^2), x); + real S(real t){return 0.5 * t * sqrt(1 + t^2/(4 * a^2)) + a * asinh(t/(2 * a));} + real R(real gle){return 2 * a/(1 - Cos(gle));} + real t = Sin(angle) * R(angle); return S(t); } -/*<asyxml><function type="real" signature="arclength(parabola,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(parabola, real, real)"><code></asyxml>*/ real arclength(parabola p, real angle1, real angle2) {/*<asyxml></code><documentation>Return the arclength from 'angle1' to 'angle2' given from focus in the canonical coordinate system of 'p'</documentation></function></asyxml>*/ - return arclength(p,angle1)-arclength(p,angle2); + return arclength(p, angle1) - arclength(p, angle2); } -/*<asyxml><function type="real" signature="arclength(parabola p)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(parabola p)"><code></asyxml>*/ real arclength(parabola p) {/*<asyxml></code><documentation>Return the length of the arc of the parabola bounded to the bounding box of the current picture.</documentation></function></asyxml>*/ - real[] b=bangles(p); - return arclength(p,b[0],b[1]); + real[] b = bangles(p); + return arclength(p, b[0], b[1]); } // *........................CONICS.........................* // *=======================================================* // *=======================================================* // *.......................ABSCISSA........................* -/*<asyxml><struct signature="abscissa"><code></asyxml>*/ +/*<asyxml><struct signature = "abscissa"><code></asyxml>*/ struct abscissa -{/*<asyxml></code><documentation>Provide abscissa structure on a curve used in the routine-like 'point(object,abscissa)' - where object can be 'line', 'segment', 'ellipse', 'circle', 'conic'...</documentation><property type="real" signature="x"><code></asyxml>*/ - real x;/*<asyxml></code><documentation>The abscissa value.</documentation></property><property type="int" signature="system"><code></asyxml>*/ - int system;/*<asyxml></code><documentation>0=relativesystem; 1=curvilinearsystem; 2=angularsystem; 3=nodesystem</documentation></property><property type="polarconicroutine" signature="polarconicroutine"><code></asyxml>*/ - polarconicroutine polarconicroutine=fromCenter;/*<asyxml></code><documentation>The routine used with angular system and two foci conic section. +{/*<asyxml></code><documentation>Provide abscissa structure on a curve used in the routine-like 'point(object, abscissa)' + where object can be 'line', 'segment', 'ellipse', 'circle', 'conic'...</documentation><property type = "real" signature = "x"><code></asyxml>*/ + real x;/*<asyxml></code><documentation>The abscissa value.</documentation></property><property type = "int" signature = "system"><code></asyxml>*/ + int system;/*<asyxml></code><documentation>0 = relativesystem; 1 = curvilinearsystem; 2 = angularsystem; 3 = nodesystem</documentation></property><property type = "polarconicroutine" signature = "polarconicroutine"><code></asyxml>*/ + polarconicroutine polarconicroutine = fromCenter;/*<asyxml></code><documentation>The routine used with angular system and two foci conic section. Possible values are 'formCenter' and 'formFocus'.</documentation></property></asyxml>*/ - /*<asyxml><method type="abscissa" signature="copy()"><code></asyxml>*/ + /*<asyxml><method type = "abscissa" signature = "copy()"><code></asyxml>*/ abscissa copy() {/*<asyxml></code><documentation>Return a copy of this abscissa.</documentation></method></asyxml>*/ - abscissa oa=new abscissa; - oa.x=this.x; - oa.system=this.system; - oa.polarconicroutine=this.polarconicroutine; + abscissa oa = new abscissa; + oa.x = this.x; + oa.system = this.system; + oa.polarconicroutine = this.polarconicroutine; return oa; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><constant type="int" signature="relativesystem, curvilinearsystem, angularsystem, nodesystem"><code></asyxml>*/ -restricted int relativesystem=0, curvilinearsystem=1, angularsystem=2, nodesystem=3;/*<asyxml></code><documentation>Constant used to set the abscissa system.</documentation></constant></asyxml>*/ +/*<asyxml><constant type = "int" signature = "relativesystem, curvilinearsystem, angularsystem, nodesystem"><code></asyxml>*/ +restricted int relativesystem = 0, curvilinearsystem = 1, angularsystem = 2, nodesystem = 3;/*<asyxml></code><documentation>Constant used to set the abscissa system.</documentation></constant></asyxml>*/ -/*<asyxml><operator type="abscissa" signature="cast(explicit position)"><code></asyxml>*/ +/*<asyxml><operator type = "abscissa" signature = "cast(explicit position)"><code></asyxml>*/ abscissa operator cast(explicit position position) {/*<asyxml></code><documentation>Cast position to abscissa. If 'position' is relative, the abscissa is relative else it's a curvilinear abscissa.</documentation></operator></asyxml>*/ abscissa oarcc; - oarcc.x=position.position.x; - oarcc.system=position.relative ? relativesystem : curvilinearsystem; + oarcc.x = position.position.x; + oarcc.system = position.relative ? relativesystem : curvilinearsystem; return oarcc; } -/*<asyxml><operator type="abscissa" signature="+(real,explicit abscissa)"><code></asyxml>*/ +/*<asyxml><operator type = "abscissa" signature = "+(real, explicit abscissa)"><code></asyxml>*/ abscissa operator +(real x, explicit abscissa a) -{/*<asyxml></code><documentation>Provide 'real+abscissa'. - Return abscissa b so that b.x=a.x+x. - +(explicit abscissa,real), -(real,explicit abscissa) and -(explicit abscissa,real) are also defined.</documentation></operator></asyxml>*/ - abscissa oa=a.copy(); - oa.x=a.x+x; +{/*<asyxml></code><documentation>Provide 'real + abscissa'. + Return abscissa b so that b.x = a.x + x. + +(explicit abscissa, real), -(real, explicit abscissa) and -(explicit abscissa, real) are also defined.</documentation></operator></asyxml>*/ + abscissa oa = a.copy(); + oa.x = a.x + x; return oa; } abscissa operator +(explicit abscissa a, real x) { - return x+a; + return x + a; } abscissa operator +(int x, explicit abscissa a) { - return ((real)x)+a; + return ((real)x) + a; } -/*<asyxml><operator type="abscissa" signature="-(explicit abscissa a)"><code></asyxml>*/ +/*<asyxml><operator type = "abscissa" signature = "-(explicit abscissa a)"><code></asyxml>*/ abscissa operator -(explicit abscissa a) -{/*<asyxml></code><documentation>Return the abscissa b so that b.x=-a.x.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Return the abscissa b so that b.x = -a.x.</documentation></operator></asyxml>*/ abscissa oa; - oa.system=a.system; - oa.x=-a.x; + oa.system = a.system; + oa.x = -a.x; return oa; } abscissa operator -(real x, explicit abscissa a) { abscissa oa; - oa.system=a.system; - oa.x=x-a.x; + oa.system = a.system; + oa.x = x - a.x; return oa; } abscissa operator -(explicit abscissa a, real x) { abscissa oa; - oa.system=a.system; - oa.x=a.x-x; + oa.system = a.system; + oa.x = a.x - x; return oa; } abscissa operator -(int x, explicit abscissa a) { - return ((real)x)-a; + return ((real)x) - a; } -/*<asyxml><operator type="abscissa" signature="*(real,abscissa)"><code></asyxml>*/ +/*<asyxml><operator type = "abscissa" signature = "*(real, abscissa)"><code></asyxml>*/ abscissa operator *(real x, explicit abscissa a) -{/*<asyxml></code><documentation>Provide 'real*abscissa'. - Return abscissa b so that b.x=x*a.x. - *(explicit abscissa,real), /(real,explicit abscissa) and /(explicit abscissa,real) are also defined.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide 'real * abscissa'. + Return abscissa b so that b.x = x * a.x. + *(explicit abscissa, real), /(real, explicit abscissa) and /(explicit abscissa, real) are also defined.</documentation></operator></asyxml>*/ abscissa oa; - oa.system=a.system; - oa.x=a.x*x; + oa.system = a.system; + oa.x = a.x * x; return oa; } abscissa operator *(explicit abscissa a, real x) { - return x*a; + return x * a; } abscissa operator /(real x, explicit abscissa a) { abscissa oa; - oa.system=a.system; - oa.x=x/a.x; + oa.system = a.system; + oa.x = x/a.x; return oa; } abscissa operator /(explicit abscissa a, real x) { abscissa oa; - oa.system=a.system; - oa.x=a.x/x; + oa.system = a.system; + oa.x = a.x/x; return oa; } @@ -4217,7 +4258,7 @@ abscissa operator /(int x, explicit abscissa a) return ((real)x)/a; } -/*<asyxml><function type="abscissa" signature="relabscissa(real)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(real)"><code></asyxml>*/ abscissa relabscissa(real x) {/*<asyxml></code><documentation>Return a relative abscissa.</documentation></function></asyxml>*/ return (abscissa)(Relative(x)); @@ -4227,7 +4268,7 @@ abscissa relabscissa(int x) return (abscissa)(Relative(x)); } -/*<asyxml><function type="abscissa" signature="curabscissa(real)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(real)"><code></asyxml>*/ abscissa curabscissa(real x) {/*<asyxml></code><documentation>Return a curvilinear abscissa.</documentation></function></asyxml>*/ return (abscissa)((position)x); @@ -4237,26 +4278,26 @@ abscissa curabscissa(int x) return (abscissa)((position)x); } -/*<asyxml><function type="abscissa" signature="angabscissa(real,polarconicroutine)"><code></asyxml>*/ -abscissa angabscissa(real x, polarconicroutine polarconicroutine=currentpolarconicroutine) +/*<asyxml><function type = "abscissa" signature = "angabscissa(real, polarconicroutine)"><code></asyxml>*/ +abscissa angabscissa(real x, polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return a angular abscissa.</documentation></function></asyxml>*/ abscissa oarcc; - oarcc.x=x; - oarcc.polarconicroutine=polarconicroutine; - oarcc.system=angularsystem; + oarcc.x = x; + oarcc.polarconicroutine = polarconicroutine; + oarcc.system = angularsystem; return oarcc; } -abscissa angabscissa(int x, polarconicroutine polarconicroutine=currentpolarconicroutine) +abscissa angabscissa(int x, polarconicroutine polarconicroutine = currentpolarconicroutine) { return angabscissa((real)x, polarconicroutine); } -/*<asyxml><function type="abscissa" signature="nodabscissa(real)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(real)"><code></asyxml>*/ abscissa nodabscissa(real x) {/*<asyxml></code><documentation>Return an abscissa as time on the path.</documentation></function></asyxml>*/ abscissa oarcc; - oarcc.x=x; - oarcc.system=nodesystem; + oarcc.x = x; + oarcc.system = nodesystem; return oarcc; } abscissa nodabscissa(int x) @@ -4264,7 +4305,7 @@ abscissa nodabscissa(int x) return nodabscissa((real)x); } -/*<asyxml><operator type="abscissa" signature="cast(real)"><code></asyxml>*/ +/*<asyxml><operator type = "abscissa" signature = "cast(real)"><code></asyxml>*/ abscissa operator cast(real x) {/*<asyxml></code><documentation>Cast real to abscissa, precisely 'nodabscissa'.</documentation></operator></asyxml>*/ return nodabscissa(x); @@ -4274,103 +4315,103 @@ abscissa operator cast(int x) return nodabscissa((real)x); } -/*<asyxml><function type="point" signature="point(circle,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(circle, abscissa)"><code></asyxml>*/ point point(circle c, abscissa l) {/*<asyxml></code><documentation>Return the point of 'c' which has the abscissa 'l.x' according to the abscissa system 'l.system'.</documentation></function></asyxml>*/ - coordsys R=c.C.coordsys; + coordsys R = c.C.coordsys; if (l.system == nodesystem) - return point(R,point((path)c,l.x)/R); + return point(R, point((path)c, l.x)/R); if (l.system == relativesystem) - return c.C+point(R,R.polar(c.r,2*pi*l.x)); + return c.C + point(R, R.polar(c.r, 2 * pi * l.x)); if (l.system == curvilinearsystem) - return c.C+point(R,R.polar(c.r,l.x/c.r)); + return c.C + point(R, R.polar(c.r, l.x/c.r)); if (l.system == angularsystem) - return c.C+point(R,R.polar(c.r,radians(l.x))); + return c.C + point(R, R.polar(c.r, radians(l.x))); abort("point: bad abscissa system."); - return (0,0); + return (0, 0); } -/*<asyxml><function type="point" signature="point(ellipse,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(ellipse, abscissa)"><code></asyxml>*/ point point(ellipse el, abscissa l) {/*<asyxml></code><documentation>Return the point of 'el' which has the abscissa 'l.x' according to the abscissa system 'l.system'.</documentation></function></asyxml>*/ if(el.e == 0) return point((circle)el, l); - coordsys R=coordsys(el); + coordsys R = coordsys(el); if (l.system == nodesystem) - return point(R,point((path)el,l.x)/R); + return point(R, point((path)el, l.x)/R); if (l.system == relativesystem) { - return point(el,curabscissa((l.x%1)*arclength(el))); + return point(el, curabscissa((l.x%1) * arclength(el))); } if (l.system == curvilinearsystem) { - real a1=0, a2=360, cx=0; - real aout=a1; - real x=abs(l.x)%arclength(el); - while (abs(cx-x) > epsgeo) { - aout=(a1+a2)/2; - cx=arclength(el,0,aout,CCW,fromCenter); //fromCenter is speeder - if(cx > x) a2=(a1+a2)/2; else a1=(a1+a2)/2; + real a1 = 0, a2 = 360, cx = 0; + real aout = a1; + real x = abs(l.x)%arclength(el); + while (abs(cx - x) > epsgeo) { + aout = (a1 + a2)/2; + cx = arclength(el, 0, aout, CCW, fromCenter); //fromCenter is speeder + if(cx > x) a2 = (a1 + a2)/2; else a1 = (a1 + a2)/2; } - path pel=fromCenter(el,sgn(l.x)*aout,sgn(l.x)*aout,1,CCW); - return point(R,point(pel,0)/R); + path pel = fromCenter(el, sgn(l.x) * aout, sgn(l.x) * aout, 1, CCW); + return point(R, point(pel, 0)/R); } if (l.system == angularsystem) { - return point(R,point(l.polarconicroutine(el,l.x,l.x,1,CCW),0)/R); + return point(R, point(l.polarconicroutine(el, l.x, l.x, 1, CCW), 0)/R); } abort("point: bad abscissa system."); - return (0,0); + return (0, 0); } -/*<asyxml><function type="point" signature="point(parabola,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(parabola, abscissa)"><code></asyxml>*/ point point(parabola p, abscissa l) {/*<asyxml></code><documentation>Return the point of 'p' which has the abscissa 'l.x' according to the abscissa system 'l.system'.</documentation></function></asyxml>*/ - coordsys R=coordsys(p); + coordsys R = coordsys(p); if (l.system == nodesystem) - return point(R,point((path)p,l.x)/R); + return point(R, point((path)p, l.x)/R); if (l.system == relativesystem) { - real[] b=bangles(p); - real al=sgn(l.x) > 0 ? arclength(p,180,b[1]) : arclength(p,180,b[0]); - return point(p,curabscissa(abs(l.x)*al)); + real[] b = bangles(p); + real al = sgn(l.x) > 0 ? arclength(p, 180, b[1]) : arclength(p, 180, b[0]); + return point(p, curabscissa(abs(l.x) * al)); } if (l.system == curvilinearsystem) { - real a1=1e-3,a2=360-1e-3, cx=infinity; - while (abs(cx-l.x) > epsgeo) { - cx=arclength(p,180,(a1+a2)/2); - if(cx > l.x) a2=(a1+a2)/2; else a1=(a1+a2)/2; + real a1 = 1e-3, a2 = 360 - 1e-3, cx = infinity; + while (abs(cx - l.x) > epsgeo) { + cx = arclength(p, 180, (a1 + a2)/2); + if(cx > l.x) a2 = (a1 + a2)/2; else a1 = (a1 + a2)/2; } - path pp=fromFocus(p,a1,a1,1,CCW); - return point(R,point(pp,0)/R); + path pp = fromFocus(p, a1, a1, 1, CCW); + return point(R, point(pp, 0)/R); } if (l.system == angularsystem) { - return point(R,point(fromFocus(p, l.x, l.x, 1, CCW), 0)/R); + return point(R, point(fromFocus(p, l.x, l.x, 1, CCW), 0)/R); } abort("point: bad abscissa system."); - return (0,0); + return (0, 0); } -/*<asyxml><function type="point" signature="point(hyperbola,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(hyperbola, abscissa)"><code></asyxml>*/ point point(hyperbola h, abscissa l) {/*<asyxml></code><documentation>Return the point of 'h' which has the abscissa 'l.x' according to the abscissa system 'l.system'.</documentation></function></asyxml>*/ - coordsys R=coordsys(h); + coordsys R = coordsys(h); if (l.system == nodesystem) - return point(R,point((path)h,l.x)/R); + return point(R, point((path)h, l.x)/R); if (l.system == relativesystem) { - abort("point(hyperbola,relativeSystem) is not implemented... -Try relpoint((path)your_hyperbola,x);"); + abort("point(hyperbola, relativeSystem) is not implemented... +Try relpoint((path)your_hyperbola, x);"); } if (l.system == curvilinearsystem) { - abort("point(hyperbola,curvilinearSystem) is not implemented..."); + abort("point(hyperbola, curvilinearSystem) is not implemented..."); } if (l.system == angularsystem) { - return point(R,point(l.polarconicroutine(h,l.x,l.x,1,CCW),0)/R); + return point(R, point(l.polarconicroutine(h, l.x, l.x, 1, CCW), 0)/R); } abort("point: bad abscissa system."); - return (0,0); + return (0, 0); } -/*<asyxml><function type="abscissa" signature="point(conic,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "point(conic, point)"><code></asyxml>*/ point point(explicit conic co, abscissa l) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/ if(co.e == 0) return point((circle)co, l); @@ -4380,468 +4421,468 @@ point point(explicit conic co, abscissa l) } -/*<asyxml><function type="point" signature="point(line,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(line, abscissa)"><code></asyxml>*/ point point(line l, abscissa x) {/*<asyxml></code><documentation>Return the point of 'l' which has the abscissa 'l.x' according to the abscissa system 'l.system'. - Note that the origin is l.A, and point(l, relabscissa(x)) returns l.A + x.x*vector(l.B-l.A).</documentation></function></asyxml>*/ - coordsys R=l.A.coordsys; + Note that the origin is l.A, and point(l, relabscissa(x)) returns l.A + x.x * vector(l.B - l.A).</documentation></function></asyxml>*/ + coordsys R = l.A.coordsys; if (x.system == nodesystem) - return l.A+(x.x < 0 ? 0 : x.x > 1 ? 1 : x.x)*vector(l.B-l.A); + return l.A + (x.x < 0 ? 0 : x.x > 1 ? 1 : x.x) * vector(l.B - l.A); if (x.system == relativesystem) - return l.A+x.x*vector(l.B-l.A); + return l.A + x.x * vector(l.B - l.A); if (x.system == curvilinearsystem) - return l.A+x.x*l.u; + return l.A + x.x * l.u; if (x.system == angularsystem) abort("point: what the meaning of angular abscissa on line ?."); abort("point: bad abscissa system."); - return (0,0); + return (0, 0); } -/*<asyxml><function type="point" signature="point(line,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(line, real)"><code></asyxml>*/ point point(line l, explicit real x) {/*<asyxml></code><documentation>Return the point between node l.A and l.B (x <= 0 means l.A, x >=1 means l.B).</documentation></function></asyxml>*/ - return point(l,nodabscissa(x)); + return point(l, nodabscissa(x)); } point point(line l, explicit int x) { - return point(l,nodabscissa(x)); + return point(l, nodabscissa(x)); } -/*<asyxml><function type="circle" signature="point(explicit circle,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "point(explicit circle, explicit real)"><code></asyxml>*/ point point(explicit circle c, explicit real x) -{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/ - return point(c,nodabscissa(x)); +{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/ + return point(c, nodabscissa(x)); } point point(explicit circle c, explicit int x) { - return point(c,nodabscissa(x)); + return point(c, nodabscissa(x)); } -/*<asyxml><function type="point" signature="point(explicit ellipse,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit ellipse, explicit real)"><code></asyxml>*/ point point(explicit ellipse el, explicit real x) -{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/ - return point(el,nodabscissa(x)); +{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/ + return point(el, nodabscissa(x)); } point point(explicit ellipse el, explicit int x) { - return point(el,nodabscissa(x)); + return point(el, nodabscissa(x)); } -/*<asyxml><function type="point" signature="point(explicit parabola,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit parabola, explicit real)"><code></asyxml>*/ point point(explicit parabola p, explicit real x) -{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/ - return point(p,nodabscissa(x)); +{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/ + return point(p, nodabscissa(x)); } point point(explicit parabola p, explicit int x) { - return point(p,nodabscissa(x)); + return point(p, nodabscissa(x)); } -/*<asyxml><function type="point" signature="point(explicit hyperbola,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit hyperbola, explicit real)"><code></asyxml>*/ point point(explicit hyperbola h, explicit real x) -{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/ - return point(h,nodabscissa(x)); +{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/ + return point(h, nodabscissa(x)); } point point(explicit hyperbola h, explicit int x) { - return point(h,nodabscissa(x)); + return point(h, nodabscissa(x)); } -/*<asyxml><function type="point" signature="point(explicit conic,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit conic, explicit real)"><code></asyxml>*/ point point(explicit conic co, explicit real x) -{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x)+1.</documentation></function></asyxml>*/ +{/*<asyxml></code><documentation>Return the point between node floor(x) and floor(x) + 1.</documentation></function></asyxml>*/ point op; - if(co.e == 0) op=point((circle)co,nodabscissa(x)); - else if(co.e < 1) op=point((ellipse)co,nodabscissa(x)); - else if(co.e == 1) op=point((parabola)co,nodabscissa(x)); - else op=point((hyperbola)co,nodabscissa(x)); + if(co.e == 0) op = point((circle)co, nodabscissa(x)); + else if(co.e < 1) op = point((ellipse)co, nodabscissa(x)); + else if(co.e == 1) op = point((parabola)co, nodabscissa(x)); + else op = point((hyperbola)co, nodabscissa(x)); return op; } -point point(explicit conic co,explicit int x) +point point(explicit conic co, explicit int x) { - return point(co,(real)x); + return point(co, (real)x); } -/*<asyxml><function type="point" signature="relpoint(line,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(line, real)"><code></asyxml>*/ point relpoint(line l, real x) {/*<asyxml></code><documentation>Return the relative point of 'l' (0 means l.A, - 1 means l.B, x means l.A+x*vector(l.B-l.A) ).</documentation></function></asyxml>*/ + 1 means l.B, x means l.A + x * vector(l.B - l.A) ).</documentation></function></asyxml>*/ return point(l, Relative(x)); } -/*<asyxml><function type="point" signature="relpoint(explicit circle,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(explicit circle, real)"><code></asyxml>*/ point relpoint(explicit circle c, real x) {/*<asyxml></code><documentation>Return the relative point of 'c' (0 means origin, 1 means end). - Origin is c.center+c.r*(1,0).</documentation></function></asyxml>*/ + Origin is c.center + c.r * (1, 0).</documentation></function></asyxml>*/ return point(c, Relative(x)); } -/*<asyxml><function type="point" signature="relpoint(explicit ellipse,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(explicit ellipse, real)"><code></asyxml>*/ point relpoint(explicit ellipse el, real x) {/*<asyxml></code><documentation>Return the relative point of 'el' (0 means origin, 1 means end).</documentation></function></asyxml>*/ - return point(el,Relative(x)); + return point(el, Relative(x)); } -/*<asyxml><function type="point" signature="relpoint(explicit parabola,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(explicit parabola, real)"><code></asyxml>*/ point relpoint(explicit parabola p, real x) {/*<asyxml></code><documentation>Return the relative point of the path of the parabola bounded by the bounding box of the current picture. 0 means origin, 1 means end, where the origin is the vertex of 'p'.</documentation></function></asyxml>*/ - return point(p,Relative(x)); + return point(p, Relative(x)); } -/*<asyxml><function type="point" signature="relpoint(explicit hyperbola,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(explicit hyperbola, real)"><code></asyxml>*/ point relpoint(explicit hyperbola h, real x) -{/*<asyxml></code><documentation>Not yet implemented... <look href="point(hyperbola,abscissa)"/></documentation></function></asyxml>*/ - return point(h,Relative(x)); +{/*<asyxml></code><documentation>Not yet implemented... <look href = "point(hyperbola, abscissa)"/></documentation></function></asyxml>*/ + return point(h, Relative(x)); } -/*<asyxml><function type="point" signature="relpoint(explicit conic,explicit real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(explicit conic, explicit real)"><code></asyxml>*/ point relpoint(explicit conic co, explicit real x) {/*<asyxml></code><documentation>Return the relative point of 'co' (0 means origin, 1 means end).</documentation></function></asyxml>*/ point op; - if(co.e == 0) op=point((circle)co,Relative(x)); - else if(co.e < 1) op=point((ellipse)co,Relative(x)); - else if(co.e == 1) op=point((parabola)co,Relative(x)); - else op=point((hyperbola)co,Relative(x)); + if(co.e == 0) op = point((circle)co, Relative(x)); + else if(co.e < 1) op = point((ellipse)co, Relative(x)); + else if(co.e == 1) op = point((parabola)co, Relative(x)); + else op = point((hyperbola)co, Relative(x)); return op; } point relpoint(explicit conic co, explicit int x) { - return relpoint(co,(real)x); + return relpoint(co, (real)x); } -/*<asyxml><function type="point" signature="angpoint(explicit circle,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(explicit circle, real)"><code></asyxml>*/ point angpoint(explicit circle c, real x) {/*<asyxml></code><documentation>Return the point of 'c' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/ - return point(c,angabscissa(x)); + return point(c, angabscissa(x)); } -/*<asyxml><function type="point" signature="angpoint(explicit ellipse,real,polarconicroutine)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(explicit ellipse, real, polarconicroutine)"><code></asyxml>*/ point angpoint(explicit ellipse el, real x, - polarconicroutine polarconicroutine=currentpolarconicroutine) + polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return the point of 'el' in the direction 'x' measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/ - return el.e == 0 ? angpoint((circle) el, x) : point(el,angabscissa(x,polarconicroutine)); + return el.e == 0 ? angpoint((circle) el, x) : point(el, angabscissa(x, polarconicroutine)); } -/*<asyxml><function type="point" signature="angpoint(explicit parabola,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(explicit parabola, real)"><code></asyxml>*/ point angpoint(explicit parabola p, real x) {/*<asyxml></code><documentation>Return the point of 'p' in the direction 'x' measured in degrees.</documentation></function></asyxml>*/ - return point(p,angabscissa(x)); + return point(p, angabscissa(x)); } -/*<asyxml><function type="point" signature="angpoint(explicit hyperbola,real,polarconicroutine)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(explicit hyperbola, real, polarconicroutine)"><code></asyxml>*/ point angpoint(explicit hyperbola h, real x, - polarconicroutine polarconicroutine=currentpolarconicroutine) + polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return the point of 'h' in the direction 'x' measured in degrees according to 'polarconicroutine'.</documentation></function></asyxml>*/ - return point(h,angabscissa(x,polarconicroutine)); + return point(h, angabscissa(x, polarconicroutine)); } -/*<asyxml><function type="point" signature="curpoint(line,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(line, real)"><code></asyxml>*/ point curpoint(line l, real x) {/*<asyxml></code><documentation>Return the point of 'l' which has the curvilinear abscissa 'x'. Origin is l.A.</documentation></function></asyxml>*/ return point(l, curabscissa(x)); } -/*<asyxml><function type="point" signature="curpoint(explicit circle,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(explicit circle, real)"><code></asyxml>*/ point curpoint(explicit circle c, real x) {/*<asyxml></code><documentation>Return the point of 'c' which has the curvilinear abscissa 'x'. - Origin is c.center+c.r*(1,0).</documentation></function></asyxml>*/ + Origin is c.center + c.r * (1, 0).</documentation></function></asyxml>*/ return point(c, curabscissa(x)); } -/*<asyxml><function type="point" signature="curpoint(explicit ellipse,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(explicit ellipse, real)"><code></asyxml>*/ point curpoint(explicit ellipse el, real x) {/*<asyxml></code><documentation>Return the point of 'el' which has the curvilinear abscissa 'el'.</documentation></function></asyxml>*/ - return point(el,curabscissa(x)); + return point(el, curabscissa(x)); } -/*<asyxml><function type="point" signature="curpoint(explicit parabola,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(explicit parabola, real)"><code></asyxml>*/ point curpoint(explicit parabola p, real x) {/*<asyxml></code><documentation>Return the point of 'p' which has the curvilinear abscissa 'x'. Origin is the vertex of 'p'.</documentation></function></asyxml>*/ - return point(p,curabscissa(x)); + return point(p, curabscissa(x)); } -/*<asyxml><function type="point" signature="curpoint(conic,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(conic, real)"><code></asyxml>*/ point curpoint(conic co, real x) {/*<asyxml></code><documentation>Return the point of 'co' which has the curvilinear abscissa 'x'.</documentation></function></asyxml>*/ point op; - if(co.e == 0) op=point((circle)co,curabscissa(x)); - else if(co.e < 1) op=point((ellipse)co,curabscissa(x)); - else if(co.e == 1) op=point((parabola)co,curabscissa(x)); - else op=point((hyperbola)co,curabscissa(x)); + if(co.e == 0) op = point((circle)co, curabscissa(x)); + else if(co.e < 1) op = point((ellipse)co, curabscissa(x)); + else if(co.e == 1) op = point((parabola)co, curabscissa(x)); + else op = point((hyperbola)co, curabscissa(x)); return op; } -/*<asyxml><function type="abscissa" signature="angabscissa(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(circle, point)"><code></asyxml>*/ abscissa angabscissa(circle c, point M) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/ if(!(M @ c)) abort("angabscissa: the point is not on the circle."); abscissa oa; - oa.system=angularsystem; - oa.x=degrees(M-c.C); + oa.system = angularsystem; + oa.x = degrees(M - c.C); if(oa.x < 0) oa.x+=360; return oa; } -/*<asyxml><function type="abscissa" signature="angabscissa(ellipse,point,polarconicroutine)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(ellipse, point, polarconicroutine)"><code></asyxml>*/ abscissa angabscissa(ellipse el, point M, - polarconicroutine polarconicroutine=currentpolarconicroutine) + polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the ellipse 'el' according to 'polarconicroutine'.</documentation></function></asyxml>*/ if(!(M @ el)) abort("angabscissa: the point is not on the ellipse."); abscissa oa; - oa.system=angularsystem; - oa.polarconicroutine=polarconicroutine; - oa.x=polarconicroutine == fromCenter ? degrees(M-el.C) : degrees(M-el.F1); + oa.system = angularsystem; + oa.polarconicroutine = polarconicroutine; + oa.x = polarconicroutine == fromCenter ? degrees(M - el.C) : degrees(M - el.F1); oa.x -= el.angle; if(oa.x < 0) oa.x += 360; return oa; } -/*<asyxml><function type="abscissa" signature="angabscissa(hyperbola,point,polarconicroutine)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(hyperbola, point, polarconicroutine)"><code></asyxml>*/ abscissa angabscissa(hyperbola h, point M, - polarconicroutine polarconicroutine=currentpolarconicroutine) + polarconicroutine polarconicroutine = currentpolarconicroutine) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the hyperbola 'h' according to 'polarconicroutine'.</documentation></function></asyxml>*/ if(!(M @ h)) abort("angabscissa: the point is not on the hyperbola."); abscissa oa; - oa.system=angularsystem; - oa.polarconicroutine=polarconicroutine; - oa.x=polarconicroutine == fromCenter ? degrees(M-h.C) : degrees(M-h.F1)+180; + oa.system = angularsystem; + oa.polarconicroutine = polarconicroutine; + oa.x = polarconicroutine == fromCenter ? degrees(M - h.C) : degrees(M - h.F1) + 180; oa.x -= h.angle; if(oa.x < 0) oa.x += 360; return oa; } -/*<asyxml><function type="abscissa" signature="angabscissa(parabola,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(parabola, point)"><code></asyxml>*/ abscissa angabscissa(parabola p, point M) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/ if(!(M @ p)) abort("angabscissa: the point is not on the parabola."); abscissa oa; - oa.system=angularsystem; - oa.polarconicroutine=fromFocus;// Not used - oa.x=degrees(M-p.F); + oa.system = angularsystem; + oa.polarconicroutine = fromFocus;// Not used + oa.x = degrees(M - p.F); oa.x -= p.angle; if(oa.x < 0) oa.x += 360; return oa; } -/*<asyxml><function type="abscissa" signature="angabscissa(conic,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(conic, point)"><code></asyxml>*/ abscissa angabscissa(explicit conic co, point M) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/ - if(co.e == 0) return angabscissa((circle)co,M); - if(co.e < 1) return angabscissa((ellipse)co,M); - if(co.e == 1) return angabscissa((parabola)co,M); - return angabscissa((hyperbola)co,M); + if(co.e == 0) return angabscissa((circle)co, M); + if(co.e < 1) return angabscissa((ellipse)co, M); + if(co.e == 1) return angabscissa((parabola)co, M); + return angabscissa((hyperbola)co, M); } -/*<asyxml><function type="abscissa" signature="curabscissa(line,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(line, point)"><code></asyxml>*/ abscissa curabscissa(line l, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/ if(!(M @ extend(l))) abort("curabscissa: the point is not on the line."); abscissa oa; - oa.system=curvilinearsystem; - oa.x=sgn(dot(M-l.A, l.B-l.A))*abs(M-l.A); + oa.system = curvilinearsystem; + oa.x = sgn(dot(M - l.A, l.B - l.A)) * abs(M - l.A); return oa; } -/*<asyxml><function type="abscissa" signature="curabscissa(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(circle, point)"><code></asyxml>*/ abscissa curabscissa(circle c, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/ if(!(M @ c)) abort("curabscissa: the point is not on the circle."); abscissa oa; - oa.system=curvilinearsystem; - oa.x=pi*angabscissa(c,M).x*c.r/180; + oa.system = curvilinearsystem; + oa.x = pi * angabscissa(c, M).x * c.r/180; return oa; } -/*<asyxml><function type="abscissa" signature="curabscissa(ellipse,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(ellipse, point)"><code></asyxml>*/ abscissa curabscissa(ellipse el, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/ if(!(M @ el)) abort("curabscissa: the point is not on the ellipse."); abscissa oa; - oa.system=curvilinearsystem; - real a=angabscissa(el,M,fromCenter).x; - oa.x=arclength(el,0,a,fromCenter); - oa.polarconicroutine=fromCenter; + oa.system = curvilinearsystem; + real a = angabscissa(el, M, fromCenter).x; + oa.x = arclength(el, 0, a, fromCenter); + oa.polarconicroutine = fromCenter; return oa; } -/*<asyxml><function type="abscissa" signature="curabscissa(parabola,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(parabola, point)"><code></asyxml>*/ abscissa curabscissa(parabola p, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the parabola 'p'.</documentation></function></asyxml>*/ if(!(M @ p)) abort("curabscissa: the point is not on the parabola."); abscissa oa; - oa.system=curvilinearsystem; - real a=angabscissa(p,M).x; - oa.x=arclength(p,180,a); - oa.polarconicroutine=fromFocus; // Not used. + oa.system = curvilinearsystem; + real a = angabscissa(p, M).x; + oa.x = arclength(p, 180, a); + oa.polarconicroutine = fromFocus; // Not used. return oa; } -/*<asyxml><function type="abscissa" signature="curabscissa(conic,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(conic, point)"><code></asyxml>*/ abscissa curabscissa(conic co, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/ if(co.e > 1) abort("curabscissa: not implemented for this hyperbola."); - if(co.e == 0) return curabscissa((circle)co,M); - if(co.e < 1) return curabscissa((ellipse)co,M); - return curabscissa((parabola)co,M); + if(co.e == 0) return curabscissa((circle)co, M); + if(co.e < 1) return curabscissa((ellipse)co, M); + return curabscissa((parabola)co, M); } -/*<asyxml><function type="abscissa" signature="nodabscissa(line,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(line, point)"><code></asyxml>*/ abscissa nodabscissa(line l, point M) {/*<asyxml></code><documentation>Return the node abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/ if(!(M @ (segment)l)) abort("nodabscissa: the point is not on the segment."); abscissa oa; - oa.system=nodesystem; - oa.x=abs(M-l.A)/abs(l.A-l.B); + oa.system = nodesystem; + oa.x = abs(M - l.A)/abs(l.A - l.B); return oa; } -/*<asyxml><function type="abscissa" signature="nodabscissa(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(circle, point)"><code></asyxml>*/ abscissa nodabscissa(circle c, point M) {/*<asyxml></code><documentation>Return the node abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/ if(!(M @ c)) abort("nodabscissa: the point is not on the circle."); abscissa oa; - oa.system=nodesystem; - oa.x=intersect((path)c,locate(M))[0]; + oa.system = nodesystem; + oa.x = intersect((path)c, locate(M))[0]; return oa; } -/*<asyxml><function type="abscissa" signature="nodabscissa(ellipse,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(ellipse, point)"><code></asyxml>*/ abscissa nodabscissa(ellipse el, point M) {/*<asyxml></code><documentation>Return the node abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/ if(!(M @ el)) abort("nodabscissa: the point is not on the ellipse."); abscissa oa; - oa.system=nodesystem; - oa.x=intersect((path)el,M)[0]; + oa.system = nodesystem; + oa.x = intersect((path)el, M)[0]; return oa; } -/*<asyxml><function type="abscissa" signature="nodabscissa(parabola,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(parabola, point)"><code></asyxml>*/ abscissa nodabscissa(parabola p, point M) {/*<asyxml></code><documentation>Return the node abscissa OF 'M' on the parabola 'p'.</documentation></function></asyxml>*/ if(!(M @ p)) abort("nodabscissa: the point is not on the parabola."); abscissa oa; - oa.system=nodesystem; - path pg=p; - real[] t=intersect(pg,M,1e-5); + oa.system = nodesystem; + path pg = p; + real[] t = intersect(pg, M, 1e-5); if(t.length == 0) abort("nodabscissa: the point is not on the path of the parabola."); - oa.x=t[0]; + oa.x = t[0]; return oa; } -/*<asyxml><function type="abscissa" signature="nodabscissa(conic,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(conic, point)"><code></asyxml>*/ abscissa nodabscissa(conic co, point M) {/*<asyxml></code><documentation>Return the node abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/ if(co.e > 1) abort("nodabscissa: not implemented for hyperbola."); - if(co.e == 0) return nodabscissa((circle)co,M); - if(co.e < 1) return nodabscissa((ellipse)co,M); - return nodabscissa((parabola)co,M); + if(co.e == 0) return nodabscissa((circle)co, M); + if(co.e < 1) return nodabscissa((ellipse)co, M); + return nodabscissa((parabola)co, M); } -/*<asyxml><function type="abscissa" signature="relabscissa(line,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(line, point)"><code></asyxml>*/ abscissa relabscissa(line l, point M) {/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the line 'l'.</documentation></function></asyxml>*/ if(!(M @ extend(l))) abort("relabscissa: the point is not on the line."); abscissa oa; - oa.system=relativesystem; - oa.x=sgn(dot(M-l.A, l.B-l.A))*abs(M-l.A)/abs(l.A-l.B); + oa.system = relativesystem; + oa.x = sgn(dot(M - l.A, l.B - l.A)) * abs(M - l.A)/abs(l.A - l.B); return oa; } -/*<asyxml><function type="abscissa" signature="relabscissa(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(circle, point)"><code></asyxml>*/ abscissa relabscissa(circle c, point M) {/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the circle 'c'.</documentation></function></asyxml>*/ if(!(M @ c)) abort("relabscissa: the point is not on the circle."); abscissa oa; - oa.system=relativesystem; - oa.x=angabscissa(c,M).x/360; + oa.system = relativesystem; + oa.x = angabscissa(c, M).x/360; return oa; } -/*<asyxml><function type="abscissa" signature="relabscissa(ellipse,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(ellipse, point)"><code></asyxml>*/ abscissa relabscissa(ellipse el, point M) {/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the ellipse 'el'.</documentation></function></asyxml>*/ if(!(M @ el)) abort("relabscissa: the point is not on the ellipse."); abscissa oa; - oa.system=relativesystem; - oa.x=curabscissa(el,M).x/arclength(el); - oa.polarconicroutine=fromFocus; + oa.system = relativesystem; + oa.x = curabscissa(el, M).x/arclength(el); + oa.polarconicroutine = fromFocus; return oa; } -/*<asyxml><function type="abscissa" signature="relabscissa(conic,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(conic, point)"><code></asyxml>*/ abscissa relabscissa(conic co, point M) {/*<asyxml></code><documentation>Return the relative abscissa of 'M' on the conic 'co'.</documentation></function></asyxml>*/ write("PASS"); if(co.e > 1) abort("relabscissa: not implemented for hyperbola and parabola."); - if(co.e == 1) return relabscissa((parabola)co,M); - if(co.e == 0) return relabscissa((circle)co,M); - return relabscissa((ellipse)co,M); + if(co.e == 1) return relabscissa((parabola)co, M); + if(co.e == 0) return relabscissa((circle)co, M); + return relabscissa((ellipse)co, M); } // *.......................ABSCISSA........................* // *=======================================================* // *=======================================================* // *.........................ARCS..........................* -/*<asyxml><struct signature="arc"><code></asyxml>*/ +/*<asyxml><struct signature = "arc"><code></asyxml>*/ struct arc { /*<asyxml></code><documentation>Implement oriented ellipse (included circle) arcs. All the calculus with this structure will be as exact as Asymptote can do. For a full precision, you must not cast 'arc' to 'path' excepted for drawing routines. - </documentation><property type="ellipse" signature="el"><code></asyxml>*/ - ellipse el;/*<asyxml></code><documentation>The support of the arc.</documentation></property><property type="real" signature="angle0"><code></asyxml>*/ - restricted real angle0=0;/*<asyxml></code><documentation>Internal use: rotating a circle does not modify the origin point, this variable stocks the eventual angle rotation. This value is not used for ellipses which are not circles.</documentation></property><property type="real" signature="angle1,angle2"><code></asyxml>*/ - restricted real angle1, angle2;/*<asyxml></code><documentation>Values (in degrees) in ]-360,360[.</documentation></property><property type="bool" signature="direction"><code></asyxml>*/ - bool direction=CCW;/*<asyxml></code><documentation>The arc will be drawn from 'angle1' to 'angle2' rotating in the direction 'direction'.</documentation></property><property type="polarconicroutine" signature="polarconicroutine"><code></asyxml>*/ - polarconicroutine polarconicroutine=currentpolarconicroutine;/*<asyxml></code><documentation>The routine to which the angles refer. + </documentation><property type = "ellipse" signature = "el"><code></asyxml>*/ + ellipse el;/*<asyxml></code><documentation>The support of the arc.</documentation></property><property type = "real" signature = "angle0"><code></asyxml>*/ + restricted real angle0 = 0;/*<asyxml></code><documentation>Internal use: rotating a circle does not modify the origin point, this variable stocks the eventual angle rotation. This value is not used for ellipses which are not circles.</documentation></property><property type = "real" signature = "angle1, angle2"><code></asyxml>*/ + restricted real angle1, angle2;/*<asyxml></code><documentation>Values (in degrees) in ]-360, 360[.</documentation></property><property type = "bool" signature = "direction"><code></asyxml>*/ + bool direction = CCW;/*<asyxml></code><documentation>The arc will be drawn from 'angle1' to 'angle2' rotating in the direction 'direction'.</documentation></property><property type = "polarconicroutine" signature = "polarconicroutine"><code></asyxml>*/ + polarconicroutine polarconicroutine = currentpolarconicroutine;/*<asyxml></code><documentation>The routine to which the angles refer. If 'el' is a circle 'fromCenter' is always used.</documentation></property></asyxml>*/ - /*<asyxml><method type="void" signature="setangles(real,real,real)"><code></asyxml>*/ + /*<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); + this.angle0 = a0%(sgnd(a0) * 360); + this.angle1 = a1%(sgnd(a1) * 360); + this.angle2 = a2%(sgnd(2) * 360); } - /*<asyxml><method type="void" signature="init(ellipse,real,real,real,polarconicroutine,bool)"><code></asyxml>*/ - void init(ellipse el, real angle0=0, real angle1, real angle2, + /*<asyxml><method type = "void" signature = "init(ellipse, real, real, real, polarconicroutine, bool)"><code></asyxml>*/ + void init(ellipse el, real angle0 = 0, real angle1, real angle2, polarconicroutine polarconicroutine, - bool direction=CCW) + bool direction = CCW) {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/ - if(abs(angle1-angle2) > 360) abort("arc: |angle1-angle2| > 360."); - this.el=el; + if(abs(angle1 - angle2) > 360) abort("arc: |angle1 - angle2| > 360."); + this.el = el; this.setangles(angle0, angle1, angle2); - this.polarconicroutine=polarconicroutine; - this.direction=direction; + this.polarconicroutine = polarconicroutine; + this.direction = direction; } - /*<asyxml><method type="arc" signature="copy()"><code></asyxml>*/ + /*<asyxml><method type = "arc" signature = "copy()"><code></asyxml>*/ arc copy() {/*<asyxml></code><documentation>Copy the arc.</documentation></method></asyxml>*/ - arc oa=new arc; - oa.el=this.el; - oa.direction=this.direction; - oa.polarconicroutine=this.polarconicroutine; - oa.angle1=this.angle1; - oa.angle2=this.angle2; - oa.angle0=this.angle0; + arc oa = new arc; + oa.el = this.el; + oa.direction = this.direction; + oa.polarconicroutine = this.polarconicroutine; + oa.angle1 = this.angle1; + oa.angle2 = this.angle2; + oa.angle0 = this.angle0; return oa; } }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="polarconicroutine" signature="polarconicroutine(ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "polarconicroutine" signature = "polarconicroutine(ellipse)"><code></asyxml>*/ polarconicroutine polarconicroutine(conic co) {/*<asyxml></code><documentation>Return the default routine used to draw a conic.</documentation></function></asyxml>*/ if(co.e == 0) return fromCenter; @@ -4849,173 +4890,173 @@ polarconicroutine polarconicroutine(conic co) return currentpolarconicroutine; } -/*<asyxml><function type="arc" signature="arc(ellipse,real,real,polarconicroutine,bool)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "arc(ellipse, real, real, polarconicroutine, bool)"><code></asyxml>*/ arc arc(ellipse el, real angle1, real angle2, - polarconicroutine polarconicroutine=polarconicroutine(el), - bool direction=CCW) + polarconicroutine polarconicroutine = polarconicroutine(el), + bool direction = CCW) {/*<asyxml></code><documentation>Return the ellipse arc from 'angle1' to 'angle2' with respect to 'polarconicroutine' and rotating in the direction 'direction'.</documentation></function></asyxml>*/ arc oa; - oa.init(el,0,angle1,angle2,polarconicroutine,direction); + oa.init(el, 0, angle1, angle2, polarconicroutine, direction); return oa; } -/*<asyxml><function type="arc" signature="complementary(arc)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "complementary(arc)"><code></asyxml>*/ arc complementary(arc a) {/*<asyxml></code><documentation>Return the complementary of 'a'.</documentation></function></asyxml>*/ arc oa; - oa.init(a.el,a.angle0,a.angle2,a.angle1,a.polarconicroutine,a.direction); + oa.init(a.el, a.angle0, a.angle2, a.angle1, a.polarconicroutine, a.direction); return oa; } -/*<asyxml><function type="arc" signature="reverse(arc)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "reverse(arc)"><code></asyxml>*/ arc reverse(arc a) {/*<asyxml></code><documentation>Return arc 'a' oriented in reverse direction.</documentation></function></asyxml>*/ arc oa; - oa.init(a.el,a.angle0,a.angle2,a.angle1,a.polarconicroutine,!a.direction); + oa.init(a.el, a.angle0, a.angle2, a.angle1, a.polarconicroutine, !a.direction); return oa; } -/*<asyxml><function type="real" signature="degrees(arc)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "degrees(arc)"><code></asyxml>*/ real degrees(arc a) {/*<asyxml></code><documentation>Return the measure in degrees of the oriented arc 'a'.</documentation></function></asyxml>*/ real or; - real da=a.angle2-a.angle1; + real da = a.angle2 - a.angle1; if(a.direction) { - or=a.angle1 < a.angle2 ? da : 360+da; + or = a.angle1 < a.angle2 ? da : 360 + da; } else { - or=a.angle1 < a.angle2 ? -360+da : da; + or = a.angle1 < a.angle2 ? -360 + da : da; } return or; } -/*<asyxml><function type="real" signature="angle(a)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "angle(a)"><code></asyxml>*/ real angle(arc a) {/*<asyxml></code><documentation>Return the measure in radians of the oriented arc 'a'.</documentation></function></asyxml>*/ return radians(degrees(a)); } -/*<asyxml><function type="int" signature="arcnodesnumber(explicit arc)"><code></asyxml>*/ +/*<asyxml><function type = "int" signature = "arcnodesnumber(explicit arc)"><code></asyxml>*/ int arcnodesnumber(explicit arc a) {/*<asyxml></code><documentation>Return the number of nodes to draw the arc 'a'.</documentation></function></asyxml>*/ - return ellipsenodesnumber(a.el.a,a.el.b,a.angle1,a.angle2,a.direction); + return ellipsenodesnumber(a.el.a, a.el.b, a.angle1, a.angle2, a.direction); } private path arctopath(arc a, int n) { - if(a.el.e == 0) return arcfromcenter(a.el,a.angle0+a.angle1,a.angle0+a.angle2,a.direction,n); - if(a.el.e != 1) return a.polarconicroutine(a.el,a.angle1,a.angle2,n,a.direction); - return arcfromfocus(a.el,a.angle1,a.angle2,n,a.direction); + if(a.el.e == 0) return arcfromcenter(a.el, a.angle0 + a.angle1, a.angle0 + a.angle2, a.direction, n); + if(a.el.e != 1) return a.polarconicroutine(a.el, a.angle1, a.angle2, n, a.direction); + return arcfromfocus(a.el, a.angle1, a.angle2, n, a.direction); } -/*<asyxml><function type="point" signature="angpoint(arc,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "angpoint(arc, real)"><code></asyxml>*/ point angpoint(arc a, real angle) {/*<asyxml></code><documentation>Return the point given by its angular position (in degrees) relative to the arc 'a'. If 'angle > degrees(a)' or 'angle < 0' the returned point is on the extended arc.</documentation></function></asyxml>*/ pair p; if(a.el.e == 0) { - real gle=a.angle0+a.angle1+(a.direction ? angle : -angle); - p=point(arcfromcenter(a.el,gle,gle,CCW,1),0); + real gle = a.angle0 + a.angle1 + (a.direction ? angle : -angle); + p = point(arcfromcenter(a.el, gle, gle, CCW, 1), 0); } else { - real gle=a.angle1+(a.direction ? angle : -angle); - p=point(a.polarconicroutine(a.el,gle,gle,1,CCW),0); + real gle = a.angle1 + (a.direction ? angle : -angle); + p = point(a.polarconicroutine(a.el, gle, gle, 1, CCW), 0); } - return point(coordsys(a.el),p/coordsys(a.el)); + return point(coordsys(a.el), p/coordsys(a.el)); } -/*<asyxml><operator type="path" signature="cast(explicit arc)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(explicit arc)"><code></asyxml>*/ path operator cast(explicit arc a) {/*<asyxml></code><documentation>Cast arc to path.</documentation></operator></asyxml>*/ - return arctopath(a,arcnodesnumber(a)); + return arctopath(a, arcnodesnumber(a)); } -/*<asyxml><operator type="guide" signature="cast(explicit arc)"><code></asyxml>*/ +/*<asyxml><operator type = "guide" signature = "cast(explicit arc)"><code></asyxml>*/ guide operator cast(explicit arc a) {/*<asyxml></code><documentation>Cast arc to guide.</documentation></operator></asyxml>*/ - return arctopath(a,arcnodesnumber(a)); + return arctopath(a, arcnodesnumber(a)); } -/*<asyxml><operator type="arc" signature="*(transform,explicit arc)"><code></asyxml>*/ +/*<asyxml><operator type = "arc" signature = "*(transform, explicit arc)"><code></asyxml>*/ arc operator *(transform t, explicit arc a) -{/*<asyxml></code><documentation>Provide transform*arc.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide transform * arc.</documentation></operator></asyxml>*/ pair[] P, PP; - path g=arctopath(a,3); - real a0, a1=a.angle1, a2=a.angle2, ap1, ap2; - bool dir=a.direction; - P[0]=t*point(g,0); - P[1]=t*point(g,2); - ellipse el=t*a.el; + path g = arctopath(a, 3); + real a0, a1 = a.angle1, a2 = a.angle2, ap1, ap2; + bool dir = a.direction; + P[0] = t * point(g, 0); + P[1] = t * point(g, 2); + ellipse el = t * a.el; arc oa; - a0=(a.angle0+angle(shiftless(t)))%360; + a0 = (a.angle0 + angle(shiftless(t)))%360; pair C; - if(a.polarconicroutine == fromCenter) C=el.C; else C=el.F1; - real d=abs(locate(el.F2-el.F1)) > epsgeo ? - degrees(locate(el.F2-el.F1)) : a0+degrees(el.C.coordsys.i); - ap1=(degrees(P[0]-C,false)-d)%360; - ap2=(degrees(P[1]-C,false)-d)%360; - oa.init(el,a0,ap1,ap2,a.polarconicroutine,dir); - g=arctopath(oa,3); - PP[0]=point(g,0); - PP[1]=point(g,2); - if((a1-a2)*(ap1-ap2) < 0) {// Handle reflection. + if(a.polarconicroutine == fromCenter) C = el.C; else C = el.F1; + real d = abs(locate(el.F2 - el.F1)) > epsgeo ? + degrees(locate(el.F2 - el.F1)) : a0 + degrees(el.C.coordsys.i); + ap1 = (degrees(P[0]-C, false) - d)%360; + ap2 = (degrees(P[1]-C, false) - d)%360; + oa.init(el, a0, ap1, ap2, a.polarconicroutine, dir); + g = arctopath(oa, 3); + PP[0] = point(g, 0); + PP[1] = point(g, 2); + if((a1 - a2) * (ap1 - ap2) < 0) {// Handle reflection. dir=!a.direction; - oa.init(el,a0,ap1,ap2,a.polarconicroutine,dir); + oa.init(el, a0, ap1, ap2, a.polarconicroutine, dir); } return oa; } -/*<asyxml><operator type="arc" signature="*(real,explicit arc)"><code></asyxml>*/ +/*<asyxml><operator type = "arc" signature = "*(real, explicit arc)"><code></asyxml>*/ arc operator *(real x, explicit arc a) -{/*<asyxml></code><documentation>Provide real*arc. - Return the arc subtracting and adding '(x-1)*degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/ +{/*<asyxml></code><documentation>Provide real * arc. + Return the arc subtracting and adding '(x - 1) * degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/ real a1, a2, gle; - gle=(x-1)*degrees(a)/2; - a1=a.angle1-gle; - a2=a.angle2+gle; + gle = (x - 1) * degrees(a)/2; + a1 = a.angle1 - gle; + a2 = a.angle2 + gle; arc oa; - oa.init(a.el,a.angle0,a1,a2,a.polarconicroutine,a.direction); + oa.init(a.el, a.angle0, a1, a2, a.polarconicroutine, a.direction); return oa; } -arc operator *(int x, explicit arc a){return (real)x*a;} -/*<asyxml><operator type="arc" signature="/(real,explicit arc)"><code></asyxml>*/ +arc operator *(int x, explicit arc a){return (real)x * a;} +/*<asyxml><operator type = "arc" signature = "/(real, explicit arc)"><code></asyxml>*/ arc operator /(explicit arc a, real x) {/*<asyxml></code><documentation>Provide arc/real. - Return the arc subtracting and adding '(1/x-1)*degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/ - return (1/x)*a; + Return the arc subtracting and adding '(1/x - 1) * degrees(a)/2' to 'a.angle1' and 'a.angle2' respectively.</documentation></operator></asyxml>*/ + return (1/x) * a; } -/*<asyxml><operator type="arc" signature="+(explicit arc,point)"><code></asyxml>*/ +/*<asyxml><operator type = "arc" signature = "+(explicit arc, point)"><code></asyxml>*/ arc operator +(explicit arc a, point M) -{/*<asyxml></code><documentation>Provide arc+point. +{/*<asyxml></code><documentation>Provide arc + point. Return shifted arc. - 'operator +(explicit arc,point)', 'operator +(explicit arc,vector)' and 'operator -(explicit arc,vector)' are also defined.</documentation></operator></asyxml>*/ - return shift(M)*a; + 'operator +(explicit arc, point)', 'operator +(explicit arc, vector)' and 'operator -(explicit arc, vector)' are also defined.</documentation></operator></asyxml>*/ + return shift(M) * a; } -arc operator -(explicit arc a, point M){return a+(-M);} -arc operator +(explicit arc a, vector v){return shift(locate(v))*a;} -arc operator -(explicit arc a, vector v){return a+(-v);} +arc operator -(explicit arc a, point M){return a + (-M);} +arc operator +(explicit arc a, vector v){return shift(locate(v)) * a;} +arc operator -(explicit arc a, vector v){return a + (-v);} -/*<asyxml><operator type="bool" signature="@(point,arc)"><code></asyxml>*/ +/*<asyxml><operator type = "bool" signature = "@(point, arc)"><code></asyxml>*/ bool operator @(point M, arc a) {/*<asyxml></code><documentation>Return true iff 'M' is on the arc 'a'.</documentation></operator></asyxml>*/ if (!(M @ a.el)) return false; - coordsys R=defaultcoordsys; - path ap=arctopath(a,3); - line l=line(point(R,point(ap,0)),point(R,point(ap,2))); - return sameside(M, point(R,point(ap,1)), l); + coordsys R = defaultcoordsys; + path ap = arctopath(a, 3); + line l = line(point(R, point(ap, 0)), point(R, point(ap, 2))); + return sameside(M, point(R, point(ap, 1)), l); } -/*<asyxml><function type="void" signature="draw(picture,Label,arc,align,pen,arrowbar,arrowbar,margin,Label,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, Label L="", arc a, - align align=NoAlign, pen p=currentpen, - arrowbar arrow=None, arrowbar bar=None, margin margin=NoMargin, - Label legend="", marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, Label, arc, align, pen, arrowbar, arrowbar, margin, Label, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, Label L = "", arc a, + align align = NoAlign, pen p = currentpen, + arrowbar arrow = None, arrowbar bar = None, margin margin = NoMargin, + Label legend = "", marker marker = nomarker) {/*<asyxml></code><documentation>Draw 'arc' adding the pen returned by 'addpenarc(p)' to the pen 'p'. - <look href="#addpenarc"/></documentation></function></asyxml>*/ - draw(pic,L,(path)a,align,addpenarc(p),arrow,bar,margin,legend,marker); + <look href = "#addpenarc"/></documentation></function></asyxml>*/ + draw(pic, L, (path)a, align, addpenarc(p), arrow, bar, margin, legend, marker); } -/*<asyxml><function type="real" signature="arclength(arc)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "arclength(arc)"><code></asyxml>*/ real arclength(arc a) {/*<asyxml></code><documentation>The arc length of 'a'.</documentation></function></asyxml>*/ return arclength(a.el, a.angle1, a.angle2, a.direction, a.polarconicroutine); @@ -5025,101 +5066,101 @@ private point ppoint(arc a, real x) {// Return the point of the arc proportionally to its length. point oP; if(a.el.e == 0) { // Case of circle. - oP=angpoint(a,x*abs(degrees(a))); + oP = angpoint(a, x * abs(degrees(a))); } else { // Ellipse and not circle. if(!a.direction) { - transform t=reflect(line(a.el.F1,a.el.F2)); - return t*ppoint(t*a,x); + transform t = reflect(line(a.el.F1, a.el.F2)); + return t * ppoint(t * a, x); } - real angle1=a.angle1, angle2=a.angle2; + real angle1 = a.angle1, angle2 = a.angle2; if(a.polarconicroutine == fromFocus) { - // dot(point(fromFocus(a.el,angle1,angle1,1,CCW),0),2mm+blue); - // dot(point(fromFocus(a.el,angle2,angle2,1,CCW),0),2mm+blue); - // write("fromfocus1=",angle1); - // write("fromfocus2=",angle2); - real gle1=focusToCenter(a.el,angle1); - real gle2=focusToCenter(a.el,angle2); - if((gle1-gle2)*(angle1-angle2) > 0) { - angle1=gle1; angle2=gle2; + // dot(point(fromFocus(a.el, angle1, angle1, 1, CCW), 0), 2mm + blue); + // dot(point(fromFocus(a.el, angle2, angle2, 1, CCW), 0), 2mm + blue); + // write("fromfocus1 = ", angle1); + // write("fromfocus2 = ", angle2); + real gle1 = focusToCenter(a.el, angle1); + real gle2 = focusToCenter(a.el, angle2); + if((gle1 - gle2) * (angle1 - angle2) > 0) { + angle1 = gle1; angle2 = gle2; } else { - angle1=gle2; angle2=gle1; + angle1 = gle2; angle2 = gle1; } - // write("fromcenter1=",angle1); - // write("fromcenter2=",angle2); - // dot(point(fromCenter(a.el,angle1,angle1,1,CCW),0),1mm+red); - // dot(point(fromCenter(a.el,angle2,angle2,1,CCW),0),1mm+red); + // write("fromcenter1 = ", angle1); + // write("fromcenter2 = ", angle2); + // dot(point(fromCenter(a.el, angle1, angle1, 1, CCW), 0), 1mm + red); + // dot(point(fromCenter(a.el, angle2, angle2, 1, CCW), 0), 1mm + red); } if(angle1 > angle2) { - arc ta=a.copy(); - ta.polarconicroutine=fromCenter; - ta.setangles(a0=a.angle0,a1=angle1-360,a2=angle2); - return ppoint(ta,x); + arc ta = a.copy(); + ta.polarconicroutine = fromCenter; + ta.setangles(a0 = a.angle0, a1 = angle1 - 360, a2 = angle2); + return ppoint(ta, x); } - ellipse co=a.el; - real gle, a1, a2, cx=0; + ellipse co = a.el; + real gle, a1, a2, cx = 0; bool direction; if(x >= 0) { - a1=angle1; - a2=a1+360; - direction=CCW; + a1 = angle1; + a2 = a1 + 360; + direction = CCW; } else { - a1=angle1-360; - a2=a1-360; - direction=CW; + a1 = angle1 - 360; + a2 = a1 - 360; + direction = CW; } - gle=a1; - real L=arclength(co,angle1,angle2,a.direction,fromCenter); - real tx=L*abs(x)%arclength(co); - real aout=a1; - while(abs(cx-tx) > epsgeo) { - aout=(a1+a2)/2; - cx=abs(arclength(co,gle,aout,direction,fromCenter)); - if(cx > tx) a2=(a1+a2)/2 ; else a1=(a1+a2)/2; + gle = a1; + real L = arclength(co, angle1, angle2, a.direction, fromCenter); + real tx = L * abs(x)%arclength(co); + real aout = a1; + while(abs(cx - tx) > epsgeo) { + aout = (a1 + a2)/2; + cx = abs(arclength(co, gle, aout, direction, fromCenter)); + if(cx > tx) a2 = (a1 + a2)/2 ; else a1 = (a1 + a2)/2; } - pair p=point(arcfromcenter(co,aout,aout,CCW,1), 0); - oP=point(coordsys(co), p/coordsys(co)); + pair p = point(arcfromcenter(co, aout, aout, CCW, 1), 0); + oP = point(coordsys(co), p/coordsys(co)); } return oP; } -/*<asyxml><function type="point" signature="point(arc,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(arc, abscissa)"><code></asyxml>*/ point point(arc a, abscissa l) {/*<asyxml></code><documentation>Return the point of 'a' which has the abscissa 'l.x' according to the abscissa system 'l.system'. Note that 'a.polarconicroutine' is used instead of 'l.polarconicroutine'. - <look href="#struct abscissa"/></documentation></function></asyxml>*/ + <look href = "#struct abscissa"/></documentation></function></asyxml>*/ real posx; - arc ta=a.copy(); - ellipse co=a.el; + arc ta = a.copy(); + ellipse co = a.el; if (l.system == relativesystem) { - posx=l.x; + posx = l.x; } else if (l.system == curvilinearsystem) { real tl; if(co.e == 0) { - tl=curabscissa(a.el,angpoint(a.el,a.angle0+a.angle1)).x; - return curpoint(a.el,tl + (a.direction ? l.x : -l.x)); + tl = curabscissa(a.el, angpoint(a.el, a.angle0 + a.angle1)).x; + return curpoint(a.el, tl + (a.direction ? l.x : -l.x)); } else { - tl=curabscissa(a.el,angpoint(a.el,a.angle1,a.polarconicroutine)).x; - return curpoint(a.el,tl + (a.direction ? l.x : -l.x)); + tl = curabscissa(a.el, angpoint(a.el, a.angle1, a.polarconicroutine)).x; + return curpoint(a.el, tl + (a.direction ? l.x : -l.x)); } } else if (l.system == nodesystem) { - coordsys R=coordsys(co); - return point(R,point((path)a,l.x)/R); + coordsys R = coordsys(co); + return point(R, point((path)a, l.x)/R); } else if (l.system == angularsystem) { - return angpoint(a,l.x); + return angpoint(a, l.x); } else abort("point: bad abscissa system."); return ppoint(ta, posx); } -/*<asyxml><function type="point" signature="point(arc,real)"><code></asyxml>*/ -point point(arc a,real x) -{/*<asyxml></code><documentation>Return the point between node floor(t) and floor(t)+1.</documentation></function></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(arc, real)"><code></asyxml>*/ +point point(arc a, real x) +{/*<asyxml></code><documentation>Return the point between node floor(t) and floor(t) + 1.</documentation></function></asyxml>*/ return point(a, nodabscissa(x)); } pair point(explicit arc a, int x) @@ -5127,145 +5168,145 @@ pair point(explicit arc a, int x) return point(a, nodabscissa(x)); } -/*<asyxml><function type="point" signature="relpoint(arc,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "relpoint(arc, real)"><code></asyxml>*/ point relpoint(arc a, real x) {/*<asyxml></code><documentation>Return the relative point of 'a'. If x > 1 or x < 0, the returned point is on the extended arc.</documentation></function></asyxml>*/ return point(a, relabscissa(x)); } -/*<asyxml><function type="point" signature="curpoint(arc,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "curpoint(arc, real)"><code></asyxml>*/ point curpoint(arc a, real x) {/*<asyxml></code><documentation>Return the point of 'a' which has the curvilinear abscissa 'x'. If x < 0 or x > arclength(a), the returned point is on the extended arc.</documentation></function></asyxml>*/ return point(a, curabscissa(x)); } -/*<asyxml><function type="abscissa" signature="angabscissa(arc,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "angabscissa(arc, point)"><code></asyxml>*/ abscissa angabscissa(arc a, point M) {/*<asyxml></code><documentation>Return the angular abscissa of 'M' according to the arc 'a'.</documentation></function></asyxml>*/ if(!(M @ a.el)) abort("angabscissa: the point is not on the extended arc."); abscissa oa; - oa.system=angularsystem; - oa.polarconicroutine=a.polarconicroutine; - real am=angabscissa(a.el,M,a.polarconicroutine).x; - oa.x=(am-a.angle1-(a.el.e == 0 ? a.angle0 : 0))%360; - oa.x=a.direction ? oa.x : 360-oa.x; + oa.system = angularsystem; + oa.polarconicroutine = a.polarconicroutine; + real am = angabscissa(a.el, M, a.polarconicroutine).x; + oa.x = (am - a.angle1 - (a.el.e == 0 ? a.angle0 : 0))%360; + oa.x = a.direction ? oa.x : 360 - oa.x; return oa; } -/*<asyxml><function type="abscissa" signature="curabscissa(arc,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "curabscissa(arc, point)"><code></asyxml>*/ abscissa curabscissa(arc a, point M) {/*<asyxml></code><documentation>Return the curvilinear abscissa according to the arc 'a'.</documentation></function></asyxml>*/ - ellipse el=a.el; + ellipse el = a.el; if(!(M @ el)) abort("angabscissa: the point is not on the extended arc."); abscissa oa; - oa.system=curvilinearsystem; - real xm=curabscissa(el,M).x; - real a0=el.e == 0 ? a.angle0 : 0; - real am=curabscissa(el,angpoint(el,a.angle1+a0,a.polarconicroutine)).x; - real l=arclength(el); - oa.x=(xm-am)%l; - oa.x=a.direction ? oa.x : l-oa.x; + oa.system = curvilinearsystem; + real xm = curabscissa(el, M).x; + real a0 = el.e == 0 ? a.angle0 : 0; + real am = curabscissa(el, angpoint(el, a.angle1 + a0, a.polarconicroutine)).x; + real l = arclength(el); + oa.x = (xm - am)%l; + oa.x = a.direction ? oa.x : l - oa.x; return oa; } -/*<asyxml><function type="abscissa" signature="nodabscissa(arc,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "nodabscissa(arc, point)"><code></asyxml>*/ abscissa nodabscissa(arc a, point M) {/*<asyxml></code><documentation>Return the node abscissa according to the arc 'a'.</documentation></function></asyxml>*/ if(!(M @ a)) abort("nodabscissa: the point is not on the arc."); abscissa oa; - oa.system=nodesystem; - oa.x=intersect((path)a,M)[0]; + oa.system = nodesystem; + oa.x = intersect((path)a, M)[0]; return oa; } -/*<asyxml><function type="abscissa" signature="relabscissa(arc,point)"><code></asyxml>*/ +/*<asyxml><function type = "abscissa" signature = "relabscissa(arc, point)"><code></asyxml>*/ abscissa relabscissa(arc a, point M) {/*<asyxml></code><documentation>Return the relative abscissa according to the arc 'a'.</documentation></function></asyxml>*/ - ellipse el=a.el; + ellipse el = a.el; if(!( M @ el)) abort("relabscissa: the point is not on the prolonged arc."); abscissa oa; - oa.system=relativesystem; - oa.x=curabscissa(a,M).x/arclength(a); + oa.system = relativesystem; + oa.x = curabscissa(a, M).x/arclength(a); return oa; } -/*<asyxml><function type="void" signature="markarc(picture,Label,int,real,real,arc,arrowbar,pen,pen,margin,marker)"><code></asyxml>*/ -void markarc(picture pic=currentpicture, - Label L="", - int n=1, real radius=0, real space=0, +/*<asyxml><function type = "void" signature = "markarc(picture, Label, int, real, real, arc, arrowbar, pen, pen, margin, marker)"><code></asyxml>*/ +void markarc(picture pic = currentpicture, + Label L = "", + int n = 1, real radius = 0, real space = 0, arc a, - pen sectorpen=currentpen, - pen markpen=sectorpen, - margin margin=NoMargin, - arrowbar arrow=None, - marker marker=nomarker) + pen sectorpen = currentpen, + pen markpen = sectorpen, + margin margin = NoMargin, + arrowbar arrow = None, + marker marker = nomarker) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - real Da=degrees(a); - pair p1=point(a,0); - pair p2=relpoint(a,1); - pair c=a.polarconicroutine == fromCenter ? locate(a.el.C) : locate(a.el.F1); - if(radius == 0) radius=markangleradius(markpen); - if(abs(Da) > 180) radius=-radius; - radius=(a.direction ? 1 : -1)*sgnd(Da)*radius; - draw(c--p1^^c--p2,sectorpen); - markangle(pic=pic,L=L,n=n,radius=radius,space=space, - A=p1,O=c,B=p2, - arrow=arrow,p=markpen,margin=margin, - marker=marker); + real Da = degrees(a); + pair p1 = point(a, 0); + pair p2 = relpoint(a, 1); + pair c = a.polarconicroutine == fromCenter ? locate(a.el.C) : locate(a.el.F1); + if(radius == 0) radius = markangleradius(markpen); + if(abs(Da) > 180) radius = -radius; + radius = (a.direction ? 1 : -1) * sgnd(Da) * radius; + draw(c--p1^^c--p2, sectorpen); + markangle(pic = pic, L = L, n = n, radius = radius, space = space, + A = p1, O = c, B = p2, + arrow = arrow, p = markpen, margin = margin, + marker = marker); } // *.........................ARCS..........................* // *=======================================================* // *=======================================================* // *........................MASSES.........................* -/*<asyxml><struct signature="mass"><code></asyxml>*/ -struct mass {/*<asyxml></code><documentation></documentation><property type="point" signature="M"><code></asyxml>*/ - point M;/*<asyxml></code><documentation></documentation></property><property type="real" signature="m"><code></asyxml>*/ +/*<asyxml><struct signature = "mass"><code></asyxml>*/ +struct mass {/*<asyxml></code><documentation></documentation><property type = "point" signature = "M"><code></asyxml>*/ + point M;/*<asyxml></code><documentation></documentation></property><property type = "real" signature = "m"><code></asyxml>*/ real m;/*<asyxml></code><documentation></documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="mass" signature="mass(point,real)"><code></asyxml>*/ +/*<asyxml><function type = "mass" signature = "mass(point, real)"><code></asyxml>*/ mass mass(point M, real m) {/*<asyxml></code><documentation>Constructor of mass point.</documentation></function></asyxml>*/ mass om; - om.M=M; - om.m=m; + om.M = M; + om.m = m; return om; } -/*<asyxml><operator type="point" signature="cast(mass)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "cast(mass)"><code></asyxml>*/ point operator cast(mass m) {/*<asyxml></code><documentation>Cast mass point to point.</documentation></operator></asyxml>*/ point op; - op=m.M; - op.m=m.m; + op = m.M; + op.m = m.m; return op; } -/*<asyxml><function type="point" signature="point(explicit mass)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit mass)"><code></asyxml>*/ point point(explicit mass m){return m;}/*<asyxml></code><documentation>Cast 'm' to point</documentation></function></asyxml>*/ -/*<asyxml><operator type="mass" signature="cast(point)"><code></asyxml>*/ +/*<asyxml><operator type = "mass" signature = "cast(point)"><code></asyxml>*/ mass operator cast(point M) {/*<asyxml></code><documentation>Cast point to mass point.</documentation></operator></asyxml>*/ mass om; - om.M=M; - om.m=M.m; + om.M = M; + om.m = M.m; return om; } -/*<asyxml><function type="mass" signature="mass(explicit point)"><code></asyxml>*/ +/*<asyxml><function type = "mass" signature = "mass(explicit point)"><code></asyxml>*/ mass mass(explicit point P) {/*<asyxml></code><documentation>Cast 'P' to mass.</documentation></function></asyxml>*/ - return mass(P,P.m); + return mass(P, P.m); } -/*<asyxml><operator type="point[]" signature="cast(mass[])"><code></asyxml>*/ +/*<asyxml><operator type = "point[]" signature = "cast(mass[])"><code></asyxml>*/ point[] operator cast(mass[] m) {/*<asyxml></code><documentation>Cast mass[] to point[].</documentation></operator></asyxml>*/ point[] op; @@ -5273,7 +5314,7 @@ point[] operator cast(mass[] m) return op; } -/*<asyxml><operator type="mass[]" signature="cast(point[])"><code></asyxml>*/ +/*<asyxml><operator type = "mass[]" signature = "cast(point[])"><code></asyxml>*/ mass[] operator cast(point[] P) {/*<asyxml></code><documentation>Cast point[] to mass[].</documentation></operator></asyxml>*/ mass[] om; @@ -5281,306 +5322,306 @@ mass[] operator cast(point[] P) return om; } -/*<asyxml><function type="mass" signature="mass(coordsys,explicit pair,real)"><code></asyxml>*/ +/*<asyxml><function type = "mass" signature = "mass(coordsys, explicit pair, real)"><code></asyxml>*/ mass mass(coordsys R, explicit pair p, real m) {/*<asyxml></code><documentation>Return the mass which has coordinates 'p' with respect to 'R' and weight 'm'.</documentation></function></asyxml>*/ - return point(R,p,m);// Using casting. + return point(R, p, m);// Using casting. } -/*<asyxml><operator type="mass" signature="cast(pair)"><code></asyxml>*/ -mass operator cast(pair m){return mass((point)m,1);}/*<asyxml></code><documentation>Cast pair to mass point.</documentation></operator></asyxml>*/ -/*<asyxml><operator type="path" signature="cast(mass)"><code></asyxml>*/ +/*<asyxml><operator type = "mass" signature = "cast(pair)"><code></asyxml>*/ +mass operator cast(pair m){return mass((point)m, 1);}/*<asyxml></code><documentation>Cast pair to mass point.</documentation></operator></asyxml>*/ +/*<asyxml><operator type = "path" signature = "cast(mass)"><code></asyxml>*/ path operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass point to path.</documentation></operator></asyxml>*/ -/*<asyxml><operator type="guide" signature="cast(mass)"><code></asyxml>*/ +/*<asyxml><operator type = "guide" signature = "cast(mass)"><code></asyxml>*/ guide operator cast(mass M){return M.M;}/*<asyxml></code><documentation>Cast mass to guide.</documentation></operator></asyxml>*/ -/*<asyxml><operator type="mass" signature="+(mass,mass)"><code></asyxml>*/ +/*<asyxml><operator type = "mass" signature = "+(mass, mass)"><code></asyxml>*/ mass operator +(mass M1, mass M2) -{/*<asyxml></code><documentation>Provide mass+mass. - mass-mass is also defined.</documentation></operator></asyxml>*/ - return mass(M1.M+M2.M,M1.m+M2.m); +{/*<asyxml></code><documentation>Provide mass + mass. + mass - mass is also defined.</documentation></operator></asyxml>*/ + return mass(M1.M + M2.M, M1.m + M2.m); } mass operator -(mass M1, mass M2) { - return mass(M1.M-M2.M,M1.m-M2.m); + return mass(M1.M - M2.M, M1.m - M2.m); } -/*<asyxml><operator type="mass" signature="*(real,mass)"><code></asyxml>*/ +/*<asyxml><operator type = "mass" signature = "*(real, mass)"><code></asyxml>*/ mass operator *(real x, explicit mass M) -{/*<asyxml></code><documentation>Provide real*mass. +{/*<asyxml></code><documentation>Provide real * mass. The resulted mass is the mass of 'M' multiplied by 'x' . - mass/real, mass+real and mass-real are also defined.</documentation></operator></asyxml>*/ - return mass(M.M,x*M.m); -} -mass operator *(int x, explicit mass M){return mass(M.M,x*M.m);} -mass operator /(explicit mass M,real x){return mass(M.M,M.m/x);} -mass operator /(explicit mass M,int x){return mass(M.M,M.m/x);} -mass operator +(explicit mass M,real x){return mass(M.M,M.m+x);} -mass operator +(explicit mass M,int x){return mass(M.M,M.m+x);} -mass operator -(explicit mass M,real x){return mass(M.M,M.m-x);} -mass operator -(explicit mass M,int x){return mass(M.M,M.m-x);} -/*<asyxml><operator type="mass" signature="*(transform,mass)"><code></asyxml>*/ + mass/real, mass + real and mass - real are also defined.</documentation></operator></asyxml>*/ + return mass(M.M, x * M.m); +} +mass operator *(int x, explicit mass M){return mass(M.M, x * M.m);} +mass operator /(explicit mass M, real x){return mass(M.M, M.m/x);} +mass operator /(explicit mass M, int x){return mass(M.M, M.m/x);} +mass operator +(explicit mass M, real x){return mass(M.M, M.m + x);} +mass operator +(explicit mass M, int x){return mass(M.M, M.m + x);} +mass operator -(explicit mass M, real x){return mass(M.M, M.m - x);} +mass operator -(explicit mass M, int x){return mass(M.M, M.m - x);} +/*<asyxml><operator type = "mass" signature = "*(transform, mass)"><code></asyxml>*/ mass operator *(transform t, mass M) -{/*<asyxml></code><documentation>Provide transform*mass.</documentation></operator></asyxml>*/ - return mass(t*M.M,M.m); +{/*<asyxml></code><documentation>Provide transform * mass.</documentation></operator></asyxml>*/ + return mass(t * M.M, M.m); } -/*<asyxml><function type="mass" signature="masscenter(... mass[])"><code></asyxml>*/ +/*<asyxml><function type = "mass" signature = "masscenter(... mass[])"><code></asyxml>*/ mass masscenter(... mass[] M) {/*<asyxml></code><documentation>Return the center of the masses 'M'.</documentation></function></asyxml>*/ point[] P; - for (int i=0; i < M.length; ++i) + for (int i = 0; i < M.length; ++i) P.push(M[i].M); - P=standardizecoordsys(currentcoordsys,true ... P); - real m=M[0].m; - point oM=M[0].m*P[0]; - for (int i=1; i < M.length; ++i) { - oM+=M[i].m*P[i]; - m+=M[i].m; + P = standardizecoordsys(currentcoordsys, true ... P); + real m = M[0].m; + point oM = M[0].m * P[0]; + for (int i = 1; i < M.length; ++i) { + oM += M[i].m * P[i]; + m += M[i].m; } if (m == 0) abort("masscenter: the sum of masses is null."); - return mass(oM/m,m); + return mass(oM/m, m); } -/*<asyxml><function type="string" signature="massformat(string,string,mass)"><code></asyxml>*/ -string massformat(string format=defaultmassformat, +/*<asyxml><function type = "string" signature = "massformat(string, string, mass)"><code></asyxml>*/ +string massformat(string format = defaultmassformat, string s, mass M) {/*<asyxml></code><documentation>Return the string formated by 'format' with the mass value. In the parameter 'format', %L will be replaced by 's'. - <look href="#defaultmassformat"/>.</documentation></function></asyxml>*/ + <look href = "#defaultmassformat"/>.</documentation></function></asyxml>*/ return format == "" ? s : - format(replace(format,"%L",replace(s,"$","")),M.m); + format(replace(format, "%L", replace(s, "$", "")), M.m); } -/*<asyxml><function type="void" signature="label(picture, Label,explicit mass,align,string,pen,filltype)"><code></asyxml>*/ -void label(picture pic=currentpicture, Label L, explicit mass M, - align align=NoAlign, string format=defaultmassformat, - pen p=nullpen, filltype filltype=NoFill) -{/*<asyxml></code><documentation>Draw label returned by massformat(format,L,M) at coordinates of M. - <look href="#massformat(string,string,mass)"/>.</documentation></function></asyxml>*/ - Label lL=L.copy(); - lL.s=massformat(format,lL.s,M); - Label L=Label(lL,M.M,align,p,filltype); - add(pic,L); +/*<asyxml><function type = "void" signature = "label(picture, Label, explicit mass, align, string, pen, filltype)"><code></asyxml>*/ +void label(picture pic = currentpicture, Label L, explicit mass M, + align align = NoAlign, string format = defaultmassformat, + pen p = nullpen, filltype filltype = NoFill) +{/*<asyxml></code><documentation>Draw label returned by massformat(format, L, M) at coordinates of M. + <look href = "#massformat(string, string, mass)"/>.</documentation></function></asyxml>*/ + Label lL = L.copy(); + lL.s = massformat(format, lL.s, M); + Label L = Label(lL, M.M, align, p, filltype); + add(pic, L); } -/*<asyxml><function type="void" signature="dot(picture,Label,explicit mass,align,string,pen)"><code></asyxml>*/ -void dot(picture pic=currentpicture, Label L, explicit mass M, align align=NoAlign, - string format=defaultmassformat, pen p=currentpen) +/*<asyxml><function type = "void" signature = "dot(picture, Label, explicit mass, align, string, pen)"><code></asyxml>*/ +void dot(picture pic = currentpicture, Label L, explicit mass M, align align = NoAlign, + string format = defaultmassformat, pen p = currentpen) {/*<asyxml></code><documentation>Draw a dot with label 'L' as - label(picture, Label,explicit mass,align,string,pen,filltype) does. - <look href="#label(picture, Label,mass,align,string,pen,filltype)"/>.</documentation></function></asyxml>*/ - Label lL=L.copy(); - lL.s=massformat(format,lL.s,M); + label(picture, Label, explicit mass, align, string, pen, filltype) does. + <look href = "#label(picture, Label, mass, align, string, pen, filltype)"/>.</documentation></function></asyxml>*/ + Label lL = L.copy(); + lL.s = massformat(format, lL.s, M); lL.position(locate(M.M)); - lL.align(align,E); + lL.align(align, E); lL.p(p); - dot(pic,M.M,p); - add(pic,lL); + dot(pic, M.M, p); + add(pic, lL); } // *........................MASSES.........................* // *=======================================================* // *=======================================================* // *.......................TRIANGLES.......................* -/*<asyxml><function type="point" signature="orthocentercenter(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "orthocentercenter(point, point, point)"><code></asyxml>*/ point orthocentercenter(point A, point B, point C) {/*<asyxml></code><documentation>Return the orthocenter of the triangle ABC.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B,C); - coordsys R=P[0].coordsys; - pair pp=extension(A, projection(P[1],P[2])*P[0], B, projection(P[0],P[2])*P[1]); - return point(R,pp/R); + point[] P = standardizecoordsys(A, B, C); + coordsys R = P[0].coordsys; + pair pp = extension(A, projection(P[1], P[2]) * P[0], B, projection(P[0], P[2]) * P[1]); + return point(R, pp/R); } -/*<asyxml><function type="point" signature="centroid(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "centroid(point, point, point)"><code></asyxml>*/ point centroid(point A, point B, point C) {/*<asyxml></code><documentation>Return the centroid of the triangle ABC.</documentation></function></asyxml>*/ - return (A+B+C)/3; + return (A + B + C)/3; } -/*<asyxml><function type="point" signature="incenter(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "incenter(point, point, point)"><code></asyxml>*/ point incenter(point A, point B, point C) {/*<asyxml></code><documentation>Return the center of the incircle of the triangle ABC.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B,C); - coordsys R=P[0].coordsys; - pair a=A, b=B, c=C; - pair pp=extension(a, a+dir(a--b,a--c), b, b+dir(b--a,b--c)); - return point(R,pp/R); + point[] P = standardizecoordsys(A, B, C); + coordsys R = P[0].coordsys; + pair a = A, b = B, c = C; + pair pp = extension(a, a + dir(a--b, a--c), b, b + dir(b--a, b--c)); + return point(R, pp/R); } -/*<asyxml><function type="real" signature="inradius(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "inradius(point, point, point)"><code></asyxml>*/ real inradius(point A, point B, point C) {/*<asyxml></code><documentation>Return the radius of the incircle of the triangle ABC.</documentation></function></asyxml>*/ - point IC=incenter(A,B,C); - return abs(IC-projection(A,B)*IC); + point IC = incenter(A, B, C); + return abs(IC - projection(A, B) * IC); } -/*<asyxml><function type="circle" signature="incircle(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "incircle(point, point, point)"><code></asyxml>*/ circle incircle(point A, point B, point C) {/*<asyxml></code><documentation>Return the incircle of the triangle ABC.</documentation></function></asyxml>*/ - point IC=incenter(A, B, C); - return circle(IC,abs(IC-projection(A,B)*IC)); + point IC = incenter(A, B, C); + return circle(IC, abs(IC - projection(A, B) * IC)); } -/*<asyxml><function type="point" signature="excenter(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "excenter(point, point, point)"><code></asyxml>*/ point excenter(point A, point B, point C) {/*<asyxml></code><documentation>Return the center of the excircle of the triangle tangent with (AB).</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B,C); - coordsys R=P[0].coordsys; - pair a=A, b=B, c=C; - pair pp=extension(a, a+rotate(90)*dir(a--b,a--c), b, b+rotate(90)*dir(b--a,b--c)); - return point(R,pp/R); + point[] P = standardizecoordsys(A, B, C); + coordsys R = P[0].coordsys; + pair a = A, b = B, c = C; + pair pp = extension(a, a + rotate(90) * dir(a--b, a--c), b, b + rotate(90) * dir(b--a, b--c)); + return point(R, pp/R); } -/*<asyxml><function type="real" signature="exradius(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "exradius(point, point, point)"><code></asyxml>*/ real exradius(point A, point B, point C) {/*<asyxml></code><documentation>Return the radius of the excircle of the triangle ABC with (AB).</documentation></function></asyxml>*/ - point EC=excenter(A,B,C); - return abs(EC-projection(A,B)*EC); + point EC = excenter(A, B, C); + return abs(EC - projection(A, B) * EC); } -/*<asyxml><function type="circle" signature="excircle(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "excircle(point, point, point)"><code></asyxml>*/ circle excircle(point A, point B, point C) {/*<asyxml></code><documentation>Return the excircle of the triangle ABC tangent with (AB).</documentation></function></asyxml>*/ - point center=excenter(A,B,C); - real radius=abs(center-projection(B,C)*center); - return circle(center,radius); + point center = excenter(A, B, C); + real radius = abs(center - projection(B, C) * center); + return circle(center, radius); } -private int[] numarray={1,2,3}; -numarray.cyclic=true; +private int[] numarray = {1, 2, 3}; +numarray.cyclic = true; -/*<asyxml><struct signature="triangle"><code></asyxml>*/ +/*<asyxml><struct signature = "triangle"><code></asyxml>*/ struct triangle {/*<asyxml></code><documentation></documentation></asyxml>*/ - /*<asyxml><struct signature="vertex"><code></asyxml>*/ - struct vertex {/*<asyxml></code><documentation>Structure used to communicate the vertex of a triangle.</documentation><property type="int" signature="n"><code></asyxml>*/ - int n;/*<asyxml></code><documentation>1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></property><property type="triangle" signature="triangle"><code></asyxml>*/ + /*<asyxml><struct signature = "vertex"><code></asyxml>*/ + struct vertex {/*<asyxml></code><documentation>Structure used to communicate the vertex of a triangle.</documentation><property type = "int" signature = "n"><code></asyxml>*/ + int n;/*<asyxml></code><documentation>1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></property><property type = "triangle" signature = "triangle"><code></asyxml>*/ triangle t;/*<asyxml></code><documentation>The triangle to which the vertex refers.</documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ - /*<asyxml><property type="point" signature="A, B, C"><code></asyxml>*/ - restricted point A, B, C;/*<asyxml></code><documentation>The vertices of the triangle (as point).</documentation></property><property type="vertex" signature="VA, VB, VC"><code></asyxml>*/ + /*<asyxml><property type = "point" signature = "A, B, C"><code></asyxml>*/ + restricted point A, B, C;/*<asyxml></code><documentation>The vertices of the triangle (as point).</documentation></property><property type = "vertex" signature = "VA, VB, VC"><code></asyxml>*/ restricted vertex VA, VB, VC;/*<asyxml></code><documentation>The vertices of the triangle (as vertex). Note that the vertex structure contains the triangle to wish it refers.</documentation></property></asyxml>*/ - VA.n=1;VB.n=2;VC.n=3; + VA.n = 1;VB.n = 2;VC.n = 3; - /*<asyxml><method type="vertex" signature="vertex(int)"><code></asyxml>*/ + /*<asyxml><method type = "vertex" signature = "vertex(int)"><code></asyxml>*/ vertex vertex(int n) {/*<asyxml></code><documentation>Return numbered vertex. 'n' is 1 means VA, 2 means VB, 3 means VC, 4 means VA etc...</documentation></method></asyxml>*/ - n = numarray[n-1]; + n = numarray[n - 1]; if(n == 1) return VA; else if(n == 2) return VB; return VC; } - /*<asyxml><method type="point" signature="point(int)"><code></asyxml>*/ + /*<asyxml><method type = "point" signature = "point(int)"><code></asyxml>*/ point point(int n) {/*<asyxml></code><documentation>Return numbered point. n is 1 means A, 2 means B, 3 means C, 4 means A etc...</documentation></method></asyxml>*/ - n = numarray[n-1]; + n = numarray[n - 1]; if(n == 1) return A; else if(n == 2) return B; return C; } - /*<asyxml><method type="void" signature="init(point,point,point)"><code></asyxml>*/ + /*<asyxml><method type = "void" signature = "init(point, point, point)"><code></asyxml>*/ void init(point A, point B, point C) {/*<asyxml></code><documentation>Constructor.</documentation></method></asyxml>*/ - point[] P=standardizecoordsys(A,B,C); - this.A=P[0]; - this.B=P[1]; - this.C=P[2]; - VA.t=this; VB.t=this; VC.t=this; + point[] P = standardizecoordsys(A, B, C); + this.A = P[0]; + this.B = P[1]; + this.C = P[2]; + VA.t = this; VB.t = this; VC.t = this; } - /*<asyxml><method type="void" signature="operator init(point,point,point)"><code></asyxml>*/ + /*<asyxml><method type = "void" signature = "operator init(point, point, point)"><code></asyxml>*/ void operator init(point A, point B, point C) {/*<asyxml></code><documentation>For backward compatibility. Provide the routine 'triangle(point A, point B, point C)'.</documentation></method></asyxml>*/ - this.init(A,B,C); + this.init(A, B, C); } - /*<asyxml><method type="void" signature="init(real,real,real,real,point)"><code></asyxml>*/ - void operator init(real b, real alpha, real c, real angle=0, point A=(0,0)) + /*<asyxml><method type = "void" signature = "init(real, real, real, real, point)"><code></asyxml>*/ + void operator init(real b, real alpha, real c, real angle = 0, point A = (0, 0)) {/*<asyxml></code><documentation>For backward compatibility. - Provide the routine 'triangle(real b, real alpha, real c, real angle=0, point A=(0,0)) - which returns the triangle ABC rotated by 'angle' (in degrees) and where b=AC, degrees(A)=alpha, AB=c.</documentation></method></asyxml>*/ - coordsys R=A.coordsys; - this.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle+alpha))); + Provide the routine 'triangle(real b, real alpha, real c, real angle = 0, point A = (0, 0)) + which returns the triangle ABC rotated by 'angle' (in degrees) and where b = AC, degrees(A) = alpha, AB = c.</documentation></method></asyxml>*/ + coordsys R = A.coordsys; + this.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle + alpha))); } - /*<asyxml><method type="real" signature="a(),b(),c()"><code></asyxml>*/ + /*<asyxml><method type = "real" signature = "a(), b(), c()"><code></asyxml>*/ real a() {/*<asyxml></code><documentation>Return the length BC. b() and c() are also defined and return the length AC and AB respectively.</documentation></method></asyxml>*/ - return length(C-B); + return length(C - B); } - real b() {return length(A-C);} - real c() {return length(B-A);} + real b() {return length(A - C);} + real c() {return length(B - A);} - private real det(pair a, pair b) {return a.x*b.y-a.y*b.x;} + private real det(pair a, pair b) {return a.x * b.y - a.y * b.x;} - /*<asyxml><method type="real" signature="area()"><code></asyxml>*/ + /*<asyxml><method type = "real" signature = "area()"><code></asyxml>*/ real area() {/*<asyxml></code><documentation></documentation></method></asyxml>*/ - pair a=locate(A), b=locate(B), c=locate(C); - return 0.5*abs(det(a,b)+det(b,c)+det(c,a)); + pair a = locate(A), b = locate(B), c = locate(C); + return 0.5 * abs(det(a, b) + det(b, c) + det(c, a)); } - /*<asyxml><method type="real" signature="alpha(),beta(),gamma()"><code></asyxml>*/ + /*<asyxml><method type = "real" signature = "alpha(), beta(), gamma()"><code></asyxml>*/ real alpha() {/*<asyxml></code><documentation>Return the measure (in degrees) of the angle A. beta() and gamma() are also defined and return the measure of the angles B and C respectively.</documentation></method></asyxml>*/ - return degrees(acos((b()^2+c()^2-a()^2)/(2b()*c()))); + return degrees(acos((b()^2 + c()^2 - a()^2)/(2b() * c()))); } - real beta() {return degrees(acos((c()^2+a()^2-b()^2)/(2c()*a())));} - real gamma() {return degrees(acos((a()^2+b()^2-c()^2)/(2a()*b())));} + real beta() {return degrees(acos((c()^2 + a()^2 - b()^2)/(2c() * a())));} + real gamma() {return degrees(acos((a()^2 + b()^2 - c()^2)/(2a() * b())));} - /*<asyxml><method type="path" signature="Path()"><code></asyxml>*/ + /*<asyxml><method type = "path" signature = "Path()"><code></asyxml>*/ path Path() {/*<asyxml></code><documentation>The path of the triangle.</documentation></method></asyxml>*/ return A--C--B--cycle; } - /*<asyxml><struct signature="side"><code></asyxml>*/ + /*<asyxml><struct signature = "side"><code></asyxml>*/ struct side - {/*<asyxml></code><documentation>Structure used to communicate the side of a triangle.</documentation><property type="int" signature="n"><code></asyxml>*/ - int n;/*<asyxml></code><documentation>1 or 0 means [AB], -1 means [BA], 2 means [BC], -2 means [CB] etc.</documentation></property><property type="triangle" signature="triangle"><code></asyxml>*/ + {/*<asyxml></code><documentation>Structure used to communicate the side of a triangle.</documentation><property type = "int" signature = "n"><code></asyxml>*/ + int n;/*<asyxml></code><documentation>1 or 0 means [AB], -1 means [BA], 2 means [BC], -2 means [CB] etc.</documentation></property><property type = "triangle" signature = "triangle"><code></asyxml>*/ triangle t;/*<asyxml></code><documentation>The triangle to which the side refers.</documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ - /*<asyxml><property type="side" signature="AB"><code></asyxml>*/ + /*<asyxml><property type = "side" signature = "AB"><code></asyxml>*/ side AB;/*<asyxml></code><documentation>For the routines using the structure 'side', triangle.AB means 'side AB'. BA, AC, CA etc are also defined.</documentation></property></asyxml>*/ - AB.n=1; AB.t=this; - side BA; BA.n=-1; BA.t=this; - side BC; BC.n=2; BC.t=this; - side CB; CB.n=-2; CB.t=this; - side CA; CA.n=3; CA.t=this; - side AC; AC.n=-3; AC.t=this; - - /*<asyxml><method type="side" signature="side(int)"><code></asyxml>*/ + AB.n = 1; AB.t = this; + side BA; BA.n = -1; BA.t = this; + side BC; BC.n = 2; BC.t = this; + side CB; CB.n = -2; CB.t = this; + side CA; CA.n = 3; CA.t = this; + side AC; AC.n = -3; AC.t = this; + + /*<asyxml><method type = "side" signature = "side(int)"><code></asyxml>*/ side side(int n) {/*<asyxml></code><documentation>Return numbered side. n is 1 means AB, -1 means BA, 2 means BC, -2 means CB, etc.</documentation></method></asyxml>*/ if(n == 0) abort('Invalid side number.'); - int an=numarray[abs(n)-1]; + int an = numarray[abs(n)-1]; if(an == 1) return n > 0 ? AB : BA; else if(an == 2) return n > 0 ? BC : CB; return n > 0 ? CA : AC; } - /*<asyxml><method type="line" signature="line(int)"><code></asyxml>*/ + /*<asyxml><method type = "line" signature = "line(int)"><code></asyxml>*/ line line(int n) {/*<asyxml></code><documentation>Return the numbered line.</documentation></method></asyxml>*/ if(n == 0) abort('Invalid line number.'); - int an=numarray[abs(n)-1]; - if(an == 1) return n > 0 ? line(A,B) : line(B,A); - else if(an == 2) return n > 0 ? line(B,C) : line(C,B); - return n > 0 ? line(C,A) : line(A,C); + int an = numarray[abs(n)-1]; + if(an == 1) return n > 0 ? line(A, B) : line(B, A); + else if(an == 2) return n > 0 ? line(B, C) : line(C, B); + return n > 0 ? line(C, A) : line(A, C); } }/*<asyxml></struct></asyxml>*/ @@ -5591,7 +5632,7 @@ from triangle unravel vertex; // The structure 'vertex' is now available outside triangle[] operator ^^(triangle[] t1, triangle t2) { triangle[] T; - for (int i=0; i < t1.length; ++i) T.push(t1[i]); + for (int i = 0; i < t1.length; ++i) T.push(t1[i]); T.push(t2); return T; } @@ -5599,704 +5640,704 @@ triangle[] operator ^^(triangle[] t1, triangle t2) triangle[] operator ^^(... triangle[] t) { triangle[] T; - for (int i=0; i < t.length; ++i) { + for (int i = 0; i < t.length; ++i) { T.push(t[i]); } return T; } -/*<asyxml><operator type="line" signature="cast(side)"><code></asyxml>*/ +/*<asyxml><operator type = "line" signature = "cast(side)"><code></asyxml>*/ line operator cast(side side) {/*<asyxml></code><documentation>Cast side to (infinite) line. Most routine with line parameters works with side parameters. One can use the code 'segment(a_side)' to obtain a line segment.</documentation></operator></asyxml>*/ - triangle t=side.t; + triangle t = side.t; return t.line(side.n); } -/*<asyxml><function type="line" signature="line(explicit side)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "line(explicit side)"><code></asyxml>*/ line line(explicit side side) {/*<asyxml></code><documentation>Return 'side' as line.</documentation></function></asyxml>*/ return (line)side; } -/*<asyxml><function type="segment" signature="segment(explicit side)"><code></asyxml>*/ +/*<asyxml><function type = "segment" signature = "segment(explicit side)"><code></asyxml>*/ segment segment(explicit side side) {/*<asyxml></code><documentation>Return 'side' as segment.</documentation></function></asyxml>*/ return (segment)(line)side; } -/*<asyxml><operator type="point" signature="cast(vertex)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "cast(vertex)"><code></asyxml>*/ point operator cast(vertex V) {/*<asyxml></code><documentation>Cast vertex to point. Most routine with point parameters works with vertex parameters.</documentation></operator></asyxml>*/ return V.t.point(V.n); } -/*<asyxml><function type="point" signature="point(explicit vertex)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(explicit vertex)"><code></asyxml>*/ point point(explicit vertex V) {/*<asyxml></code><documentation>Return the point corresponding to the vertex 'V'.</documentation></function></asyxml>*/ return (point)V; } -/*<asyxml><function type="side" signature="opposite(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "side" signature = "opposite(vertex)"><code></asyxml>*/ side opposite(vertex V) {/*<asyxml></code><documentation>Return the opposite side of vertex 'V'.</documentation></function></asyxml>*/ return V.t.side(numarray[abs(V.n)]); } -/*<asyxml><function type="vertex" signature="opposite(side)"><code></asyxml>*/ +/*<asyxml><function type = "vertex" signature = "opposite(side)"><code></asyxml>*/ vertex opposite(side side) {/*<asyxml></code><documentation>Return the opposite vertex of side 'side'.</documentation></function></asyxml>*/ - return side.t.vertex(numarray[abs(side.n)+1]); + return side.t.vertex(numarray[abs(side.n) + 1]); } -/*<asyxml><function type="point" signature="midpoint(side)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "midpoint(side)"><code></asyxml>*/ point midpoint(side side) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ return midpoint(segment(side)); } -/*<asyxml><operator type="triangle" signature="*(transform,triangle)"><code></asyxml>*/ +/*<asyxml><operator type = "triangle" signature = "*(transform, triangle)"><code></asyxml>*/ triangle operator *(transform T, triangle t) -{/*<asyxml></code><documentation>Provide transform*triangle.</documentation></operator></asyxml>*/ - return triangle(T*t.A,T*t.B,T*t.C); +{/*<asyxml></code><documentation>Provide transform * triangle.</documentation></operator></asyxml>*/ + return triangle(T * t.A, T * t.B, T * t.C); } -/*<asyxml><function type="triangle" signature="triangleAbc(real,real,real,real,point)"><code></asyxml>*/ -triangle triangleAbc(real alpha, real b, real c, real angle=0, point A=(0,0)) -{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BAC=alpha, AC=b and AB=c.</documentation></function></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "triangleAbc(real, real, real, real, point)"><code></asyxml>*/ +triangle triangleAbc(real alpha, real b, real c, real angle = 0, point A = (0, 0)) +{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BAC = alpha, AC = b and AB = c.</documentation></function></asyxml>*/ triangle T; - coordsys R=A.coordsys; - T.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle+alpha))); + coordsys R = A.coordsys; + T.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle + alpha))); return T; } -/*<asyxml><function type="triangle" signature="triangleabc(real,real,real,real,point)"><code></asyxml>*/ -triangle triangleabc(real a, real b, real c, real angle=0, point A=(0,0)) -{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BC=a, AC=b and AB=c.</documentation></function></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "triangleabc(real, real, real, real, point)"><code></asyxml>*/ +triangle triangleabc(real a, real b, real c, real angle = 0, point A = (0, 0)) +{/*<asyxml></code><documentation>Return the triangle ABC rotated by 'angle' with BC = a, AC = b and AB = c.</documentation></function></asyxml>*/ triangle T; - coordsys R=A.coordsys; - T.init(A,A+R.polar(c,radians(angle)),A+R.polar(b,radians(angle)+acos((b^2+c^2-a^2)/(2*b*c)))); + coordsys R = A.coordsys; + T.init(A, A + R.polar(c, radians(angle)), A + R.polar(b, radians(angle) + acos((b^2 + c^2 - a^2)/(2 * b * c)))); return T; } -/*<asyxml><function type="triangle" signature="triangle(line,line,line)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "triangle(line, line, line)"><code></asyxml>*/ triangle triangle(line l1, line l2, line l3) {/*<asyxml></code><documentation>Return the triangle defined by three line.</documentation></function></asyxml>*/ - point P1,P2,P3; - P1=intersectionpoint(l1,l2); - P2=intersectionpoint(l1,l3); - P3=intersectionpoint(l2,l3); + point P1, P2, P3; + P1 = intersectionpoint(l1, l2); + P2 = intersectionpoint(l1, l3); + P3 = intersectionpoint(l2, l3); if(!(defined(P1) && defined(P2) && defined(P3))) abort("triangle: two lines are parallel."); - return triangle(P1,P2,P3); + return triangle(P1, P2, P3); } -/*<asyxml><function type="point" signature="foot(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "foot(vertex)"><code></asyxml>*/ point foot(vertex V) {/*<asyxml></code><documentation>Return the endpoint of the altitude from V.</documentation></function></asyxml>*/ - return projection((line)opposite(V))*((point)V); + return projection((line)opposite(V)) * ((point)V); } -/*<asyxml><function type="point" signature="foot(side)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "foot(side)"><code></asyxml>*/ point foot(side side) {/*<asyxml></code><documentation>Return the endpoint of the altitude on 'side'.</documentation></function></asyxml>*/ - return projection((line)side)*point(opposite(side)); + return projection((line)side) * point(opposite(side)); } -/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "altitude(vertex)"><code></asyxml>*/ line altitude(vertex V) {/*<asyxml></code><documentation>Return the altitude passing through 'V'.</documentation></function></asyxml>*/ - return line(point(V),foot(V)); + return line(point(V), foot(V)); } -/*<asyxml><function type="line" signature="altitude(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "altitude(vertex)"><code></asyxml>*/ line altitude(side side) {/*<asyxml></code><documentation>Return the altitude cutting 'side'.</documentation></function></asyxml>*/ return altitude(opposite(side)); } -/*<asyxml><function type="point" signature="orthocentercenter(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "orthocentercenter(triangle)"><code></asyxml>*/ point orthocentercenter(triangle t) {/*<asyxml></code><documentation>Return the orthocenter of the triangle t.</documentation></function></asyxml>*/ - return orthocentercenter(t.A,t.B,t.C); + return orthocentercenter(t.A, t.B, t.C); } -/*<asyxml><function type="point" signature="centroid(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "centroid(triangle)"><code></asyxml>*/ point centroid(triangle t) {/*<asyxml></code><documentation>Return the centroid of the triangle 't'.</documentation></function></asyxml>*/ - return (t.A+t.B+t.C)/3; + return (t.A + t.B + t.C)/3; } -/*<asyxml><function type="point" signature="circumcenter(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "circumcenter(triangle)"><code></asyxml>*/ point circumcenter(triangle t) {/*<asyxml></code><documentation>Return the circumcenter of the triangle 't'.</documentation></function></asyxml>*/ - return circumcenter(t.A,t.B,t.C); + return circumcenter(t.A, t.B, t.C); } -/*<asyxml><function type="circle" signature="circle(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circle(triangle)"><code></asyxml>*/ circle circle(triangle t) {/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/ - return circle(t.A,t.B,t.C); + return circle(t.A, t.B, t.C); } -/*<asyxml><function type="circle" signature="circumcircle(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "circumcircle(triangle)"><code></asyxml>*/ circle circumcircle(triangle t) {/*<asyxml></code><documentation>Return the circumcircle of the triangle 't'.</documentation></function></asyxml>*/ - return circle(t.A,t.B,t.C); + return circle(t.A, t.B, t.C); } -/*<asyxml><function type="point" signature="incenter(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "incenter(triangle)"><code></asyxml>*/ point incenter(triangle t) {/*<asyxml></code><documentation>Return the center of the incircle of the triangle 't'.</documentation></function></asyxml>*/ - return incenter(t.A,t.B,t.C); + return incenter(t.A, t.B, t.C); } -/*<asyxml><function type="real" signature="inradius(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "inradius(triangle)"><code></asyxml>*/ real inradius(triangle t) {/*<asyxml></code><documentation>Return the radius of the incircle of the triangle 't'.</documentation></function></asyxml>*/ - return inradius(t.A,t.B,t.C); + return inradius(t.A, t.B, t.C); } -/*<asyxml><function type="circle" signature="incircle(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "incircle(triangle)"><code></asyxml>*/ circle incircle(triangle t) {/*<asyxml></code><documentation>Return the the incircle of the triangle 't'.</documentation></function></asyxml>*/ - return incircle(t.A,t.B,t.C); + return incircle(t.A, t.B, t.C); } -/*<asyxml><function type="point" signature="excenter(side,triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "excenter(side, triangle)"><code></asyxml>*/ point excenter(side side) {/*<asyxml></code><documentation>Return the center of the excircle tangent with the side 'side' of its triangle. - side=0 means AB, 1 means AC, other means BC. + side = 0 means AB, 1 means AC, other means BC. One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/ point op; - triangle t=side.t; - int n=numarray[abs(side.n)-1]; - if(n == 1) op=excenter(t.A,t.B,t.C); - else if(n == 2) op=excenter(t.B,t.C,t.A); - else op=excenter(t.C,t.A,t.B); + triangle t = side.t; + int n = numarray[abs(side.n) - 1]; + if(n == 1) op = excenter(t.A, t.B, t.C); + else if(n == 2) op = excenter(t.B, t.C, t.A); + else op = excenter(t.C, t.A, t.B); return op; } -/*<asyxml><function type="real" signature="exradius(side,triangle)"><code></asyxml>*/ +/*<asyxml><function type = "real" signature = "exradius(side, triangle)"><code></asyxml>*/ real exradius(side side) {/*<asyxml></code><documentation>Return radius of the excircle tangent with the side 'side' of its triangle. - side=0 means AB, 1 means BC, other means CA. + side = 0 means AB, 1 means BC, other means CA. One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/ real or; - triangle t=side.t; - int n=numarray[abs(side.n)-1]; - if(n == 1) or=exradius(t.A,t.B,t.C); - else if(n == 2) or=exradius(t.B,t.C,t.A); - else or=exradius(t.A,t.C,t.B); + triangle t = side.t; + int n = numarray[abs(side.n) - 1]; + if(n == 1) or = exradius(t.A, t.B, t.C); + else if(n == 2) or = exradius(t.B, t.C, t.A); + else or = exradius(t.A, t.C, t.B); return or; } -/*<asyxml><function type="circle" signature="excircle(side,triangle)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "excircle(side, triangle)"><code></asyxml>*/ circle excircle(side side) {/*<asyxml></code><documentation>Return the excircle tangent with the side 'side' of its triangle. - side=0 means AB, 1 means AC, other means BC. + side = 0 means AB, 1 means AC, other means BC. One must use the predefined sides t.AB, t.AC where 't' is a triangle....</documentation></function></asyxml>*/ circle oc; - int n=numarray[abs(side.n)-1]; - triangle t=side.t; - if(n == 1) oc=excircle(t.A,t.B,t.C); - else if(n == 2) oc=excircle(t.B,t.C,t.A); - else oc=excircle(t.A,t.C,t.B); + int n = numarray[abs(side.n) - 1]; + triangle t = side.t; + if(n == 1) oc = excircle(t.A, t.B, t.C); + else if(n == 2) oc = excircle(t.B, t.C, t.A); + else oc = excircle(t.A, t.C, t.B); return oc; } -/*<asyxml><struct signature="trilinear"><code></asyxml>*/ +/*<asyxml><struct signature = "trilinear"><code></asyxml>*/ struct trilinear {/*<asyxml></code><documentation>Trilinear coordinates 'a:b:c' relative to triangle 't'. - <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation><property type="real" signature="a,b,c"><code></asyxml>*/ - real a,b,c;/*<asyxml></code><documentation>The trilinear coordinates.</documentation></property><property type="triangle" signature="t"><code></asyxml>*/ + <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation><property type = "real" signature = "a, b, c"><code></asyxml>*/ + real a, b, c;/*<asyxml></code><documentation>The trilinear coordinates.</documentation></property><property type = "triangle" signature = "t"><code></asyxml>*/ triangle t;/*<asyxml></code><documentation>The reference triangle.</documentation></property></asyxml>*/ }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="trilinear" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "trilinear" signature = "trilinear(triangle, real, real, real)"><code></asyxml>*/ trilinear trilinear(triangle t, real a, real b, real c) {/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'. - <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ + <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ trilinear ot; - ot.a=a; ot.b=b; ot.c=c; - ot.t=t; + ot.a = a; ot.b = b; ot.c = c; + ot.t = t; return ot; } -/*<asyxml><function type="trilinear" signature="trilinear(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "trilinear" signature = "trilinear(triangle, point)"><code></asyxml>*/ trilinear trilinear(triangle t, point M) {/*<asyxml></code><documentation>Return the trilinear coordinates of 'M' relative to 't'. - <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ + <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ trilinear ot; - pair m=locate(M); + pair m = locate(M); int sameside(pair A, pair B, pair m, pair p) {// Return 1 if 'm' and 'p' are same side of line (AB) else return -1. - pair mil=(A+B)/2; - pair mA=rotate(90,mil)*A; - pair mB=rotate(-90,mil)*A; - return (abs(m-mA) <= abs(m-mB)) == (abs(p-mA) <= abs(p-mB)) ? 1 : -1; + pair mil = (A + B)/2; + pair mA = rotate(90, mil) * A; + pair mB = rotate(-90, mil) * A; + return (abs(m - mA) <= abs(m - mB)) == (abs(p - mA) <= abs(p - mB)) ? 1 : -1; } - real det(pair a, pair b) {return a.x*b.y-a.y*b.x;} - real area(pair a, pair b, pair c){return 0.5*abs(det(a,b)+det(b,c)+det(c,a));} - pair A=t.A, B=t.B, C=t.C; - real t1=area(B,C,m), t2=area(C,A,m), t3=area(A,B,m); - ot.a=sameside(B,C,A,m)*t1/t.a(); - ot.b=sameside(A,C,B,m)*t2/t.b(); - ot.c=sameside(A,B,C,m)*t3/t.c(); - ot.t=t; + real det(pair a, pair b) {return a.x * b.y - a.y * b.x;} + real area(pair a, pair b, pair c){return 0.5 * abs(det(a, b) + det(b, c) + det(c, a));} + pair A = t.A, B = t.B, C = t.C; + real t1 = area(B, C, m), t2 = area(C, A, m), t3 = area(A, B, m); + ot.a = sameside(B, C, A, m) * t1/t.a(); + ot.b = sameside(A, C, B, m) * t2/t.b(); + ot.c = sameside(A, B, C, m) * t3/t.c(); + ot.t = t; return ot; } -/*<asyxml><function type="void" signature="write(trilinear)"><code></asyxml>*/ +/*<asyxml><function type = "void" signature = "write(trilinear)"><code></asyxml>*/ void write(trilinear tri) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - write(format("%f : ", tri.a)+format("%f : ", tri.b)+format("%f",tri.c)); + write(format("%f : ", tri.a) + format("%f : ", tri.b) + format("%f", tri.c)); } -/*<asyxml><function type="point" signature="trilinear(triangle,real,real,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "trilinear(triangle, real, real, real)"><code></asyxml>*/ point point(trilinear tri) {/*<asyxml></code><documentation>Return the trilinear coordinates relative to 't'. - <url href="http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ - triangle t=tri.t; - return masscenter(0.5*t.a()*mass(t.A,tri.a), - 0.5*t.b()*mass(t.B,tri.b), - 0.5*t.c()*mass(t.C,tri.c)); + <url href = "http://mathworld.wolfram.com/TrilinearCoordinates.html"/></documentation></function></asyxml>*/ + triangle t = tri.t; + return masscenter(0.5 * t.a() * mass(t.A, tri.a), + 0.5 * t.b() * mass(t.B, tri.b), + 0.5 * t.c() * mass(t.C, tri.c)); } -/*<asyxml><function type="int[]" signature="tricoef(side)"><code></asyxml>*/ +/*<asyxml><function type = "int[]" signature = "tricoef(side)"><code></asyxml>*/ int[] tricoef(side side) {/*<asyxml></code><documentation>Return an array of integer (values are 0 or 1) which represents 'side'. - For example, side=t.BC will be represented by {0,1,1}.</documentation></function></asyxml>*/ + For example, side = t.BC will be represented by {0, 1, 1}.</documentation></function></asyxml>*/ int[] oi; - int n=numarray[abs(side.n)-1]; + int n = numarray[abs(side.n) - 1]; oi.push((n == 1 || n == 3) ? 1 : 0); oi.push((n == 1 || n == 2) ? 1 : 0); oi.push((n == 2 || n == 3) ? 1 : 0); return oi; } -/*<asyxml><operator type="point" signature="cast(trilinear)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "cast(trilinear)"><code></asyxml>*/ point operator cast(trilinear tri) {/*<asyxml></code><documentation>Cast trilinear to point. One may use the routine 'point(trilinear)' to force the casting.</documentation></operator></asyxml>*/ return point(tri); } -/*<asyxml><typedef type="centerfunction" return="real" params="real,real,real"><code></asyxml>*/ -typedef real centerfunction(real,real,real);/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></typedef></asyxml>*/ +/*<asyxml><typedef type = "centerfunction" return = "real" params = "real, real, real"><code></asyxml>*/ +typedef real centerfunction(real, real, real);/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></typedef></asyxml>*/ -/*<asyxml><function type="trilinear" signature="trilinear(triangle,centerfunction,real,real,real)"><code></asyxml>*/ -trilinear trilinear(triangle t, centerfunction f, real a=t.a(), real b=t.b(), real c=t.c()) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></function></asyxml>*/ - return trilinear(t,f(a,b,c),f(b,c,a),f(c,a,b)); +/*<asyxml><function type = "trilinear" signature = "trilinear(triangle, centerfunction, real, real, real)"><code></asyxml>*/ +trilinear trilinear(triangle t, centerfunction f, real a = t.a(), real b = t.b(), real c = t.c()) +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/TriangleCenterFunction.html"/></documentation></function></asyxml>*/ + return trilinear(t, f(a, b, c), f(b, c, a), f(c, a, b)); } -/*<asyxml><function type="point" signature="symmedian(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "symmedian(triangle)"><code></asyxml>*/ point symmedian(triangle t) {/*<asyxml></code><documentation>Return the symmedian point of 't'.</documentation></function></asyxml>*/ - point A,B,C; - real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, 0, b, c); - B=trilinear(t, a, 0, c); - return intersectionpoint(line(t.A,A),line(t.B,B)); + point A, B, C; + real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, 0, b, c); + B = trilinear(t, a, 0, c); + return intersectionpoint(line(t.A, A), line(t.B, B)); } -/*<asyxml><function type="point" signature="symmedian(side)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "symmedian(side)"><code></asyxml>*/ point symmedian(side side) {/*<asyxml></code><documentation>The symmedian point on the side 'side'.</documentation></function></asyxml>*/ - triangle t=side.t; - int n=numarray[abs(side.n)-1]; + triangle t = side.t; + int n = numarray[abs(side.n) - 1]; if(n == 1) return trilinear(t, t.a(), t.b(), 0); if(n == 2) return trilinear(t, 0, t.b(), t.c()); return trilinear(t, t.a(), 0, t.c()); } -/*<asyxml><function type="line" signature="symmedian(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "symmedian(vertex)"><code></asyxml>*/ line symmedian(vertex V) {/*<asyxml></code><documentation>Return the symmedian passing through 'V'.</documentation></function></asyxml>*/ - return line(point(V),symmedian(V.t)); + return line(point(V), symmedian(V.t)); } -/*<asyxml><function type="triangle" signature="cevian(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "cevian(triangle, point)"><code></asyxml>*/ triangle cevian(triangle t, point P) {/*<asyxml></code><documentation>Return the Cevian triangle with respect of 'P' - <url href="http://mathworld.wolfram.com/CevianTriangle.html"/>.</documentation></function></asyxml>*/ - trilinear tri=trilinear(t,locate(P)); - point A=point(trilinear(t,0,tri.b,tri.c)); - point B=point(trilinear(t,tri.a,0,tri.c)); - point C=point(trilinear(t,tri.a,tri.b,0)); - return triangle(A,B,C); + <url href = "http://mathworld.wolfram.com/CevianTriangle.html"/>.</documentation></function></asyxml>*/ + trilinear tri = trilinear(t, locate(P)); + point A = point(trilinear(t, 0, tri.b, tri.c)); + point B = point(trilinear(t, tri.a, 0, tri.c)); + point C = point(trilinear(t, tri.a, tri.b, 0)); + return triangle(A, B, C); } -/*<asyxml><function type="point" signature="cevian(side,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "cevian(side, point)"><code></asyxml>*/ point cevian(side side, point P) {/*<asyxml></code><documentation>Return the Cevian point on 'side' with respect of 'P'.</documentation></function></asyxml>*/ - triangle t=side.t; - trilinear tri=trilinear(t,locate(P)); - int[] s=tricoef(side); - return point(trilinear(t,s[0]*tri.a, s[1]*tri.b, s[2]*tri.c)); + triangle t = side.t; + trilinear tri = trilinear(t, locate(P)); + int[] s = tricoef(side); + return point(trilinear(t, s[0] * tri.a, s[1] * tri.b, s[2] * tri.c)); } -/*<asyxml><function type="line" signature="cevian(vertex,point)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "cevian(vertex, point)"><code></asyxml>*/ line cevian(vertex V, point P) {/*<asyxml></code><documentation>Return line passing through 'V' and its Cevian image with respect of 'P'.</documentation></function></asyxml>*/ return line(point(V), cevian(opposite(V), P)); } -/*<asyxml><function type="point" signature="gergonne(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "gergonne(triangle)"><code></asyxml>*/ point gergonne(triangle t) {/*<asyxml></code><documentation>Return the Gergonne point of 't'.</documentation></function></asyxml>*/ - real f(real a, real b, real c){return 1/(a*(b+c-a));} - return point(trilinear(t,f)); + real f(real a, real b, real c){return 1/(a * (b + c - a));} + return point(trilinear(t, f)); } -/*<asyxml><function type="point[]" signature="fermat(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "fermat(triangle)"><code></asyxml>*/ point[] fermat(triangle t) {/*<asyxml></code><documentation>Return the Fermat points of 't'.</documentation></function></asyxml>*/ point[] P; - real A=t.alpha(), B=t.beta(), C=t.gamma(); - P.push(point(trilinear(t,1/Sin(A+60), 1/Sin(B+60), 1/Sin(C+60)))); - P.push(point(trilinear(t,1/Sin(A-60), 1/Sin(B-60), 1/Sin(C-60)))); + real A = t.alpha(), B = t.beta(), C = t.gamma(); + P.push(point(trilinear(t, 1/Sin(A + 60), 1/Sin(B + 60), 1/Sin(C + 60)))); + P.push(point(trilinear(t, 1/Sin(A - 60), 1/Sin(B - 60), 1/Sin(C - 60)))); return P; } -/*<asyxml><function type="point" signature="isotomicconjugate(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "isotomicconjugate(triangle, point)"><code></asyxml>*/ point isotomicconjugate(triangle t, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ - if(!inside(t.Path(),locate(M))) abort("isotomic: the point must be inside the triangle."); - trilinear tr=trilinear(t,M); - return point(trilinear(t,1/(t.a()^2*tr.a),1/(t.b()^2*tr.b),1/(t.c()^2*tr.c))); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ + if(!inside(t.Path(), locate(M))) abort("isotomic: the point must be inside the triangle."); + trilinear tr = trilinear(t, M); + return point(trilinear(t, 1/(t.a()^2 * tr.a), 1/(t.b()^2 * tr.b), 1/(t.c()^2 * tr.c))); } -/*<asyxml><function type="line" signature="isotomic(vertex,point)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "isotomic(vertex, point)"><code></asyxml>*/ line isotomic(vertex V, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/>.</documentation></function></asyxml>*/ - side op=opposite(V); - return line(V,rotate(180,midpoint(op))*cevian(op,M)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/>.</documentation></function></asyxml>*/ + side op = opposite(V); + return line(V, rotate(180, midpoint(op)) * cevian(op, M)); } -/*<asyxml><function type="point" signature="isotomic(side,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "isotomic(side, point)"><code></asyxml>*/ point isotomic(side side, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ - return intersectionpoint(isotomic(opposite(side),M), side); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ + return intersectionpoint(isotomic(opposite(side), M), side); } -/*<asyxml><function type="triangle" signature="isotomic(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "isotomic(triangle, point)"><code></asyxml>*/ triangle isotomic(triangle t, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ - return triangle(isotomic(t.BC,M),isotomic(t.CA,M),isotomic(t.AB,M)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsotomicConjugate.html"/></documentation></function></asyxml>*/ + return triangle(isotomic(t.BC, M), isotomic(t.CA, M), isotomic(t.AB, M)); } -/*<asyxml><function type="point" signature="isogonalconjugate(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "isogonalconjugate(triangle, point)"><code></asyxml>*/ point isogonalconjugate(triangle t, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ - trilinear tr=trilinear(t,M); - return point(trilinear(t,1/tr.a,1/tr.b,1/tr.c)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ + trilinear tr = trilinear(t, M); + return point(trilinear(t, 1/tr.a, 1/tr.b, 1/tr.c)); } -/*<asyxml><function type="point" signature="isogonal(side,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "isogonal(side, point)"><code></asyxml>*/ point isogonal(side side, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ - return cevian(side,isogonalconjugate(side.t,M)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ + return cevian(side, isogonalconjugate(side.t, M)); } -/*<asyxml><function type="line" signature="isogonal(vertex,point)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "isogonal(vertex, point)"><code></asyxml>*/ line isogonal(vertex V, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ - return line(V,isogonal(opposite(V),M)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ + return line(V, isogonal(opposite(V), M)); } -/*<asyxml><function type="triangle" signature="isogonal(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "isogonal(triangle, point)"><code></asyxml>*/ triangle isogonal(triangle t, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ - return triangle(isogonal(t.BC,M),isogonal(t.CA,M),isogonal(t.AB,M)); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/IsogonalConjugate.html"/></documentation></function></asyxml>*/ + return triangle(isogonal(t.BC, M), isogonal(t.CA, M), isogonal(t.AB, M)); } -/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "pedal(triangle, point)"><code></asyxml>*/ triangle pedal(triangle t, point M) {/*<asyxml></code><documentation>Return the pedal triangle of 'M' in 't'. - <url href="http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/ - return triangle(projection(t.BC)*M,projection(t.AC)*M,projection(t.AB)*M); + <url href = "http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/ + return triangle(projection(t.BC) * M, projection(t.AC) * M, projection(t.AB) * M); } -/*<asyxml><function type="triangle" signature="pedal(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "pedal(triangle, point)"><code></asyxml>*/ line pedal(side side, point M) {/*<asyxml></code><documentation>Return the pedal line of 'M' cutting 'side'. - <url href="http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/ - return line(M, projection(side)*M); + <url href = "http://mathworld.wolfram.com/PedalTriangle.html"/></documentation></function></asyxml>*/ + return line(M, projection(side) * M); } -/*<asyxml><function type="triangle" signature="antipedal(triangle,point)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "antipedal(triangle, point)"><code></asyxml>*/ triangle antipedal(triangle t, point M) -{/*<asyxml></code><documentation><url href="http://mathworld.wolfram.com/AntipedalTriangle.html"/></documentation></function></asyxml>*/ - trilinear Tm=trilinear(t,M); - real a=Tm.a, b=Tm.b, c=Tm.c; - real CA=Cos(t.alpha()), CB=Cos(t.beta()), CC=Cos(t.gamma()); - point A=trilinear(t,-(b+a*CC)*(c+a*CB),(c+a*CB)*(a+b*CC),(b+a*CC)*(a+c*CB)); - point B=trilinear(t,(c+b*CA)*(b+a*CC),-(c+b*CA)*(a+b*CC),(a+b*CC)*(b+c*CA)); - point C=trilinear(t,(b+c*CA)*(c+a*CB),(a+c*CB)*(c+b*CA),-(a+c*CB)*(b+c*CA)); - return triangle(A,B,C); +{/*<asyxml></code><documentation><url href = "http://mathworld.wolfram.com/AntipedalTriangle.html"/></documentation></function></asyxml>*/ + trilinear Tm = trilinear(t, M); + real a = Tm.a, b = Tm.b, c = Tm.c; + real CA = Cos(t.alpha()), CB = Cos(t.beta()), CC = Cos(t.gamma()); + point A = trilinear(t, -(b + a * CC) * (c + a * CB), (c + a * CB) * (a + b * CC), (b + a * CC) * (a + c * CB)); + point B = trilinear(t, (c + b * CA) * (b + a * CC), -(c + b * CA) * (a + b * CC), (a + b * CC) * (b + c * CA)); + point C = trilinear(t, (b + c * CA) * (c + a * CB), (a + c * CB) * (c + b * CA), -(a + c * CB) * (b + c * CA)); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "extouch(triangle)"><code></asyxml>*/ triangle extouch(triangle t) {/*<asyxml></code><documentation>Return the extouch triangle of the triangle 't'. The extouch triangle of 't' is the triangle formed by the points of tangency of a triangle 't' with its excircles.</documentation></function></asyxml>*/ - point A,B,C; - real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, 0, (a-b+c)/b, (a+b-c)/c); - B=trilinear(t, (-a+b+c)/a, 0, (a+b-c)/c); - C=trilinear(t, (-a+b+c)/a, (a-b+c)/b, 0); - return triangle(A,B,C); + point A, B, C; + real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, 0, (a - b + c)/b, (a + b - c)/c); + B = trilinear(t, (-a + b + c)/a, 0, (a + b - c)/c); + C = trilinear(t, (-a + b + c)/a, (a - b + c)/b, 0); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="extouch(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "extouch(triangle)"><code></asyxml>*/ triangle incentral(triangle t) {/*<asyxml></code><documentation>Return the incentral triangle of the triangle 't'. It is the triangle whose vertices are determined by the intersections of the reference triangle's angle bisectors with the respective opposite sides.</documentation></function></asyxml>*/ - point A,B,C; - // real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, 0, 1, 1); - B=trilinear(t, 1, 0, 1); - C=trilinear(t, 1, 1, 0); - return triangle(A,B,C); + point A, B, C; + // real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, 0, 1, 1); + B = trilinear(t, 1, 0, 1); + C = trilinear(t, 1, 1, 0); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="extouch(side)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "extouch(side)"><code></asyxml>*/ triangle extouch(side side) {/*<asyxml></code><documentation>Return the triangle formed by the points of tangency of the triangle referenced by 'side' with its excircles. One vertex of the returned triangle is on the segment 'side'.</documentation></function></asyxml>*/ - triangle t=side.t; - transform p1=projection((line)t.AB); - transform p2=projection((line)t.AC); - transform p3=projection((line)t.BC); - point EP=excenter(side); - return triangle(p3*EP,p2*EP,p1*EP); + triangle t = side.t; + transform p1 = projection((line)t.AB); + transform p2 = projection((line)t.AC); + transform p3 = projection((line)t.BC); + point EP = excenter(side); + return triangle(p3 * EP, p2 * EP, p1 * EP); } -/*<asyxml><function type="point" signature="bisectorpoint(side)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "bisectorpoint(side)"><code></asyxml>*/ point bisectorpoint(side side) {/*<asyxml></code><documentation>The intersection point of the angle bisector from the opposite point of 'side' with the side 'side'.</documentation></function></asyxml>*/ - triangle t=side.t; - int n=numarray[abs(side.n)-1]; + triangle t = side.t; + int n = numarray[abs(side.n) - 1]; if(n == 1) return trilinear(t, 1, 1, 0); if(n == 2) return trilinear(t, 0, 1, 1); return trilinear(t, 1, 0, 1); } -/*<asyxml><function type="line" signature="bisector(vertex,real)"><code></asyxml>*/ -line bisector(vertex V, real angle=0) +/*<asyxml><function type = "line" signature = "bisector(vertex, real)"><code></asyxml>*/ +line bisector(vertex V, real angle = 0) {/*<asyxml></code><documentation>Return the interior bisector passing through 'V' rotated by angle (in degrees) around 'V'.</documentation></function></asyxml>*/ - return rotate(angle,point(V))*line(point(V),incenter(V.t)); + return rotate(angle, point(V)) * line(point(V), incenter(V.t)); } -/*<asyxml><function type="line" signature="bisector(side)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "bisector(side)"><code></asyxml>*/ line bisector(side side) {/*<asyxml></code><documentation>Return the bisector of the line segment 'side'.</documentation></function></asyxml>*/ return bisector(segment(side)); } -/*<asyxml><function type="point" signature="intouch(side)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "intouch(side)"><code></asyxml>*/ point intouch(side side) {/*<asyxml></code><documentation>The point of tangency on the side 'side' of its incircle.</documentation></function></asyxml>*/ - triangle t=side.t; - real a=t.a(), b=t.b(), c=t.c(); - int n=numarray[abs(side.n)-1]; - if(n == 1) return trilinear(t, b*c/(-a+b+c),a*c/(a-b+c), 0); - if(n == 2) return trilinear(t, 0, a*c/(a-b+c), a*b/(a+b-c)); - return trilinear(t, b*c/(-a+b+c), 0, a*b/(a+b-c)); + triangle t = side.t; + real a = t.a(), b = t.b(), c = t.c(); + int n = numarray[abs(side.n) - 1]; + if(n == 1) return trilinear(t, b * c/(-a + b + c), a * c/(a - b + c), 0); + if(n == 2) return trilinear(t, 0, a * c/(a - b + c), a * b/(a + b - c)); + return trilinear(t, b * c/(-a + b + c), 0, a * b/(a + b - c)); } -/*<asyxml><function type="triangle" signature="intouch(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "intouch(triangle)"><code></asyxml>*/ triangle intouch(triangle t) {/*<asyxml></code><documentation>Return the intouch triangle of the triangle 't'. The intouch triangle of 't' is the triangle formed by the points of tangency of a triangle 't' with its incircles.</documentation></function></asyxml>*/ - point A,B,C; - real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, 0, a*c/(a-b+c), a*b/(a+b-c)); - B=trilinear(t, b*c/(-a+b+c), 0, a*b/(a+b-c)); - C=trilinear(t, b*c/(-a+b+c), a*c/(a-b+c), 0); - return triangle(A,B,C); + point A, B, C; + real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, 0, a * c/(a - b + c), a * b/(a + b - c)); + B = trilinear(t, b * c/(-a + b + c), 0, a * b/(a + b - c)); + C = trilinear(t, b * c/(-a + b + c), a * c/(a - b + c), 0); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="tangential(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "tangential(triangle)"><code></asyxml>*/ triangle tangential(triangle t) {/*<asyxml></code><documentation>Return the tangential triangle of the triangle 't'. The tangential triangle of 't' is the triangle formed by the lines tangent to the circumcircle of the given triangle 't' at its vertices.</documentation></function></asyxml>*/ - point A,B,C; - real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, -a, b, c); - B=trilinear(t, a, -b, c); - C=trilinear(t, a, b, -c); - return triangle(A,B,C); + point A, B, C; + real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, -a, b, c); + B = trilinear(t, a, -b, c); + C = trilinear(t, a, b, -c); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="medial(triangle t)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "medial(triangle t)"><code></asyxml>*/ triangle medial(triangle t) {/*<asyxml></code><documentation>Return the triangle whose vertices are midpoints of the sides of 't'.</documentation></function></asyxml>*/ - return triangle(midpoint(t.BC),midpoint(t.AC),midpoint(t.AB)); + return triangle(midpoint(t.BC), midpoint(t.AC), midpoint(t.AB)); } -/*<asyxml><function type="line" signature="median(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "median(vertex)"><code></asyxml>*/ line median(vertex V) {/*<asyxml></code><documentation>Return median from 'V'.</documentation></function></asyxml>*/ - return line(point(V),midpoint(segment(opposite(V)))); + return line(point(V), midpoint(segment(opposite(V)))); } -/*<asyxml><function type="line" signature="median(side)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "median(side)"><code></asyxml>*/ line median(side side) {/*<asyxml></code><documentation>Return median from the opposite vertex of 'side'.</documentation></function></asyxml>*/ return median(opposite(side)); } -/*<asyxml><function type="triangle" signature="orthic(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "orthic(triangle)"><code></asyxml>*/ triangle orthic(triangle t) {/*<asyxml></code><documentation>Return the triangle whose vertices are endpoints of the altitudes from each of the vertices of 't'.</documentation></function></asyxml>*/ - return triangle(foot(t.BC),foot(t.AC),foot(t.AB)); + return triangle(foot(t.BC), foot(t.AC), foot(t.AB)); } -/*<asyxml><function type="triangle" signature="symmedial(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "symmedial(triangle)"><code></asyxml>*/ triangle symmedial(triangle t) {/*<asyxml></code><documentation>Return the symmedial triangle of 't'.</documentation></function></asyxml>*/ - point A,B,C; - real a=t.a(), b=t.b(), c=t.c(); - A=trilinear(t, 0, b, c); - B=trilinear(t, a, 0, c); - C=trilinear(t, a, b, 0); - return triangle(A,B,C); + point A, B, C; + real a = t.a(), b = t.b(), c = t.c(); + A = trilinear(t, 0, b, c); + B = trilinear(t, a, 0, c); + C = trilinear(t, a, b, 0); + return triangle(A, B, C); } -/*<asyxml><function type="triangle" signature="anticomplementary(triangle)"><code></asyxml>*/ +/*<asyxml><function type = "triangle" signature = "anticomplementary(triangle)"><code></asyxml>*/ triangle anticomplementary(triangle t) {/*<asyxml></code><documentation>Return the triangle which has the given triangle 't' as its medial triangle.</documentation></function></asyxml>*/ - real a=t.a(), b=t.b(), c=t.c(); - real ab=a*b, bc=b*c, ca=c*a; - point A=trilinear(t, -bc, ca, ab); - point B=trilinear(t, bc, -ca, ab); - point C=trilinear(t, bc, ca, -ab); - return triangle(A,B,C); + real a = t.a(), b = t.b(), c = t.c(); + real ab = a * b, bc = b * c, ca = c * a; + point A = trilinear(t, -bc, ca, ab); + point B = trilinear(t, bc, -ca, ab); + point C = trilinear(t, bc, ca, -ab); + return triangle(A, B, C); } -/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,line,bool)"><code></asyxml>*/ -point[] intersectionpoints(triangle t, line l, bool extended=false) +/*<asyxml><function type = "point[]" signature = "intersectionpoints(triangle, line, bool)"><code></asyxml>*/ +point[] intersectionpoints(triangle t, line l, bool extended = false) {/*<asyxml></code><documentation>Return the intersection points. If 'extended' is true, the sides are lines else the sides are segments. - intersectionpoints(line,triangle,bool) is also defined.</documentation></function></asyxml>*/ + intersectionpoints(line, triangle, bool) is also defined.</documentation></function></asyxml>*/ point[] OP; void addpoint(point P) { if(defined(P)) { - bool exist=false; - for (int i=0; i < OP.length; ++i) { - if(P == OP[i]) {exist=true; break;} + bool exist = false; + for (int i = 0; i < OP.length; ++i) { + if(P == OP[i]) {exist = true; break;} } if(!exist) OP.push(P); } } if(extended) { - for (int i=1; i <= 3; ++i) { - addpoint(intersectionpoint(t.line(i),l)); + for (int i = 1; i <= 3; ++i) { + addpoint(intersectionpoint(t.line(i), l)); } } else { - for (int i=1; i <= 3; ++i) { - addpoint(intersectionpoint((segment)t.line(i),l)); + for (int i = 1; i <= 3; ++i) { + addpoint(intersectionpoint((segment)t.line(i), l)); } } return OP; } -point[] intersectionpoints(line l, triangle t, bool extended=false) +point[] intersectionpoints(line l, triangle t, bool extended = false) { return intersectionpoints(t, l, extended); } -/*<asyxml><function type="vector" signature="dir(vertex)"><code></asyxml>*/ +/*<asyxml><function type = "vector" signature = "dir(vertex)"><code></asyxml>*/ vector dir(vertex V) {/*<asyxml></code><documentation>The direction (towards the outside of the triangle) of the interior angle bisector of 'V'.</documentation></function></asyxml>*/ - triangle t=V.t; - if(V.n == 1) return vector(defaultcoordsys,(-dir(t.A--t.B,t.A--t.C))); - if(V.n == 2) return vector(defaultcoordsys,(-dir(t.B--t.A,t.B--t.C))); - return vector(defaultcoordsys,(-dir(t.C--t.A,t.C--t.B))); + triangle t = V.t; + if(V.n == 1) return vector(defaultcoordsys, (-dir(t.A--t.B, t.A--t.C))); + if(V.n == 2) return vector(defaultcoordsys, (-dir(t.B--t.A, t.B--t.C))); + return vector(defaultcoordsys, (-dir(t.C--t.A, t.C--t.B))); } -/*<asyxml><function type="void" signature="lvoid label(picture,Label,vertex,pair,real,pen,filltype)"><code></asyxml>*/ -void label(picture pic=currentpicture, Label L, vertex V, - pair align=dir(V), - real alignFactor=1, - pen p=nullpen, filltype filltype=NoFill) -{/*<asyxml></code><documentation>Draw 'L' on picture 'pic' at vertex 'V' aligned by 'alignFactor*align'.</documentation></function></asyxml>*/ - label(pic,L,locate(point(V)),alignFactor*align,p,filltype); +/*<asyxml><function type = "void" signature = "lvoid label(picture, Label, vertex, pair, real, pen, filltype)"><code></asyxml>*/ +void label(picture pic = currentpicture, Label L, vertex V, + pair align = dir(V), + real alignFactor = 1, + pen p = nullpen, filltype filltype = NoFill) +{/*<asyxml></code><documentation>Draw 'L' on picture 'pic' at vertex 'V' aligned by 'alignFactor * align'.</documentation></function></asyxml>*/ + label(pic, L, locate(point(V)), alignFactor * align, p, filltype); } -/*<asyxml><function type="void" signature="label(picture,Label,Label,Label,triangle,real,real,pen,filltype)"><code></asyxml>*/ -void label(picture pic=currentpicture, Label LA="$A$", - Label LB="$B$", Label LC="$C$", +/*<asyxml><function type = "void" signature = "label(picture, Label, Label, Label, triangle, real, real, pen, filltype)"><code></asyxml>*/ +void label(picture pic = currentpicture, Label LA = "$A$", + Label LB = "$B$", Label LC = "$C$", triangle t, - real alignAngle=0, - real alignFactor=1, - pen p=nullpen, filltype filltype=NoFill) + real alignAngle = 0, + real alignFactor = 1, + pen p = nullpen, filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw labels LA, LB and LC aligned in the rotated (by 'alignAngle' in degrees) direction (towards the outside of the triangle) of the interior angle bisector of vertices. One can individually modify the alignment by setting the Label parameter 'align'.</documentation></function></asyxml>*/ - Label lla=LA.copy(); - lla.align(lla.align,rotate(alignAngle)*locate(dir(t.VA))); - label(pic,LA,t.VA,align=lla.align.dir,alignFactor=alignFactor,p,filltype); - Label llb=LB.copy(); - llb.align(llb.align,rotate(alignAngle)*locate(dir(t.VB))); - label(pic,llb,t.VB,align=llb.align.dir,alignFactor=alignFactor,p,filltype); - Label llc=LC.copy(); - llc.align(llc.align,rotate(alignAngle)*locate(dir(t.VC))); - label(pic,llc,t.VC,align=llc.align.dir,alignFactor=alignFactor,p,filltype); -} - -/*<asyxml><function type="void" signature="show(picture,Label,Label,Label,Label,Label,Label,triangle,pen,filltype)"><code></asyxml>*/ -void show(picture pic=currentpicture, - Label LA="$A$", Label LB="$B$", Label LC="$C$", - Label La="$a$", Label Lb="$b$", Label Lc="$c$", - triangle t, pen p=currentpen, filltype filltype=NoFill) + Label lla = LA.copy(); + lla.align(lla.align, rotate(alignAngle) * locate(dir(t.VA))); + label(pic, LA, t.VA, align = lla.align.dir, alignFactor = alignFactor, p, filltype); + Label llb = LB.copy(); + llb.align(llb.align, rotate(alignAngle) * locate(dir(t.VB))); + label(pic, llb, t.VB, align = llb.align.dir, alignFactor = alignFactor, p, filltype); + Label llc = LC.copy(); + llc.align(llc.align, rotate(alignAngle) * locate(dir(t.VC))); + label(pic, llc, t.VC, align = llc.align.dir, alignFactor = alignFactor, p, filltype); +} + +/*<asyxml><function type = "void" signature = "show(picture, Label, Label, Label, Label, Label, Label, triangle, pen, filltype)"><code></asyxml>*/ +void show(picture pic = currentpicture, + Label LA = "$A$", Label LB = "$B$", Label LC = "$C$", + Label La = "$a$", Label Lb = "$b$", Label Lc = "$c$", + triangle t, pen p = currentpen, filltype filltype = NoFill) {/*<asyxml></code><documentation>Draw triangle and labels of sides and vertices.</documentation></function></asyxml>*/ - pair a=locate(t.A), b=locate(t.B), c=locate(t.C); - draw(pic,a--b--c--cycle,p); - label(pic,LA,a,-dir(a--b,a--c),p,filltype); - label(pic,LB,b,-dir(b--a,b--c),p,filltype); - label(pic,LC,c,-dir(c--a,c--b),p,filltype); - pair aligna=I*unit(c-b), alignb=I*unit(c-a), alignc=I*unit(b-a); - pair mAB=locate(midpoint(t.AB)), mAC=locate(midpoint(t.AC)), mBC=locate(midpoint(t.BC)); - draw(pic,La,b--c, align=rotate(dot(a-mBC,aligna) > 0 ? 180 :0)*aligna,p); - draw(pic,Lb,a--c, align=rotate(dot(b-mAC,alignb) > 0 ? 180 :0)*alignb,p); - draw(pic,Lc,a--b, align=rotate(dot(c-mAB,alignc) > 0 ? 180 :0)*alignc,p); -} - -/*<asyxml><function type="void" signature="draw(picture,triangle,pen,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, triangle t, pen p=currentpen, marker marker=nomarker) + pair a = locate(t.A), b = locate(t.B), c = locate(t.C); + draw(pic, a--b--c--cycle, p); + label(pic, LA, a, -dir(a--b, a--c), p, filltype); + label(pic, LB, b, -dir(b--a, b--c), p, filltype); + label(pic, LC, c, -dir(c--a, c--b), p, filltype); + pair aligna = I * unit(c - b), alignb = I * unit(c - a), alignc = I * unit(b - a); + pair mAB = locate(midpoint(t.AB)), mAC = locate(midpoint(t.AC)), mBC = locate(midpoint(t.BC)); + draw(pic, La, b--c, align = rotate(dot(a - mBC, aligna) > 0 ? 180 :0) * aligna, p); + draw(pic, Lb, a--c, align = rotate(dot(b - mAC, alignb) > 0 ? 180 :0) * alignb, p); + draw(pic, Lc, a--b, align = rotate(dot(c - mAB, alignc) > 0 ? 180 :0) * alignc, p); +} + +/*<asyxml><function type = "void" signature = "draw(picture, triangle, pen, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, triangle t, pen p = currentpen, marker marker = nomarker) {/*<asyxml></code><documentation>Draw sides of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/ - draw(pic,t.Path(),p,marker); + draw(pic, t.Path(), p, marker); } -/*<asyxml><function type="void" signature="draw(picture,triangle[],pen,marker)"><code></asyxml>*/ -void draw(picture pic=currentpicture, triangle[] t, pen p=currentpen, marker marker=nomarker) +/*<asyxml><function type = "void" signature = "draw(picture, triangle[], pen, marker)"><code></asyxml>*/ +void draw(picture pic = currentpicture, triangle[] t, pen p = currentpen, marker marker = nomarker) {/*<asyxml></code><documentation>Draw sides of the triangles 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/ - for(int i=0; i < t.length; ++i) draw(pic,t[i],p,marker); + for(int i = 0; i < t.length; ++i) draw(pic, t[i], p, marker); } -/*<asyxml><function type="void" signature="drawline(picture,triangle,pen)"><code></asyxml>*/ -void drawline(picture pic=currentpicture, triangle t, pen p=currentpen) +/*<asyxml><function type = "void" signature = "drawline(picture, triangle, pen)"><code></asyxml>*/ +void drawline(picture pic = currentpicture, triangle t, pen p = currentpen) {/*<asyxml></code><documentation>Draw lines of the triangle 't' on picture 'pic' using pen 'p'.</documentation></function></asyxml>*/ - draw(t,p); - draw(pic,line(t.A,t.B),p); - draw(pic,line(t.A,t.C),p); - draw(pic,line(t.B,t.C),p); + draw(t, p); + draw(pic, line(t.A, t.B), p); + draw(pic, line(t.A, t.C), p); + draw(pic, line(t.B, t.C), p); } -/*<asyxml><function type="void" signature="dot(picture,triangle,pen)"><code></asyxml>*/ -void dot(picture pic=currentpicture, triangle t, pen p=currentpen) +/*<asyxml><function type = "void" signature = "dot(picture, triangle, pen)"><code></asyxml>*/ +void dot(picture pic = currentpicture, triangle t, pen p = currentpen) {/*<asyxml></code><documentation>Draw a dot at each vertex of 't'.</documentation></function></asyxml>*/ dot(pic, t.A^^t.B^^t.C, p); } @@ -6305,88 +6346,88 @@ void dot(picture pic=currentpicture, triangle t, pen p=currentpen) // *=======================================================* // *.......................INVERSIONS......................* -/*<asyxml><function type="point" signature="inverse(real k,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "inverse(real k, point, point)"><code></asyxml>*/ point inverse(real k, point A, point M) {/*<asyxml></code><documentation>Return the inverse point of 'M' with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/ - return A+k/conj(M-A); + return A + k/conj(M - A); } -/*<asyxml><function type="point" signature="radicalcenter(circle,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "radicalcenter(circle, circle)"><code></asyxml>*/ point radicalcenter(circle c1, circle c2) -{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ - point[] P=standardizecoordsys(c1.C,c2.C); - real k=c1.r^2-c2.r^2; - pair C1=locate(c1.C); - pair C2=locate(c2.C); - pair oop=C2-C1; - pair K=(abs(oop) == 0) ? - (infinity,infinity) : - midpoint(C1--C2)+0.5*k*oop/dot(oop,oop); - return point(P[0].coordsys,K/P[0].coordsys); -} - -/*<asyxml><function type="line" signature="radicalline(circle,circle)"><code></asyxml>*/ +{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ + point[] P = standardizecoordsys(c1.C, c2.C); + real k = c1.r^2 - c2.r^2; + pair C1 = locate(c1.C); + pair C2 = locate(c2.C); + pair oop = C2 - C1; + pair K = (abs(oop) == 0) ? + (infinity, infinity) : + midpoint(C1--C2) + 0.5 * k * oop/dot(oop, oop); + return point(P[0].coordsys, K/P[0].coordsys); +} + +/*<asyxml><function type = "line" signature = "radicalline(circle, circle)"><code></asyxml>*/ line radicalline(circle c1, circle c2) -{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ +{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ if (c1.C == c2.C) abort("radicalline: the centers must be distinct"); - return perpendicular(radicalcenter(c1,c2),line(c1.C,c2.C)); + return perpendicular(radicalcenter(c1, c2), line(c1.C, c2.C)); } -/*<asyxml><function type="point" signature="radicalcenter(circle,circle,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "radicalcenter(circle, circle, circle)"><code></asyxml>*/ point radicalcenter(circle c1, circle c2, circle c3) -{/*<asyxml></code><documentation><url href="http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ - return intersectionpoint(radicalline(c1,c2),radicalline(c1,c3)); +{/*<asyxml></code><documentation><url href = "http://fr.wikipedia.org/wiki/Puissance_d'un_point_par_rapport_%C3%A0_un_cercle"/></documentation></function></asyxml>*/ + return intersectionpoint(radicalline(c1, c2), radicalline(c1, c3)); } -/*<asyxml><struct signature="inversion"><code></asyxml>*/ +/*<asyxml><struct signature = "inversion"><code></asyxml>*/ struct inversion {/*<asyxml></code><documentation>http://mathworld.wolfram.com/Inversion.html</documentation></asyxml>*/ point C; real k; }/*<asyxml></struct></asyxml>*/ -/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/ +/*<asyxml><function type = "inversion" signature = "inversion(real, point)"><code></asyxml>*/ inversion inversion(real k, point C) {/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/ inversion oi; - oi.k=k; - oi.C=C; + oi.k = k; + oi.C = C; return oi; } -/*<asyxml><function type="inversion" signature="inversion(real,point)"><code></asyxml>*/ +/*<asyxml><function type = "inversion" signature = "inversion(real, point)"><code></asyxml>*/ inversion inversion(point C, real k) {/*<asyxml></code><documentation>Return the inversion with respect to 'C' having inversion radius 'k'.</documentation></function></asyxml>*/ - return inversion(k,C); + return inversion(k, C); } -/*<asyxml><function type="inversion" signature="inversion(circle,circle)"><code></asyxml>*/ -inversion inversion(circle c1, circle c2, real sgn=1) +/*<asyxml><function type = "inversion" signature = "inversion(circle, circle)"><code></asyxml>*/ +inversion inversion(circle c1, circle c2, real sgn = 1) {/*<asyxml></code><documentation>Return the inversion which transforms 'c1' to . 'c2' and positive inversion radius if 'sgn > 0'; . 'c2' and negative inversion radius if 'sgn < 0'; . 'c1' and 'c2' to 'c2' if 'sgn = 0'.</documentation></function></asyxml>*/ if(sgn == 0) { - point O=radicalcenter(c1,c2); + point O = radicalcenter(c1, c2); return inversion(O^c1, O); } - real a=abs(c1.r/c2.r); + real a = abs(c1.r/c2.r); if(sgn > 0) { - point O=c1.C+a/abs(1-a)*(c2.C-c1.C); - return inversion(a*abs(abs(O-c2.C)^2-c2.r^2),O); + point O = c1.C + a/abs(1 - a) * (c2.C - c1.C); + return inversion(a * abs(abs(O - c2.C)^2 - c2.r^2), O); } - point O=c1.C+a/abs(1+a)*(c2.C-c1.C); - return inversion(-a*abs(abs(O-c2.C)^2-c2.r^2),O); + point O = c1.C + a/abs(1 + a) * (c2.C - c1.C); + return inversion(-a * abs(abs(O - c2.C)^2 - c2.r^2), O); } -/*<asyxml><function type="inversion" signature="inversion(circle,circle,circle)"><code></asyxml>*/ +/*<asyxml><function type = "inversion" signature = "inversion(circle, circle, circle)"><code></asyxml>*/ inversion inversion(circle c1, circle c2, circle c3) {/*<asyxml></code><documentation>Return the inversion which transform 'c1' to 'c1', 'c2' to 'c2' and 'c3' to 'c3'.</documentation></function></asyxml>*/ - point Rc=radicalcenter(c1,c2,c3); + point Rc = radicalcenter(c1, c2, c3); return inversion(Rc, Rc^c1); } -circle operator cast(inversion i){return circle(i.C, sgn(i.k)*sqrt(abs(i.k)));} -/*<asyxml><function type="circle" signature="circle(inversion)"><code></asyxml>*/ +circle operator cast(inversion i){return circle(i.C, sgn(i.k) * sqrt(abs(i.k)));} +/*<asyxml><function type = "circle" signature = "circle(inversion)"><code></asyxml>*/ circle circle(inversion i) {/*<asyxml></code><documentation>Return the inversion circle of 'i'.</documentation></function></asyxml>*/ return i; @@ -6394,94 +6435,94 @@ circle circle(inversion i) inversion operator cast(circle c) { - return inversion(sgn(c.r)*c.r^2, c.C); + return inversion(sgn(c.r) * c.r^2, c.C); } -/*<asyxml><function type="inversion" signature="inversion(circle)"><code></asyxml>*/ +/*<asyxml><function type = "inversion" signature = "inversion(circle)"><code></asyxml>*/ inversion inversion(circle c) {/*<asyxml></code><documentation>Return the inversion represented by the circle of 'c'.</documentation></function></asyxml>*/ return c; } -/*<asyxml><operator type="point" signature="*(inversion, point)"><code></asyxml>*/ +/*<asyxml><operator type = "point" signature = "*(inversion, point)"><code></asyxml>*/ point operator *(inversion i, point P) -{/*<asyxml></code><documentation>Provide inversion*point.</documentation></operator></asyxml>*/ - return inverse(i.k,i.C,P); +{/*<asyxml></code><documentation>Provide inversion * point.</documentation></operator></asyxml>*/ + return inverse(i.k, i.C, P); } void lineinversion() { - warning("lineinversion","the inversion of the line is not a circle. + warning("lineinversion", "the inversion of the line is not a circle. The returned circle has an infinite radius, circle.l has been set."); } -/*<asyxml><function type="circle" signature="inverse(real,point,line)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "inverse(real, point, line)"><code></asyxml>*/ circle inverse(real k, point A, line l) {/*<asyxml></code><documentation>Return the inverse circle of 'l' with respect to point 'A' and inversion radius 'k'.</documentation></function></asyxml>*/ if(A @ l) { lineinversion(); - circle C=circle(A, infinity); - C.l=l; + circle C = circle(A, infinity); + C.l = l; return C; } - point Ap=inverse(k,A,l.A), Bp=inverse(k,A,l.B); - return circle(A,Ap,Bp); + point Ap = inverse(k, A, l.A), Bp = inverse(k, A, l.B); + return circle(A, Ap, Bp); } -/*<asyxml><operator type="circle" signature="*(inversion,line)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "*(inversion, line)"><code></asyxml>*/ circle operator *(inversion i, line l) -{/*<asyxml></code><documentation>Provide inversion*line for lines that don't pass through the inversion center.</documentation></operator></asyxml>*/ - return inverse(i.k,i.C,l); +{/*<asyxml></code><documentation>Provide inversion * line for lines that don't pass through the inversion center.</documentation></operator></asyxml>*/ + return inverse(i.k, i.C, l); } -/*<asyxml><function type="circle" signature="inverse(real,point,circle)"><code></asyxml>*/ +/*<asyxml><function type = "circle" signature = "inverse(real, point, circle)"><code></asyxml>*/ circle inverse(real k, point A, circle c) {/*<asyxml></code><documentation>Return the inverse circle of 'c' with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/ - if(degenerate(c)) return inverse(k,A,c.l); + if(degenerate(c)) return inverse(k, A, c.l); if(A @ c) { lineinversion(); - point M=rotate(180,c.C)*A, Mp=rotate(90,c.C)*A; - circle oc=circle(A,infinity); - oc.l=line(inverse(k,A,M),inverse(k,A,Mp)); + point M = rotate(180, c.C) * A, Mp = rotate(90, c.C) * A; + circle oc = circle(A, infinity); + oc.l = line(inverse(k, A, M), inverse(k, A, Mp)); return oc; } - point[] P=standardizecoordsys(A,c.C); - real s=k/((P[1].x-P[0].x)^2+(P[1].y-P[0].y)^2-c.r^2); - return circle(P[0]+s*(P[1]-P[0]),abs(s)*c.r); + point[] P = standardizecoordsys(A, c.C); + real s = k/((P[1].x - P[0].x)^2 + (P[1].y - P[0].y)^2 - c.r^2); + return circle(P[0] + s * (P[1]-P[0]), abs(s) * c.r); } -/*<asyxml><operator type="circle" signature="*(inversion,circle)"><code></asyxml>*/ +/*<asyxml><operator type = "circle" signature = "*(inversion, circle)"><code></asyxml>*/ circle operator *(inversion i, circle c) -{/*<asyxml></code><documentation>Provide inversion*circle.</documentation></operator></asyxml>*/ - return inverse(i.k,i.C,c); +{/*<asyxml></code><documentation>Provide inversion * circle.</documentation></operator></asyxml>*/ + return inverse(i.k, i.C, c); } // *.......................INVERSIONS......................* // *=======================================================* // *=======================================================* // *........................FOOTER.........................* -/*<asyxml><function type="point[]" signature="intersectionpoints(line,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, circle)"><code></asyxml>*/ point[] intersectionpoints(line l, circle c) {/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting. - intersectionpoints(circle,line) is also defined.</documentation></function></asyxml>*/ - if(degenerate(c)) return new point[]{intersectionpoint(l,c.l)}; + intersectionpoints(circle, line) is also defined.</documentation></function></asyxml>*/ + if(degenerate(c)) return new point[]{intersectionpoint(l, c.l)}; point[] op; - coordsys R=samecoordsys(l.A,c.C) ? + coordsys R = samecoordsys(l.A, c.C) ? l.A.coordsys : defaultcoordsys; - coordsys Rp=defaultcoordsys; - circle cc=circle(changecoordsys(Rp,c.C),c.r); - point proj=projection(l)*c.C; + coordsys Rp = defaultcoordsys; + circle cc = circle(changecoordsys(Rp, c.C), c.r); + point proj = projection(l) * c.C; if(proj @ cc) { // The line is a tangente of the circle. if(proj @ l) op.push(proj);// line may be a segement... } else { - coordsys Rc=cartesiansystem(c.C,(1,0),(0,1)); - line ll=changecoordsys(Rc,l); - pair[] P=intersectionpoints(ll.A.coordinates, ll.B.coordinates, + coordsys Rc = cartesiansystem(c.C, (1, 0), (0, 1)); + line ll = changecoordsys(Rc, l); + pair[] P = intersectionpoints(ll.A.coordinates, ll.B.coordinates, 1, 0, 1, 0, 0, -c.r^2); - for (int i=0; i<P.length; ++i) { - point inter=changecoordsys(R,point(Rc,P[i])); + for (int i = 0; i < P.length; ++i) { + point inter = changecoordsys(R, point(Rc, P[i])); if(inter @ l) op.push(inter); } } @@ -6490,38 +6531,38 @@ point[] intersectionpoints(line l, circle c) point[] intersectionpoints(circle c, line l) { - return intersectionpoints(l,c); + return intersectionpoints(l, c); } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, ellipse)"><code></asyxml>*/ point[] intersectionpoints(line l, ellipse el) {/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting. - intersectionpoints(ellipse,line) is also defined.</documentation></function></asyxml>*/ - if(el.e == 0) return intersectionpoints(l,(circle)el); - if(degenerate(el)) return new point[]{intersectionpoint(l,el.l)}; + intersectionpoints(ellipse, line) is also defined.</documentation></function></asyxml>*/ + if(el.e == 0) return intersectionpoints(l, (circle)el); + if(degenerate(el)) return new point[]{intersectionpoint(l, el.l)}; point[] op; - coordsys R=samecoordsys(l.A,el.C) ? l.A.coordsys : defaultcoordsys; - coordsys Rp=defaultcoordsys; - line ll=changecoordsys(Rp,l); - ellipse ell=changecoordsys(Rp,el); - circle C=circle(ell.C,ell.a); - point[] Ip=intersectionpoints(ll,C); + coordsys R = samecoordsys(l.A, el.C) ? l.A.coordsys : defaultcoordsys; + coordsys Rp = defaultcoordsys; + line ll = changecoordsys(Rp, l); + ellipse ell = changecoordsys(Rp, el); + circle C = circle(ell.C, ell.a); + point[] Ip = intersectionpoints(ll, C); if (Ip.length > 0 && - (perpendicular(ll,line(ell.F1,Ip[0])) || - perpendicular(ll,line(ell.F2,Ip[0])))) { + (perpendicular(ll, line(ell.F1, Ip[0])) || + perpendicular(ll, line(ell.F2, Ip[0])))) { // http://www.mathcurve.com/courbes2d/ellipse/ellipse.shtml // Définition tangentielle par antipodaire de cercle. // 'l' is a tangent of 'el' - transform t=scale(el.a/el.b,el.F1,el.F2,el.C,rotate(90,el.C)*el.F1); - point inter=inverse(t)*intersectionpoints(C,t*ll)[0]; + transform t = scale(el.a/el.b, el.F1, el.F2, el.C, rotate(90, el.C) * el.F1); + point inter = inverse(t) * intersectionpoints(C, t * ll)[0]; if(inter @ l) op.push(inter); } else { - coordsys Rc=canonicalcartesiansystem(el); - line ll=changecoordsys(Rc,l); - pair[] P=intersectionpoints(ll.A.coordinates, ll.B.coordinates, + coordsys Rc = canonicalcartesiansystem(el); + line ll = changecoordsys(Rc, l); + pair[] P = intersectionpoints(ll.A.coordinates, ll.B.coordinates, 1/el.a^2, 0, 1/el.b^2, 0, 0, -1); - for (int i=0; i<P.length; ++i) { - point inter=changecoordsys(R,point(Rc,P[i])); + for (int i = 0; i < P.length; ++i) { + point inter = changecoordsys(R, point(Rc, P[i])); if(inter @ l) op.push(inter); } } @@ -6530,34 +6571,34 @@ point[] intersectionpoints(line l, ellipse el) point[] intersectionpoints(ellipse el, line l) { - return intersectionpoints(l,el); + return intersectionpoints(l, el); } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,parabola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, parabola)"><code></asyxml>*/ point[] intersectionpoints(line l, parabola p) {/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting. - intersectionpoints(parabola,line) is also defined.</documentation></function></asyxml>*/ + intersectionpoints(parabola, line) is also defined.</documentation></function></asyxml>*/ point[] op; - coordsys R=coordsys(p); - bool tgt=false; - line ll=changecoordsys(R,l), - lv=parallel(p.V,p.D); - point M=intersectionpoint(lv,ll), tgtp; + coordsys R = coordsys(p); + bool tgt = false; + line ll = changecoordsys(R, l), + lv = parallel(p.V, p.D); + point M = intersectionpoint(lv, ll), tgtp; if(finite(M)) {// Test if 'l' is tangent to 'p' - line l1=bisector(line(M,p.F)); - line l2=rotate(90,M)*lv; - point P=intersectionpoint(l1,l2); - tgtp=rotate(180,P)*p.F; - tgt=(tgtp @ l); + line l1 = bisector(line(M, p.F)); + line l2 = rotate(90, M) * lv; + point P = intersectionpoint(l1, l2); + tgtp = rotate(180, P) * p.F; + tgt = (tgtp @ l); } if(tgt) { if(tgtp @ l) op.push(tgtp); } else { - real[] eq=changecoordsys(defaultcoordsys,equation(p)).a; - pair[] tp=intersectionpoints(locate(l.A),locate(l.B),eq); + real[] eq = changecoordsys(defaultcoordsys, equation(p)).a; + pair[] tp = intersectionpoints(locate(l.A), locate(l.B), eq); point inter; - for (int i=0; i < tp.length; ++i) { - inter=point(R,tp[i]/R); + for (int i = 0; i < tp.length; ++i) { + inter = point(R, tp[i]/R); if(inter @ l) op.push(inter); } } @@ -6566,26 +6607,26 @@ point[] intersectionpoints(line l, parabola p) point[] intersectionpoints(parabola p, line l) { - return intersectionpoints(l,p); + return intersectionpoints(l, p); } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, hyperbola)"><code></asyxml>*/ point[] intersectionpoints(line l, hyperbola h) {/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting. - intersectionpoints(hyperbola,line) is also defined.</documentation></function></asyxml>*/ + intersectionpoints(hyperbola, line) is also defined.</documentation></function></asyxml>*/ point[] op; - coordsys R=coordsys(h); - point A=intersectionpoint(l,h.A1), B=intersectionpoint(l,h.A2); - point M=midpoint(segment(A,B)); - bool tgt=M @ h; + coordsys R = coordsys(h); + point A = intersectionpoint(l, h.A1), B = intersectionpoint(l, h.A2); + point M = midpoint(segment(A, B)); + bool tgt = M @ h; if(tgt) { if(M @ l) op.push(M); } else { - real[] eq=changecoordsys(defaultcoordsys,equation(h)).a; - pair[] tp=intersectionpoints(locate(l.A),locate(l.B),eq); + real[] eq = changecoordsys(defaultcoordsys, equation(h)).a; + pair[] tp = intersectionpoints(locate(l.A), locate(l.B), eq); point inter; - for (int i=0; i < tp.length; ++i) { - inter=point(R,tp[i]/R); + for (int i = 0; i < tp.length; ++i) { + inter = point(R, tp[i]/R); if(inter @ l) op.push(inter); } } @@ -6594,491 +6635,491 @@ point[] intersectionpoints(line l, hyperbola h) point[] intersectionpoints(hyperbola h, line l) { - return intersectionpoints(l,h); + return intersectionpoints(l, h); } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,conic)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, conic)"><code></asyxml>*/ point[] intersectionpoints(line l, conic co) {/*<asyxml></code><documentation>Note that the line 'l' may be a segment by casting. - intersectionpoints(conic,line) is also defined.</documentation></function></asyxml>*/ + intersectionpoints(conic, line) is also defined.</documentation></function></asyxml>*/ point[] op; - if(co.e < 1) op=intersectionpoints((ellipse)co,l); + if(co.e < 1) op = intersectionpoints((ellipse)co, l); else - if(co.e == 1) op=intersectionpoints((parabola)co,l); - else op=intersectionpoints((hyperbola)co,l); + if(co.e == 1) op = intersectionpoints((parabola)co, l); + else op = intersectionpoints((hyperbola)co, l); return op; } point[] intersectionpoints(conic co, line l) { - return intersectionpoints(l,co); + return intersectionpoints(l, co); } -/*<asyxml><function type="point[]" signature="intersectionpoints(conic,conic)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(conic, conic)"><code></asyxml>*/ point[] intersectionpoints(conic co1, conic co2) {/*<asyxml></code><documentation>Return the intersection points of the two conics.</documentation></function></asyxml>*/ - if(degenerate(co1)) return intersectionpoints(co1.l[0],co2); - if(degenerate(co2)) return intersectionpoints(co1,co2.l[0]); + if(degenerate(co1)) return intersectionpoints(co1.l[0], co2); + if(degenerate(co2)) return intersectionpoints(co1, co2.l[0]); return intersectionpoints(equation(co1), equation(co2)); } -/*<asyxml><function type="point[]" signature="intersectionpoints(triangle,conic,bool)"><code></asyxml>*/ -point[] intersectionpoints(triangle t, conic co, bool extended=false) +/*<asyxml><function type = "point[]" signature = "intersectionpoints(triangle, conic, bool)"><code></asyxml>*/ +point[] intersectionpoints(triangle t, conic co, bool extended = false) {/*<asyxml></code><documentation>Return the intersection points. If 'extended' is true, the sides are lines else the sides are segments. - intersectionpoints(conic,triangle,bool) is also defined.</documentation></function></asyxml>*/ - if(degenerate(co)) return intersectionpoints(t,co.l[0],extended); + intersectionpoints(conic, triangle, bool) is also defined.</documentation></function></asyxml>*/ + if(degenerate(co)) return intersectionpoints(t, co.l[0], extended); point[] OP; void addpoint(point P[]) { - for (int i=0; i < P.length; ++i) { + for (int i = 0; i < P.length; ++i) { if(defined(P[i])) { - bool exist=false; - for (int j=0; j < OP.length; ++j) { - if(P[i] == OP[j]) {exist=true; break;} + bool exist = false; + for (int j = 0; j < OP.length; ++j) { + if(P[i] == OP[j]) {exist = true; break;} } if(!exist) OP.push(P[i]); }}} if(extended) { - for (int i=1; i <= 3; ++i) { - addpoint(intersectionpoints(t.line(i),co)); + for (int i = 1; i <= 3; ++i) { + addpoint(intersectionpoints(t.line(i), co)); } } else { - for (int i=1; i <= 3; ++i) { - addpoint(intersectionpoints((segment)t.line(i),co)); + for (int i = 1; i <= 3; ++i) { + addpoint(intersectionpoints((segment)t.line(i), co)); } } return OP; } -point[] intersectionpoints(conic co, triangle t, bool extended=false) +point[] intersectionpoints(conic co, triangle t, bool extended = false) { - return intersectionpoints(t,co,extended); + return intersectionpoints(t, co, extended); } -/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(ellipse, ellipse)"><code></asyxml>*/ point[] intersectionpoints(ellipse a, ellipse b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - // if(degenerate(a)) return intersectionpoints(a.l,b); - // if(degenerate(b)) return intersectionpoints(a,b.l);; - return intersectionpoints((conic)a,(conic)b); + // if(degenerate(a)) return intersectionpoints(a.l, b); + // if(degenerate(b)) return intersectionpoints(a, b.l);; + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(ellipse, circle)"><code></asyxml>*/ point[] intersectionpoints(ellipse a, circle b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - // if(degenerate(a)) return intersectionpoints(a.l,b); - // if(degenerate(b)) return intersectionpoints(a,b.l);; - return intersectionpoints((conic)a,(conic)b); + // if(degenerate(a)) return intersectionpoints(a.l, b); + // if(degenerate(b)) return intersectionpoints(a, b.l);; + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(circle,ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(circle, ellipse)"><code></asyxml>*/ point[] intersectionpoints(circle a, ellipse b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints(b,a); + return intersectionpoints(b, a); } -/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,parabola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(ellipse, parabola)"><code></asyxml>*/ point[] intersectionpoints(ellipse a, parabola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - // if(degenerate(a)) return intersectionpoints(a.l,b); - return intersectionpoints((conic)a,(conic)b); + // if(degenerate(a)) return intersectionpoints(a.l, b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(parabola, ellipse)"><code></asyxml>*/ point[] intersectionpoints(parabola a, ellipse b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints(b,a); + return intersectionpoints(b, a); } -/*<asyxml><function type="point[]" signature="intersectionpoints(ellipse,hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(ellipse, hyperbola)"><code></asyxml>*/ point[] intersectionpoints(ellipse a, hyperbola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - // if(degenerate(a)) return intersectionpoints(a.l,b); - return intersectionpoints((conic)a,(conic)b); + // if(degenerate(a)) return intersectionpoints(a.l, b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,ellipse)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(hyperbola, ellipse)"><code></asyxml>*/ point[] intersectionpoints(hyperbola a, ellipse b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints(b,a); + return intersectionpoints(b, a); } -/*<asyxml><function type="point[]" signature="intersectionpoints(circle,parabola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(circle, parabola)"><code></asyxml>*/ point[] intersectionpoints(circle a, parabola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(parabola, circle)"><code></asyxml>*/ point[] intersectionpoints(parabola a, circle b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(circle,hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(circle, hyperbola)"><code></asyxml>*/ point[] intersectionpoints(circle a, hyperbola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(hyperbola, circle)"><code></asyxml>*/ point[] intersectionpoints(hyperbola a, circle b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,parabola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(parabola, parabola)"><code></asyxml>*/ point[] intersectionpoints(parabola a, parabola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(parabola,hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(parabola, hyperbola)"><code></asyxml>*/ point[] intersectionpoints(parabola a, hyperbola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,parabola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(hyperbola, parabola)"><code></asyxml>*/ point[] intersectionpoints(hyperbola a, parabola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(hyperbola,hyperbola)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(hyperbola, hyperbola)"><code></asyxml>*/ point[] intersectionpoints(hyperbola a, hyperbola b) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ - return intersectionpoints((conic)a,(conic)b); + return intersectionpoints((conic)a, (conic)b); } -/*<asyxml><function type="point[]" signature="intersectionpoints(circle,circle)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(circle, circle)"><code></asyxml>*/ point[] intersectionpoints(circle c1, circle c2) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ if(degenerate(c1)) return degenerate(c2) ? - new point[]{intersectionpoint(c1.l,c2.l)} : intersectionpoints(c1.l,c2); - if(degenerate(c2)) return intersectionpoints(c1,c2.l); + new point[]{intersectionpoint(c1.l, c2.l)} : intersectionpoints(c1.l, c2); + if(degenerate(c2)) return intersectionpoints(c1, c2.l); return (c1.C == c2.C) ? new point[] : - intersectionpoints(radicalline(c1,c2),c1); + intersectionpoints(radicalline(c1, c2), c1); } -/*<asyxml><function type="line" signature="tangent(circle,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(circle, abscissa)"><code></asyxml>*/ line tangent(circle c, abscissa x) -{/*<asyxml></code><documentation>Return the tangent of 'c' at 'point(c,x)'.</documentation></function></asyxml>*/ +{/*<asyxml></code><documentation>Return the tangent of 'c' at 'point(c, x)'.</documentation></function></asyxml>*/ if(c.r == 0) abort("tangent: a circle with a radius equals zero has no tangent."); - point M=point(c,x); - return line(rotate(90,M)*c.C,M); + point M = point(c, x); + return line(rotate(90, M) * c.C, M); } -/*<asyxml><function type="line[]" signature="tangents(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "line[]" signature = "tangents(circle, point)"><code></asyxml>*/ line[] tangents(circle c, point M) {/*<asyxml></code><documentation>Return the tangents of 'c' passing through 'M'.</documentation></function></asyxml>*/ line[] ol; - if(inside(c,M)) return ol; + if(inside(c, M)) return ol; if(M @ c) { - ol.push(tangent(c,relabscissa(c,M))); + ol.push(tangent(c, relabscissa(c, M))); } else { - circle cc=circle(c.C,M); - point[] inter=intersectionpoints(c,cc); - for (int i=0; i<inter.length; ++i) - ol.push(tangents(c,inter[i])[0]); + circle cc = circle(c.C, M); + point[] inter = intersectionpoints(c, cc); + for (int i = 0; i < inter.length; ++i) + ol.push(tangents(c, inter[i])[0]); } return ol; } -/*<asyxml><function type="point" signature="point(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(circle, point)"><code></asyxml>*/ point point(circle c, point M) {/*<asyxml></code><documentation>Return the intersection point of 'c' with the half-line '[c.C M)'.</documentation></function></asyxml>*/ - return intersectionpoints(c, line(c.C,false,M))[0]; + return intersectionpoints(c, line(c.C, false, M))[0]; } -/*<asyxml><function type="line" signature="tangent(circle,point)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(circle, point)"><code></asyxml>*/ line tangent(circle c, point M) {/*<asyxml></code><documentation>Return the tangent of 'c' at the intersection point of the half-line'[c.C M)'.</documentation></function></asyxml>*/ - return tangents(c,point(c,M))[0]; + return tangents(c, point(c, M))[0]; } -/*<asyxml><function type="point" signature="point(circle,explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "point(circle, explicit vector)"><code></asyxml>*/ point point(circle c, explicit vector v) {/*<asyxml></code><documentation>Return the intersection point of 'c' with the half-line '[c.C v)'.</documentation></function></asyxml>*/ - return point(c,c.C+v); + return point(c, c.C + v); } -/*<asyxml><function type="line" signature="tangent(circle,explicit vector)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(circle, explicit vector)"><code></asyxml>*/ line tangent(circle c, explicit vector v) {/*<asyxml></code><documentation>Return the tangent of 'c' at the point M so that vec(c.C M) is collinear to 'v' with the same sense.</documentation></function></asyxml>*/ - line ol=tangent(c,c.C+v); - return dot(ol.v,v) > 0 ? ol : reverse(ol); + line ol = tangent(c, c.C + v); + return dot(ol.v, v) > 0 ? ol : reverse(ol); } -/*<asyxml><function type="line" signature="tangent(ellipse,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(ellipse, abscissa)"><code></asyxml>*/ line tangent(ellipse el, abscissa x) -{/*<asyxml></code><documentation>Return the tangent of 'el' at 'point(el,x)'.</documentation></function></asyxml>*/ - point M=point(el,x); - line l1=line(el.F1,M); - line l2=line(el.F2,M); - line ol=(l1 == l2) ? perpendicular(M,l1) : bisector(l1,l2,90,false); +{/*<asyxml></code><documentation>Return the tangent of 'el' at 'point(el, x)'.</documentation></function></asyxml>*/ + point M = point(el, x); + line l1 = line(el.F1, M); + line l2 = line(el.F2, M); + line ol = (l1 == l2) ? perpendicular(M, l1) : bisector(l1, l2, 90, false); return ol; } -/*<asyxml><function type="line[]" signature="tangents(ellipse,point)"><code></asyxml>*/ +/*<asyxml><function type = "line[]" signature = "tangents(ellipse, point)"><code></asyxml>*/ line[] tangents(ellipse el, point M) {/*<asyxml></code><documentation>Return the tangents of 'el' passing through 'M'.</documentation></function></asyxml>*/ line[] ol; - if(inside(el,M)) return ol; + if(inside(el, M)) return ol; if(M @ el) { - ol.push(tangent(el,relabscissa(el,M))); + ol.push(tangent(el, relabscissa(el, M))); } else { - point Mp=samecoordsys(M,el.F2) ? - M : changecoordsys(el.F2.coordsys,M); - circle c=circle(Mp,abs(el.F1-Mp)); - circle cc=circle(el.F2,2*el.a); - point[] inter=intersectionpoints(c,cc); - for (int i=0; i<inter.length; ++i) { - line tl=line(inter[i],el.F2,false); - point[] P=intersectionpoints(tl,el); - ol.push(line(Mp,P[0])); + point Mp = samecoordsys(M, el.F2) ? + M : changecoordsys(el.F2.coordsys, M); + circle c = circle(Mp, abs(el.F1 - Mp)); + circle cc = circle(el.F2, 2 * el.a); + point[] inter = intersectionpoints(c, cc); + for (int i = 0; i < inter.length; ++i) { + line tl = line(inter[i], el.F2, false); + point[] P = intersectionpoints(tl, el); + ol.push(line(Mp, P[0])); } } return ol; } -/*<asyxml><function type="line" signature="tangent(parabola,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(parabola, abscissa)"><code></asyxml>*/ line tangent(parabola p, abscissa x) -{/*<asyxml></code><documentation>Return the tangent of 'p' at 'point(p,x)' (use the Wells method).</documentation></function></asyxml>*/ - line lt=rotate(90,p.V)*line(p.V,p.F); - point P=point(p,x); +{/*<asyxml></code><documentation>Return the tangent of 'p' at 'point(p, x)' (use the Wells method).</documentation></function></asyxml>*/ + line lt = rotate(90, p.V) * line(p.V, p.F); + point P = point(p, x); if(P == p.V) return lt; - point M=midpoint(segment(P,p.F)); - line l=rotate(90,M)*line(P,p.F); - return line(P,projection(lt)*M); + point M = midpoint(segment(P, p.F)); + line l = rotate(90, M) * line(P, p.F); + return line(P, projection(lt) * M); } -/*<asyxml><function type="line[]" signature="tangents(parabola,point)"><code></asyxml>*/ +/*<asyxml><function type = "line[]" signature = "tangents(parabola, point)"><code></asyxml>*/ line[] tangents(parabola p, point M) {/*<asyxml></code><documentation>Return the tangent of 'p' at 'M' (use the Wells method).</documentation></function></asyxml>*/ line[] ol; - if(inside(p,M)) return ol; + if(inside(p, M)) return ol; if(M @ p) { - ol.push(tangent(p,angabscissa(p,M))); + ol.push(tangent(p, angabscissa(p, M))); } else { - point Mt=changecoordsys(coordsys(p),M); - circle c=circle(Mt,p.F); - line l=rotate(90,p.V)*line(p.V,p.F); - point[] R=intersectionpoints(l,c); - for (int i=0; i < R.length; ++i) { - ol.push(line(Mt,R[i])); + point Mt = changecoordsys(coordsys(p), M); + circle c = circle(Mt, p.F); + line l = rotate(90, p.V) * line(p.V, p.F); + point[] R = intersectionpoints(l, c); + for (int i = 0; i < R.length; ++i) { + ol.push(line(Mt, R[i])); } // An other method: http://www.du.edu/~jcalvert/math/parabola.htm - // point[] R=intersectionpoints(p.directrix,c); - // for (int i=0; i < R.length; ++i) { - // ol.push(bisector(segment(p.F,R[i]))); + // point[] R = intersectionpoints(p.directrix, c); + // for (int i = 0; i < R.length; ++i) { + // ol.push(bisector(segment(p.F, R[i]))); // } } return ol; } -/*<asyxml><function type="line" signature="tangent(hyperbola,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(hyperbola, abscissa)"><code></asyxml>*/ line tangent(hyperbola h, abscissa x) -{/*<asyxml></code><documentation>Return the tangent of 'h' at 'point(p,x)'.</documentation></function></asyxml>*/ - point M=point(h,x); - line ol=bisector(line(M,h.F1),line(M,h.F2)); - if(sameside(h.F1,h.F2,ol) || ol == line(h.F1,h.F2)) ol=rotate(90,M)*ol; +{/*<asyxml></code><documentation>Return the tangent of 'h' at 'point(p, x)'.</documentation></function></asyxml>*/ + point M = point(h, x); + line ol = bisector(line(M, h.F1), line(M, h.F2)); + if(sameside(h.F1, h.F2, ol) || ol == line(h.F1, h.F2)) ol = rotate(90, M) * ol; return ol; } -/*<asyxml><function type="line[]" signature="tangents(hyperbola,point)"><code></asyxml>*/ +/*<asyxml><function type = "line[]" signature = "tangents(hyperbola, point)"><code></asyxml>*/ line[] tangents(hyperbola h, point M) {/*<asyxml></code><documentation>Return the tangent of 'h' at 'M'.</documentation></function></asyxml>*/ line[] ol; if(M @ h) { - ol.push(tangent(h,angabscissa(h,M,fromCenter))); + ol.push(tangent(h, angabscissa(h, M, fromCenter))); } else { - coordsys cano=canonicalcartesiansystem(h); - bqe bqe=changecoordsys(cano,equation(h)); - real a=abs(1/(bqe.a[5]*bqe.a[0])), b=abs(1/(bqe.a[5]*bqe.a[2])); - point Mp=changecoordsys(cano,M); - real x0=Mp.x, y0=Mp.y; + coordsys cano = canonicalcartesiansystem(h); + bqe bqe = changecoordsys(cano, equation(h)); + real a = abs(1/(bqe.a[5] * bqe.a[0])), b = abs(1/(bqe.a[5] * bqe.a[2])); + point Mp = changecoordsys(cano, M); + real x0 = Mp.x, y0 = Mp.y; if(abs(x0) > epsgeo) { - real c0=a*y0^2/(b*x0)^2-1/b, - c1=2*a*y0/(b*x0^2), c2=a/x0^2-1; - real[] sol=quadraticroots(c0,c1,c2); + real c0 = a * y0^2/(b * x0)^2 - 1/b, + c1 = 2 * a * y0/(b * x0^2), c2 = a/x0^2 - 1; + real[] sol = quadraticroots(c0, c1, c2); for (real y:sol) { - point tmp=changecoordsys(coordsys(h), point(cano,(a*(1+y*y0/b)/x0,y))); - ol.push(line(M,tmp)); + point tmp = changecoordsys(coordsys(h), point(cano, (a * (1 + y * y0/b)/x0, y))); + ol.push(line(M, tmp)); } } else if(abs(y0) > epsgeo) { - real y=-b/y0, x=sqrt(a*(1+b/y0^2)); - ol.push(line(M,changecoordsys(coordsys(h),point(cano,(x,y))))); - ol.push(line(M,changecoordsys(coordsys(h),point(cano,(-x,y))))); + real y = -b/y0, x = sqrt(a * (1 + b/y0^2)); + ol.push(line(M, changecoordsys(coordsys(h), point(cano, (x, y))))); + ol.push(line(M, changecoordsys(coordsys(h), point(cano, (-x, y))))); }} return ol; } -/*<asyxml><function type="point[]" signature="intersectionpoints(conic,arc)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(conic, arc)"><code></asyxml>*/ point[] intersectionpoints(conic co, arc a) -{/*<asyxml></code><documentation>intersectionpoints(arc,circle) is also defined.</documentation></function></asyxml>*/ +{/*<asyxml></code><documentation>intersectionpoints(arc, circle) is also defined.</documentation></function></asyxml>*/ point[] op; - point[] tp=intersectionpoints(co,(conic)a.el); - for (int i=0; i<tp.length; ++i) + point[] tp = intersectionpoints(co, (conic)a.el); + for (int i = 0; i < tp.length; ++i) if(tp[i] @ a) op.push(tp[i]); return op; } point[] intersectionpoints(arc a, conic co) { - return intersectionpoints(co,a); + return intersectionpoints(co, a); } -/*<asyxml><function type="point[]" signature="intersectionpoints(arc,arc)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(arc, arc)"><code></asyxml>*/ point[] intersectionpoints(arc a1, arc a2) {/*<asyxml></code><documentation></documentation></function></asyxml>*/ point[] op; - point[] tp=intersectionpoints(a1.el,a2.el); - for (int i=0; i<tp.length; ++i) + point[] tp = intersectionpoints(a1.el, a2.el); + for (int i = 0; i < tp.length; ++i) if(tp[i] @ a1 && tp[i] @ a2) op.push(tp[i]); return op; } -/*<asyxml><function type="point[]" signature="intersectionpoints(line,arc)"><code></asyxml>*/ +/*<asyxml><function type = "point[]" signature = "intersectionpoints(line, arc)"><code></asyxml>*/ point[] intersectionpoints(line l, arc a) -{/*<asyxml></code><documentation>intersectionpoints(arc,line) is also defined.</documentation></function></asyxml>*/ +{/*<asyxml></code><documentation>intersectionpoints(arc, line) is also defined.</documentation></function></asyxml>*/ point[] op; - point[] tp=intersectionpoints(a.el,l); - for (int i=0; i<tp.length; ++i) + point[] tp = intersectionpoints(a.el, l); + for (int i = 0; i < tp.length; ++i) if(tp[i] @ a && tp[i] @ l) op.push(tp[i]); return op; } point[] intersectionpoints(arc a, line l) { - return intersectionpoints(l,a); + return intersectionpoints(l, a); } -/*<asyxml><function type="point" signature="arcsubtendedcenter(point,point,real)"><code></asyxml>*/ +/*<asyxml><function type = "point" signature = "arcsubtendedcenter(point, point, real)"><code></asyxml>*/ point arcsubtendedcenter(point A, point B, real angle) {/*<asyxml></code><documentation>Return the center of the arc retuned by the 'arcsubtended' routine.</documentation></function></asyxml>*/ point OM; - point[] P=standardizecoordsys(A,B); - angle=angle%(sgnd(angle)*180); - line bis=bisector(P[0],P[1]); - line AB=line(P[0],P[1]); - return intersectionpoint(bis,rotate(90-angle,A)*AB); + point[] P = standardizecoordsys(A, B); + angle = angle%(sgnd(angle) * 180); + line bis = bisector(P[0], P[1]); + line AB = line(P[0], P[1]); + return intersectionpoint(bis, rotate(90 - angle, A) * AB); } -/*<asyxml><function type="arc" signature="arcsubtended(point,point,real)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "arcsubtended(point, point, real)"><code></asyxml>*/ arc arcsubtended(point A, point B, real angle) {/*<asyxml></code><documentation>Return the arc circle from which the segment AB is saw with the angle 'angle'. - If the point 'M' is on this arc, the oriented angle (MA,MB) is + If the point 'M' is on this arc, the oriented angle (MA, MB) is equal to 'angle'.</documentation></function></asyxml>*/ - point[] P=standardizecoordsys(A,B); - line AB=line(P[0],P[1]); - angle=angle%(sgnd(angle)*180); - point C=arcsubtendedcenter(P[0],P[1],angle); - real BC=degrees(B-C)%360; - real AC=degrees(A-C)%360; - return arc(circle(C,abs(B-C)),BC,AC, angle > 0 ? CCW : CW); + point[] P = standardizecoordsys(A, B); + line AB = line(P[0], P[1]); + angle = angle%(sgnd(angle) * 180); + point C = arcsubtendedcenter(P[0], P[1], angle); + real BC = degrees(B - C)%360; + real AC = degrees(A - C)%360; + return arc(circle(C, abs(B - C)), BC, AC, angle > 0 ? CCW : CW); } -/*<asyxml><function type="arc" signature="arccircle(point,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "arccircle(point, point, point)"><code></asyxml>*/ arc arccircle(point A, point M, point B) {/*<asyxml></code><documentation>Return the CCW arc circle 'AB' passing through 'M'.</documentation></function></asyxml>*/ - circle tc=circle(A,M,B); - real a=degrees(A-tc.C); - real b=degrees(B-tc.C); - arc oa=arc(tc,a,b); + circle tc = circle(A, M, B); + real a = degrees(A - tc.C); + real b = degrees(B - tc.C); + arc oa = arc(tc, a, b); if(!(M @ oa)) oa.direction=!oa.direction; return oa; } -/*<asyxml><function type="arc" signature="arc(ellipse,abscissa,abscissa,bool)"><code></asyxml>*/ -arc arc(ellipse el, explicit abscissa x1, explicit abscissa x2, bool direction=CCW) -{/*<asyxml></code><documentation>Return the arc from 'point(c,x1)' to 'point(c,x2)' in the direction 'direction'.</documentation></function></asyxml>*/ - real a=degrees(point(el,x1)-el.C); - real b=degrees(point(el,x2)-el.C); - arc oa=arc(el,a-el.angle,b-el.angle,fromCenter,direction); +/*<asyxml><function type = "arc" signature = "arc(ellipse, abscissa, abscissa, bool)"><code></asyxml>*/ +arc arc(ellipse el, explicit abscissa x1, explicit abscissa x2, bool direction = CCW) +{/*<asyxml></code><documentation>Return the arc from 'point(c, x1)' to 'point(c, x2)' in the direction 'direction'.</documentation></function></asyxml>*/ + real a = degrees(point(el, x1) - el.C); + real b = degrees(point(el, x2) - el.C); + arc oa = arc(el, a - el.angle, b - el.angle, fromCenter, direction); return oa; } -/*<asyxml><function type="arc" signature="arc(ellipse,point,point,bool)"><code></asyxml>*/ -arc arc(ellipse el, point M, point N, bool direction=CCW) +/*<asyxml><function type = "arc" signature = "arc(ellipse, point, point, bool)"><code></asyxml>*/ +arc arc(ellipse el, point M, point N, bool direction = CCW) {/*<asyxml></code><documentation>Return the arc from 'M' to 'N' in the direction 'direction'. The points 'M' and 'N' must belong to the ellipse 'el'.</documentation></function></asyxml>*/ - return arc(el, relabscissa(el,M), relabscissa(el,N), direction); + return arc(el, relabscissa(el, M), relabscissa(el, N), direction); } -/*<asyxml><function type="arc" signature="arccircle(point,point,real,bool)"><code></asyxml>*/ -arc arccircle(point A, point B, real angle, bool direction=CCW) +/*<asyxml><function type = "arc" signature = "arccircle(point, point, real, bool)"><code></asyxml>*/ +arc arccircle(point A, point B, real angle, bool direction = CCW) {/*<asyxml></code><documentation>Return the arc circle centered on A - from B to rotate(angle,A)*B in the direction 'direction'.</documentation></function></asyxml>*/ - point M=rotate(angle,A)*B; - return arc(circle(A,abs(A-B)),B,M,direction); + from B to rotate(angle, A) * B in the direction 'direction'.</documentation></function></asyxml>*/ + point M = rotate(angle, A) * B; + return arc(circle(A, abs(A - B)), B, M, direction); } -/*<asyxml><function type="arc" signature="arc(explicit arc,abscissa,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "arc(explicit arc, abscissa, abscissa)"><code></asyxml>*/ arc arc(explicit arc a, abscissa x1, abscissa x2) -{/*<asyxml></code><documentation>Return the arc from 'point(a,x1)' to 'point(a,x2)' traversed in the direction of the arc direction.</documentation></function></asyxml>*/ - real a1=angabscissa(a.el, point(a,x1), a.polarconicroutine).x; - real a2=angabscissa(a.el, point(a,x2), a.polarconicroutine).x; +{/*<asyxml></code><documentation>Return the arc from 'point(a, x1)' to 'point(a, x2)' traversed in the direction of the arc direction.</documentation></function></asyxml>*/ + real a1 = angabscissa(a.el, point(a, x1), a.polarconicroutine).x; + real a2 = angabscissa(a.el, point(a, x2), a.polarconicroutine).x; return arc(a.el, a1, a2, a.polarconicroutine, a.direction); } -/*<asyxml><function type="arc" signature="arc(explicit arc,point,point)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "arc(explicit arc, point, point)"><code></asyxml>*/ arc arc(explicit arc a, point M, point N) {/*<asyxml></code><documentation>Return the arc from 'M' to 'N'. The points 'M' and 'N' must belong to the arc 'a'.</documentation></function></asyxml>*/ - return arc(a, relabscissa(a,M), relabscissa(a,N)); + return arc(a, relabscissa(a, M), relabscissa(a, N)); } -/*<asyxml><function type="arc" signature="inverse(real,point,segment)"><code></asyxml>*/ +/*<asyxml><function type = "arc" signature = "inverse(real, point, segment)"><code></asyxml>*/ arc inverse(real k, point A, segment s) {/*<asyxml></code><documentation>Return the inverse arc circle of 's' with respect to point A and inversion radius 'k'.</documentation></function></asyxml>*/ - point Ap=inverse(k,A,s.A), Bp=inverse(k,A,s.B), - M=inverse(k,A,midpoint(s)); - return arccircle(Ap,M,Bp); + point Ap = inverse(k, A, s.A), Bp = inverse(k, A, s.B), + M = inverse(k, A, midpoint(s)); + return arccircle(Ap, M, Bp); } -/*<asyxml><operator type="arc" signature="*(inversion,segment)"><code></asyxml>*/ +/*<asyxml><operator type = "arc" signature = "*(inversion, segment)"><code></asyxml>*/ arc operator *(inversion i, segment s) {/*<asyxml></code><documentation>Provide - inversion*segment.</documentation></operator></asyxml>*/ - return inverse(i.k,i.C,s); + inversion * segment.</documentation></operator></asyxml>*/ + return inverse(i.k, i.C, s); } -/*<asyxml><operator type="path" signature="*(inversion,triangle)"><code></asyxml>*/ +/*<asyxml><operator type = "path" signature = "*(inversion, triangle)"><code></asyxml>*/ path operator *(inversion i, triangle t) -{/*<asyxml></code><documentation>Provide inversion*triangle.</documentation></operator></asyxml>*/ - return (path)(i*segment(t.AB))-- - (path)(i*segment(t.BC))-- - (path)(i*segment(t.CA))--cycle; +{/*<asyxml></code><documentation>Provide inversion * triangle.</documentation></operator></asyxml>*/ + return (path)(i * segment(t.AB))-- + (path)(i * segment(t.BC))-- + (path)(i * segment(t.CA))--cycle; } -/*<asyxml><function type="path" signature="compassmark(pair,pair,real,real)"><code></asyxml>*/ -path compassmark(pair O, pair A, real position, real angle=10) +/*<asyxml><function type = "path" signature = "compassmark(pair, pair, real, real)"><code></asyxml>*/ +path compassmark(pair O, pair A, real position, real angle = 10) {/*<asyxml></code><documentation>Return an arc centered on O with the angle 'angle' so that the position - of 'A' on this arc makes an angle 'position*angle'.</documentation></function></asyxml>*/ - real a=degrees(A-O); - real pa=(a-position*angle)%360, - pb=(a-(position-1)*angle)%360; - real t1=intersect(unitcircle,(0,0)--2*dir(pa))[0]; - real t2=intersect(unitcircle,(0,0)--2*dir(pb))[0]; - int n=length(unitcircle); + of 'A' on this arc makes an angle 'position * angle'.</documentation></function></asyxml>*/ + real a = degrees(A - O); + real pa = (a - position * angle)%360, + pb = (a - (position - 1) * angle)%360; + real t1 = intersect(unitcircle, (0, 0)--2 * dir(pa))[0]; + real t2 = intersect(unitcircle, (0, 0)--2 * dir(pb))[0]; + int n = length(unitcircle); if(t1 >= t2) t1 -= n; - return shift(O)*scale(abs(O-A))*subpath(unitcircle,t1,t2); + return shift(O) * scale(abs(O - A)) * subpath(unitcircle, t1, t2); } -/*<asyxml><function type="line" signature="tangent(explicit arc,abscissa)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(explicit arc, abscissa)"><code></asyxml>*/ line tangent(explicit arc a, abscissa x) -{/*<asyxml></code><documentation>Return the tangent of 'a' at 'point(a,x)'.</documentation></function></asyxml>*/ - abscissa ag=angabscissa(a,point(a,x)); - return tangent(a.el,ag+a.angle1+(a.el.e == 0 ? a.angle0 : 0)); +{/*<asyxml></code><documentation>Return the tangent of 'a' at 'point(a, x)'.</documentation></function></asyxml>*/ + abscissa ag = angabscissa(a, point(a, x)); + return tangent(a.el, ag + a.angle1 + (a.el.e == 0 ? a.angle0 : 0)); } -/*<asyxml><function type="line" signature="tangent(explicit arc,point)"><code></asyxml>*/ +/*<asyxml><function type = "line" signature = "tangent(explicit arc, point)"><code></asyxml>*/ line tangent(explicit arc a, point M) {/*<asyxml></code><documentation>Return the tangent of 'a' at 'M'. The points 'M' must belong to the arc 'a'.</documentation></function></asyxml>*/ - return tangent(a, angabscissa(a,M)); + return tangent(a, angabscissa(a, M)); } // *=======================================================* @@ -7086,36 +7127,36 @@ line tangent(explicit arc a, point M) path square(pair z1, pair z2) { - pair v=z2-z1; - pair z3=z2+I*v; - pair z4=z3-v; + pair v = z2 - z1; + pair z3 = z2 + I * v; + pair z4 = z3 - v; return z1--z2--z3--z4--cycle; } // Draw a perpendicular symbol at z aligned in the direction align -// relative to the path z--z+dir. -void perpendicular(picture pic=currentpicture, pair z, pair align, - pair dir=E, real size=0, pen p=currentpen, - margin margin=NoMargin, filltype filltype=NoFill) +// relative to the path z--z + dir. +void perpendicular(picture pic = currentpicture, pair z, pair align, + pair dir = E, real size = 0, pen p = currentpen, + margin margin = NoMargin, filltype filltype = NoFill) { - perpendicularmark(pic,(point) z,align,dir,size,p,margin,filltype); + perpendicularmark(pic, (point) z, align, dir, size, p, margin, filltype); } // Draw a perpendicular symbol at z aligned in the direction align -// relative to the path z--z+dir(g,0) -void perpendicular(picture pic=currentpicture, pair z, pair align, path g, - real size=0, pen p=currentpen, margin margin=NoMargin, - filltype filltype=NoFill) +// relative to the path z--z + dir(g, 0) +void perpendicular(picture pic = currentpicture, pair z, pair align, path g, + real size = 0, pen p = currentpen, margin margin = NoMargin, + filltype filltype = NoFill) { - perpendicularmark(pic,(point) z,align,dir(g,0),size,p,margin,filltype); + perpendicularmark(pic, (point) z, align, dir(g, 0), size, p, margin, filltype); } // Return an interior arc BAC of triangle ABC, given a radius r > 0. // If r < 0, return the corresponding exterior arc of radius |r|. path arc(explicit pair B, explicit pair A, explicit pair C, real r) { - return arc(A,r,degrees(B-A),degrees(C-A)); + return arc(A, r, degrees(B - A), degrees(C - A)); } // *.......End of compatibility routines........* diff --git a/Master/texmf/asymptote/obj.asy b/Master/texmf/asymptote/obj.asy index 0a6c4ab047c..8dde9341c42 100644 --- a/Master/texmf/asymptote/obj.asy +++ b/Master/texmf/asymptote/obj.asy @@ -59,12 +59,12 @@ struct obj { } close(in); if(verbose) { - write("Number of groups: ",(string) G.length); - write("Groups and their names"); + write("Number of groups: ",G.length); + write("Groups and their names:"); write(G); write("Reading done."); write("Number of faces contained in the groups: "); - for(int j=0; j < g.length; ++j) + for(int j=0; j < G.length; ++j) write(G[j],": ",(string) g[j].length); } return g; diff --git a/Master/texmf/asymptote/palette.asy b/Master/texmf/asymptote/palette.asy index 88f8ae2c42f..9a2d1845604 100644 --- a/Master/texmf/asymptote/palette.asy +++ b/Master/texmf/asymptote/palette.asy @@ -1,5 +1,7 @@ private import graph; +private transform swap=(0,0,0,1,1,0); + typedef bounds range(picture pic, real min, real max); range Range(bool automin=false, real min=-infinity, @@ -26,16 +28,18 @@ void image(frame f, real[][] data, pair initial, pair final, pen[] palette, bool transpose=(initial.x < final.x && initial.y < final.y), transform t=identity(), bool copy=true, bool antialias=false) { - _image(f,transpose ? transpose(data) : copy ? copy(data) : data, - initial,final,palette,t,copy=false,antialias=antialias); + transform T=transpose ? swap : identity(); + _image(f,copy ? copy(data) : data,T*initial,T*final,palette,t*T,copy=false, + antialias=antialias); } void image(frame f, pen[][] data, pair initial, pair final, bool transpose=(initial.x < final.x && initial.y < final.y), transform t=identity(), bool copy=true, bool antialias=false) { - _image(f,transpose ? transpose(data) : copy ? copy(data) : data, - initial,final,t,copy=false,antialias=antialias); + transform T=transpose ? swap : identity(); + _image(f,copy ? copy(data) : data,T*initial,T*final,t*T,copy=false, + antialias=antialias); } // Reduce color palette to approximate range of data relative to "display" @@ -69,8 +73,7 @@ bounds image(picture pic=currentpicture, real[][] f, range range=Full, bool transpose=(initial.x < final.x && initial.y < final.y), bool copy=true, bool antialias=false) { - if(transpose) f=transpose(f); - else if(copy) f=copy(f); + if(copy) f=copy(f); if(copy) palette=copy(palette); real m=min(f); @@ -93,14 +96,15 @@ bounds image(picture pic=currentpicture, real[][] f, range range=Full, initial=Scale(pic,initial); final=Scale(pic,final); + transform T=transpose ? swap : identity(); pic.add(new void(frame F, transform t) { - _image(F,f,initial,final,palette,t,copy=false,antialias=antialias); + _image(F,f,T*initial,T*final,palette,t*T,copy=false,antialias=antialias); },true); pic.addBox(initial,final); return bounds; // Return bounds used for color space } -bounds image(picture pic=currentpicture, real f(real,real), +bounds image(picture pic=currentpicture, real f(real, real), range range=Full, pair initial, pair final, int nx=ngraph, int ny=nx, pen[] palette, bool antialias=false) { @@ -126,26 +130,29 @@ 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) { - if(transpose) data=transpose(data); - else if(copy) data=copy(data); + if(copy) data=copy(data); initial=Scale(pic,initial); final=Scale(pic,final); + transform T=transpose ? swap : identity(); pic.add(new void(frame F, transform t) { - _image(F,data,initial,final,t,copy=false,antialias=antialias); + _image(F,data,T*initial,T*final,t*T,copy=false,antialias=antialias); },true); pic.addBox(initial,final); } void image(picture pic=currentpicture, pen f(int, int), int width, int height, - pair initial, pair final, bool antialias=false) + pair initial, pair final, + bool transpose=(initial.x < final.x && initial.y < final.y), + bool antialias=false) { initial=Scale(pic,initial); final=Scale(pic,final); + transform T=transpose ? swap : identity(); pic.add(new void(frame F, transform t) { - _image(F,f,width,height,initial,final,t,antialias=antialias); + _image(F,f,width,height,T*initial,T*final,t*T,antialias=antialias); },true); pic.addBox(initial,final); } @@ -285,10 +292,11 @@ void palette(picture pic=currentpicture, Label L="", bounds bounds, L.transform(rotate(90)); } real[][] pdata={sequence(palette.length)}; - if(vertical) pdata=transpose(pdata); + transform T=vertical ? swap : identity(); pic.add(new void(frame f, transform t) { - _image(f,pdata,initial,final,palette,t,copy=false,antialias=antialias); + _image(f,pdata,T*initial,T*final,palette,t*T,copy=false, + antialias=antialias); },true); ticklocate locate=ticklocate(initialz,finalz,pic.scale.z,mz.min,mz.max); diff --git a/Master/texmf/asymptote/version.asy b/Master/texmf/asymptote/version.asy index 458d00e534a..9daae3579ad 100644 --- a/Master/texmf/asymptote/version.asy +++ b/Master/texmf/asymptote/version.asy @@ -1 +1 @@ -string VERSION="2.10"; +string VERSION="2.12"; |