real margin=1mm; pen con = solid+1.2; pen fine = solid+0.5; defaultpen(con); pen dash = linetype("4 4"); pen dashdotted=linetype("24 8 0 8"); real height; real textScale = 1.5; real[] topArrowX = {0,0,0,0,0,0,0,0,0,0}; real[] bottomArrowX = {0,0,0,0,0,0,0,0,0,0}; real[] topArrowY = {60,60,60,60,60,60,60,60,60,60}; real[] bottomArrowY = {-60,-60,-60,-60,-60,-60,-60,-60,-60,-60}; string[] topArrowString = {"","","","","","","","","",""}; string[] bottomArrowString = {"","","","","","","","","",""}; real[] bottomLeft = {0,0,0,0,0,0,0,0,0,0}; real[] bottomRight = {0,0,0,0,0,0,0,0,0,0}; real[] middleLeft = {0,0,0,0,0,0,0,0,0,0}; real[] middleRight = {0,0,0,0,0,0,0,0,0,0}; real[] topLeft = {0,0,0,0,0,0,0,0,0,0}; real[] topRight = {0,0,0,0,0,0,0,0,0,0}; real[] shapeShift = {0,0,0,0,0,0,0,0,0,0}; real bottomSign(int left, int right, int numer, int denom) { real leftBound = shapeShift[left] + bottomRight[left]; real rightBound = shapeShift[right] + bottomLeft[right]; return (leftBound + numer / denom * (rightBound - leftBound)); return 1.0; } real topSign(int left, int right, int numer, int denom) { real leftBound = shapeShift[left] + topRight[left]; real rightBound = shapeShift[right] + topLeft[right]; return (leftBound + numer / denom * (rightBound - leftBound)); } picture makeText(string stringOne, real scaleOne, pair shiftOne) { picture pic; picture picOne; object first = draw(picOne,scale(scaleOne*textScale)*stringOne, box,(0,0),0mm, 0mm, invisible); frame frameOne = picOne.fit(); real frameOneMin = xpart(min(frameOne)); real frameOneMax = xpart(max(frameOne)); real frameOneSize = xpart(size(frameOne)); add(pic,frameOne,shiftOne); return pic; } picture makeText(string stringOne, real scaleOne, pair shiftOne, string stringTwo, real scaleTwo, pair shiftTwo) { picture pic; picture picOne; object first = draw(picOne,scale(scaleOne*textScale)*stringOne, box,(0,0),0mm, 0mm, invisible); frame frameOne = picOne.fit(); real frameOneMin = xpart(min(frameOne)); real frameOneMax = xpart(max(frameOne)); real frameOneSize = xpart(size(frameOne)); add(pic,frameOne,shiftOne); picture picTwo; object first = draw(picTwo,scale(scaleTwo*textScale)*stringTwo, box,(0,0),0mm, 0mm, invisible); frame frameTwo = picTwo.fit(); real frameTwoMin = xpart(min(frameTwo)); real frameTwoMax = xpart(max(frameTwo)); real frameTwoSize = xpart(size(frameTwo)); real twoShift = frameOneMax + xpart(shiftTwo) - frameTwoMin; add(pic,frameTwo,(twoShift,0)); return pic; } picture makeText(string stringOne, real scaleOne, pair shiftOne, string stringTwo, real scaleTwo, pair shiftTwo, string stringThree, real scaleThree, pair shiftThree) { picture pic; picture picOne; object first = draw(picOne,scale(scaleOne*textScale)*stringOne, box,(0,0),0mm, 0mm, invisible); frame frameOne = picOne.fit(); real frameOneMin = xpart(min(frameOne)); real frameOneMax = xpart(max(frameOne)); real frameOneSize = xpart(size(frameOne)); add(pic,frameOne,shiftOne); picture picTwo; object first = draw(picTwo,scale(scaleTwo*textScale)*stringTwo, box,(0,0),0mm, 0mm, invisible); frame frameTwo = picTwo.fit(); real frameTwoMin = xpart(min(frameTwo)); real frameTwoMax = xpart(max(frameTwo)); real frameTwoSize = xpart(size(frameTwo)); real twoShift = frameOneMax + xpart(shiftTwo) - frameTwoMin; add(pic,frameTwo,(twoShift,0)); picture picThree; object first = draw(picThree,scale(scaleThree*textScale)*stringThree, box,(0,0),0mm, 0mm, invisible); frame frameThree = picThree.fit(); real frameThreeMin = xpart(min(frameThree)); real frameThreeMax = xpart(max(frameThree)); real frameThreeSize = xpart(size(frameThree)); real threeShift = twoShift + frameTwoMax + xpart(shiftThree) - frameThreeMin; add(pic,frameThree,(threeShift,0)); return pic; } picture makeText(string stringOne, real scaleOne, pair shiftOne, string stringTwo, real scaleTwo, pair shiftTwo, string stringThree, real scaleThree, pair shiftThree, string stringFour, real scaleFour, pair shiftFour) { picture pic; picture picOne; object first = draw(picOne,scale(scaleOne*textScale)*stringOne, box,(0,0),0mm, 0mm, invisible); frame frameOne = picOne.fit(); real frameOneMin = xpart(min(frameOne)); real frameOneMax = xpart(max(frameOne)); real frameOneSize = xpart(size(frameOne)); add(pic,frameOne,shiftOne); picture picTwo; object first = draw(picTwo,scale(scaleTwo*textScale)*stringTwo, box,(0,0),0mm, 0mm, invisible); frame frameTwo = picTwo.fit(); real frameTwoMin = xpart(min(frameTwo)); real frameTwoMax = xpart(max(frameTwo)); real frameTwoSize = xpart(size(frameTwo)); real twoShift = frameOneMax + xpart(shiftTwo) + frameTwoMin; add(pic,frameTwo,(twoShift,0)); picture picThree; object first = draw(picThree,scale(scaleThree*textScale)*stringThree, box,(0,0),0mm, 0mm, invisible); frame frameThree = picThree.fit(); real frameThreeMin = xpart(min(frameThree)); real frameThreeMax = xpart(max(frameThree)); real frameThreeSize = xpart(size(frameThree)); real threeShift = twoShift + frameTwoMax + xpart(shiftThree) + frameThreeMin; add(pic,frameThree,(threeShift,0)); picture picFour; object first = draw(picFour,scale(scaleFour*textScale)*stringFour, box,(0,0),0mm, 0mm, invisible); frame frameFour = picFour.fit(); real frameFourMin = xpart(min(frameFour)); real frameFourMax = xpart(max(frameFour)); real frameFourSize = xpart(size(frameFour)); real fourShift = threeShift + frameThreeMax + xpart(shiftFour) + frameFourMin; add(pic,frameFour,(fourShift,0)); return pic; } frame barePic(picture pic, int minX, int minY, int i) { frame f = pic.fit(); real fMin = xpart(min(f)); real fMax = xpart(max(f)); real fSize = xpart(size(f)); real fYSize = ypart(size(f)); bottomArrowX[i] = fMin + fSize/2; real fHeight = ypart(size(f)); bottomArrowY[i] = - fHeight/2 - 0; topArrowX[i] = fMin + fSize/2; real fHeight = ypart(size(f)); topArrowY[i] = fHeight/2 + 0; bottomLeft[i] = fMin; bottomRight[i] = fMax; topLeft[i] = fMin; topRight[i] = fMax; return f; } frame minBox(frame f, int minX, int minY) { real xSize = xpart(size(f)); real ySize = ypart(size(f)); if (xSize < minX) { real shift = (minX - xSize)/2; box(f, shift, 0, invisible); } if (ySize < minY) { real yShift = (minY - ySize)/2; box(f, 0, yShift, invisible); } return f; } frame plainShape(frame bottomFrame, frame topFrame, int i) { frame pic; ellipse(bottomFrame, 0mm, 0mm); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameSize = xpart(size(bottomFrame)); real bottomCentre = bottomFrameMin + bottomFrameSize/2; add(pic,bottomFrame,(0,0)); ellipse(topFrame, 0mm, 0mm); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameSize = xpart(size(topFrame)); real topCentre = topFrameMin + topFrameSize/2; real topShift = bottomCentre - topCentre; add(pic,topFrame,(topShift,height)); draw(pic,shift(topShift,height)*point(topFrame,shift(0,0)*S) --shift(0, 0)*point(bottomFrame,shift(0,0)*N)); real l = xpart(min(pic)); real r = xpart(max(pic)); bottomLeft[i] = bottomFrameMin; bottomRight[i] = bottomFrameMax; topLeft[i] = topFrameMin + topShift; topRight[i] = topFrameMax + topShift; bottomArrowX[i] = bottomFrameMin + bottomFrameSize/2; real bottomFrameHeight = ypart(size(bottomFrame)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; topArrowX[i] = topFrameMin + topFrameSize/2; real topFrameHeight = ypart(size(topFrame)); topArrowY[i] = topFrameHeight/2 + 0; return pic; } frame plainShape(bool dashed, frame bottomFrame, frame topFrame, int i) { frame pic; ellipse(bottomFrame, 0mm, 0mm); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameSize = xpart(size(bottomFrame)); real bottomCentre = bottomFrameMin + bottomFrameSize/2; add(pic,bottomFrame,(0,0)); ellipse(topFrame, 0mm, 0mm); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameSize = xpart(size(topFrame)); real topCentre = topFrameMin + topFrameSize/2; real topShift = bottomCentre - topCentre; add(pic,topFrame,(topShift,height)); if(dashed) { draw(pic,shift(topShift,height)*point(topFrame,shift(0,0)*S) --shift(0, 0)*point(bottomFrame,shift(0,0)*N),dash); } else { draw(pic,shift(topShift,height)*point(topFrame,shift(0,0)*S) --shift(0, 0)*point(bottomFrame,shift(0,0)*N)); } real l = xpart(min(pic)); real r = xpart(max(pic)); bottomLeft[i] = bottomFrameMin; bottomRight[i] = bottomFrameMax; topLeft[i] = topFrameMin + topShift; topRight[i] = topFrameMax + topShift; bottomArrowX[i] = bottomFrameMin + bottomFrameSize/2; real bottomFrameHeight = ypart(size(bottomFrame)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; topArrowX[i] = topFrameMin + topFrameSize/2; real topFrameHeight = ypart(size(topFrame)); topArrowY[i] = topFrameHeight/2 + 0; return pic; } frame graph(string x, string y, string v, path curve) { frame f; // path xaxis = ((0,0)--(70,0),Arrow(6bp)); // path yaxis = ((0,0)--(0,50),Arrow(6bp)); draw(f,(0,0)--(80,0),Arrow(6bp)); draw(f,(0,0)--(0,53),Arrow(6bp)); label(f,x,(75,-10)); label(f,y,(-16,45)); label(f,"$a$",(15,-8)); label(f,v,(39,-8)); label(f,"$b$",(53,-7)); draw(f,(8,8){up}..(45,40){right}..(60,45){up}); draw(f,(15,0)--(15,25),fine); draw(f,(39,0)--(39,35),fine); draw(f,(53,0)--(53,39),fine); // path p = (15,0)--(39,0)--(39,35)--(15,25)--cycle; fill(f,(15,1)--(39,1)--(39,39)..(27,35)..(15,25)--cycle, lightgrey); label(f,"$A$",(25,17)); box(f,2,2,invisible); return f; } frame graphDash(string x, string y, path curve) { frame f; // path xaxis = ((0,0)--(70,0),Arrow(6bp)); // path yaxis = ((0,0)--(0,50),Arrow(6bp)); draw(f,(0,0)--(80,0),Arrow(6bp)); draw(f,(0,0)--(0,53),Arrow(6bp)); label(f,x,(75,-10)); label(f,y,(-16,45)); label(f,"$a$",(15,-8)); // label(f,v,(39,-8)); frame dashh; box(dashh,4,4,invisible); ellipse(dashh,0,0,dash); add(f,dashh,(39,-10)); label(f,"$b$",(53,-7)); draw(f,(8,8){up}..(45,40){right}..(60,45){up}); draw(f,(15,0)--(15,25),fine); draw(f,(39,0)--(39,35),fine); draw(f,(53,0)--(53,39),fine); // path p = (15,0)--(39,0)--(39,35)--(15,25)--cycle; fill(f,(15,1)--(39,1)--(39,39)..(27,35)..(15,25)--cycle, lightgrey); label(f,"$A$",(25,17)); box(f,2,2,invisible); return f; } frame integrationShape(frame bottomFrame, frame topFrame, int i) { frame pic; ellipse(bottomFrame, 0mm, 0mm); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameSize = xpart(size(bottomFrame)); real bottomCentre = bottomFrameMin + bottomFrameSize/2; real bottomFrameYMin = ypart(min(bottomFrame)); real bottomFrameYMax = ypart(max(bottomFrame)); real bottomFrameYSize = ypart(size(bottomFrame)); real bottomYCentre = bottomFrameYMin + bottomFrameYSize/2; add(pic,bottomFrame,(0, - bottomYCentre)); ellipse(topFrame, 0mm, 0mm); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameSize = xpart(size(topFrame)); real topCentre = topFrameMin + topFrameSize/2; real topShift = bottomCentre - topCentre; add(pic,topFrame,(topShift,height)); pair top = shift(topShift,height - 15)*point(topFrame,shift(0,0)*S); pair bottom = shift(0, 15 - bottomYCentre)*point(bottomFrame,shift(0,0)*N); pair middle = (top+bottom)/2; path arrowPath = shift(0,20)*middle--top; path basePath = shift(0,-20)*middle--bottom; draw(pic,arrowPath,Arrow(6bp)); draw(pic,basePath); label(pic,scale(1.0)*"$get\ the\ area\ A\ as$",shift(0,7)*middle); label(pic,scale(1.0)*"$a\ function\ of\ x$",shift(0,-7)*middle); real l = xpart(min(pic)); real r = xpart(max(pic)); bottomLeft[i] = bottomFrameMin; bottomRight[i] = bottomFrameMax; topLeft[i] = topFrameMin + topShift; topRight[i] = topFrameMax + topShift; bottomArrowX[i] = bottomFrameMin + bottomFrameSize/2; real bottomFrameHeight = ypart(size(bottomFrame)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; topArrowX[i] = topFrameMin + topFrameSize/2; real topFrameHeight = ypart(size(topFrame)); topArrowY[i] = topFrameHeight/2 + 0; return pic; } frame integrationShape(bool dashed, frame bottomFrame, frame topFrame, int i) { frame dashh; box(dashh,4,4,invisible); ellipse(dashh,0,0,dash); frame pic; ellipse(bottomFrame, 0mm, 0mm); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameSize = xpart(size(bottomFrame)); real bottomCentre = bottomFrameMin + bottomFrameSize/2; real bottomFrameYMin = ypart(min(bottomFrame)); real bottomFrameYMax = ypart(max(bottomFrame)); real bottomFrameYSize = ypart(size(bottomFrame)); real bottomYCentre = bottomFrameYMin + bottomFrameYSize/2; add(pic,bottomFrame,(0, - bottomYCentre)); // add(topFrame,dash ellipse(topFrame, 0mm, 0mm); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameSize = xpart(size(topFrame)); real topCentre = topFrameMin + topFrameSize/2; real topShift = bottomCentre - topCentre; add(pic,topFrame,(topShift,height)); pair top = shift(topShift,height - 15)*point(topFrame,shift(0,0)*S); pair bottom = shift(0, 15 - bottomYCentre)*point(bottomFrame,shift(0,0)*N); pair middle = (top+bottom)/2; path arrowPath = shift(0,20)*middle--top; path basePath = shift(0,-20)*middle--bottom; draw(pic,arrowPath,Arrow(6bp)); draw(pic,basePath); label(pic,scale(1.0)*"$get\ the\ area\ A\ as$",shift(0,7)*middle); if (dashed) { label(pic,scale(1.0)*"$a\ function\ of\ \ \ $",shift(0,-7)*middle); add(pic,dashh,shift(42,-7)*middle); } else { label(pic,scale(1.0)*"$a\ function\ of\ x$",shift(0,-7)*middle); } real l = xpart(min(pic)); real r = xpart(max(pic)); bottomLeft[i] = bottomFrameMin; bottomRight[i] = bottomFrameMax; topLeft[i] = topFrameMin + topShift; topRight[i] = topFrameMax + topShift; bottomArrowX[i] = bottomFrameMin + bottomFrameSize/2; real bottomFrameHeight = ypart(size(bottomFrame)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; topArrowX[i] = topFrameMin + topFrameSize/2; real topFrameHeight = ypart(size(topFrame)); topArrowY[i] = topFrameHeight/2 + 0; return pic; } frame plainShape(frame bottomFrame, frame middleFrame, frame topFrame, int i) { frame pic; ellipse(bottomFrame, 0mm, 0mm); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameSize = xpart(size(bottomFrame)); real bottomCentre = bottomFrameMin + bottomFrameSize/2; add(pic,bottomFrame,(0,0)); ellipse(middleFrame, 0mm, 0mm); real middleFrameMin = xpart(min(middleFrame)); real middleFrameMax = xpart(max(middleFrame)); real middleFrameSize = xpart(size(middleFrame)); real middleCentre = middleFrameMin + middleFrameSize/2; real middleShift = bottomCentre - middleCentre; add(pic,middleFrame,(middleShift,height)); ellipse(topFrame, 0mm, 0mm); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameSize = xpart(size(topFrame)); real topCentre = topFrameMin + topFrameSize/2; real topShift = middleCentre - topCentre; add(pic,topFrame,(topShift,height*2)); draw(pic,shift(topShift,height*2)*point(topFrame,shift(0,0)*S) --shift(0, height)*point(middleFrame,shift(0,0)*N)); draw(pic,shift(middleShift,height)*point(middleFrame,shift(0,0)*S) --shift(0, 0)*point(bottomFrame,shift(0,0)*N)); real l = xpart(min(pic)); real r = xpart(max(pic)); bottomLeft[i] = bottomFrameMin; bottomRight[i] = bottomFrameMax; middleLeft[i] = middleFrameMin + middleShift; middleRight[i] = middleFrameMax + middleShift; topLeft[i] = topFrameMin + topShift; topRight[i] = topFrameMax + topShift; bottomArrowX[i] = bottomFrameMin + bottomFrameSize/2; real bottomFrameHeight = ypart(size(bottomFrame)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; topArrowX[i] = topFrameMin + topFrameSize/2; real topFrameHeight = ypart(size(topFrame)); topArrowY[i] = topFrameHeight/2 + 0; return pic; } frame chainExtension(frame leftFrame, frame dashFrame) { ellipse(dashFrame ,0mm, 1mm, dash); real dashMin = xpart(min(dashFrame)); real leftFrameMax = xpart(max(leftFrame)); real leftShift = dashMin - 5 - leftFrameMax; add(dashFrame, leftFrame, (leftShift,0)); return dashFrame; } frame makeChain(frame obDashFrame, frame leftTextFrame, frame rightTextFrame, int minX, int minY) { real obDashMin = xpart(min(obDashFrame)); real obDashMax = xpart(max(obDashFrame)); real leftTextFrameMin = xpart(min(leftTextFrame)); real leftTextFrameMax = xpart(max(leftTextFrame)); real leftTextFrameWidth = leftTextFrameMax - leftTextFrameMin; real leftShift = obDashMin - 5 - leftTextFrameMax; add(obDashFrame, leftTextFrame, (leftShift,0)); real rightTextFrameMin = xpart(min(rightTextFrame)); real rightTextFrameMax = xpart(max(rightTextFrame)); real rightTextFrameWidth = rightTextFrameMax - rightTextFrameMin; real rightShift = obDashMax + 3 - rightTextFrameMin; add(obDashFrame, rightTextFrame, (rightShift,0)); box(obDashFrame, 0mm,0mm, invisible); real fMin = xpart(min(obDashFrame)); real fMax = xpart(max(obDashFrame)); real fSize = xpart(size(obDashFrame)); real fYSize = ypart(size(obDashFrame)); if (fSize < minX * 1mm) { real shift = (minX * 1mm - fSize)/2; box(obDashFrame, shift, 0, invisible); } if (fYSize < minY * 1mm) { real yShift = (30 - fYSize)/2; box(obDashFrame, 0, yShift, invisible); } return obDashFrame; } frame makeChain(bool show, picture obDashPic, string leftString, string rightString, int minX, int minY) { frame obDashFrame = obDashPic.fit(); real obDashMin = xpart(min(obDashFrame)); real obDashMax = xpart(max(obDashFrame)); picture leftTextPic; picture leftTextText; label(leftTextText,scale(textScale)*leftString,(0,0)); frame leftTextFrame = leftTextText.fit(); real leftTextFrameMin = xpart(min(leftTextFrame)); real leftTextFrameMax = xpart(max(leftTextFrame)); real leftTextFrameWidth = leftTextFrameMax - leftTextFrameMin; real leftTextFrameHeight = ypart(size(leftTextFrame)); real leftShift = obDashMin - 5 - leftTextFrameMax; if (show) { add(obDashPic, leftTextFrame, (leftShift,0)); } else { frame leftTextBlankFrame = leftTextPic.fit(); box(leftTextBlankFrame, leftTextFrameWidth, leftTextFrameHeight, invisible); add(obDashPic, leftTextBlankFrame, (leftShift,0)); } picture rightTextPic; picture rightTextText; label(rightTextText,scale(textScale)*rightString,(0,5)); frame rightTextFrame = rightTextText.fit(); real rightTextFrameMin = xpart(min(rightTextFrame)); real rightTextFrameMax = xpart(max(rightTextFrame)); real rightTextFrameWidth = rightTextFrameMax - rightTextFrameMin; real rightTextFrameHeight = ypart(size(rightTextFrame)); real rightShift = obDashMax + 3 - rightTextFrameMin; if (show) { add(obDashPic, rightTextFrame, (rightShift,0)); } else { frame rightTextBlankFrame = rightTextPic.fit(); box(rightTextBlankFrame, rightTextFrameWidth, rightTextFrameHeight, invisible); add(obDashPic, rightTextBlankFrame, (rightShift,0)); } frame f = obDashPic.fit(); box(f, 0mm,0mm, invisible); // path e = ellipse(obFrame, -1mm,3mm, invisible); // fill(obFrame,e,white); // draw(obFrame,e); real fMin = xpart(min(f)); real fMax = xpart(max(f)); real fSize = xpart(size(f)); real fYSize = ypart(size(f)); if (fSize < minX * 1mm) { real shift = (minX * 1mm - fSize)/2; box(f, shift, 0, invisible); } if (fYSize < minY * 1mm) { real yShift = (30 - fYSize)/2; box(f, 0, yShift, invisible); } return f; } frame makeExpChain(frame obDashFrame, frame leftTextFrame, frame rightTextFrame, int minX, int minY) { real obDashMin = xpart(min(obDashFrame)); real obDashMax = xpart(max(obDashFrame)); real obDashYMin = ypart(min(obDashFrame)); real leftTextFrameMin = xpart(min(leftTextFrame)); real leftTextFrameMax = xpart(max(leftTextFrame)); real leftTextFrameYMax = ypart(max(leftTextFrame)); real leftTextFrameWidth = leftTextFrameMax - leftTextFrameMin; pair leftShift = (obDashMin + 2 - leftTextFrameMax, obDashYMin + 4 - leftTextFrameYMax); add(obDashFrame, leftTextFrame, leftShift); real rightTextFrameMin = xpart(min(rightTextFrame)); real rightTextFrameMax = xpart(max(rightTextFrame)); real rightTextFrameWidth = rightTextFrameMax - rightTextFrameMin; real rightShift = obDashMax + 3 - rightTextFrameMin; add(obDashFrame, rightTextFrame, (rightShift,0)); box(obDashFrame, 0mm,0mm, invisible); real fMin = xpart(min(obDashFrame)); real fMax = xpart(max(obDashFrame)); real fSize = xpart(size(obDashFrame)); real fYSize = ypart(size(obDashFrame)); if (fSize < minX * 1mm) { real shift = (minX * 1mm - fSize)/2; box(obDashFrame, shift, 0, invisible); } if (fYSize < minY * 1mm) { real yShift = (30 - fYSize)/2; box(obDashFrame, 0, yShift, invisible); } return obDashFrame; } frame makeFractionChain(frame multiplier, frame leftBottomFrame, frame obDashFrame, frame rightBottomFrame, frame fTop, bool root, int minX, int minY) { frame f = makeChain(obDashFrame, leftBottomFrame, rightBottomFrame, 0, 0); real fXMin = xpart(min(f)); real fXMax = xpart(max(f)); real fXSize= xpart(size(f)); real fYMin = ypart(min(f)); real fYMax = ypart(max(f)); real fYSize= ypart(size(f)); real fXCentre = fXMin + (fXMax - fXMin) / 2; pair leftEnd = (fXMin, fYMax + 4); pair rightEnd = (fXMax, fYMax + 4); pair bottom = shift(-5, -0.9*fYSize)*leftEnd; pair end = shift(-3, 9)*bottom; path divider; if (root == true) { path rootSign = rightEnd--leftEnd--bottom--end; draw(f,rootSign); divider = shift(-5, 5)*leftEnd--shift(5, 5)*rightEnd; } else { divider = leftEnd--rightEnd; } draw(f,divider); real fTopXMin = xpart(min(fTop)); real fTopXMax = xpart(max(fTop)); real fTopYMin = ypart(min(fTop)); real fTopYMax = ypart(max(fTop)); real fTopXCentre = fTopXMin + (fTopXMax - fTopXMin) / 2; pair topShift; if (root == true) { topShift = (fXCentre - fTopXCentre, fYMax + 10 - fTopYMin); } else { topShift = (fXCentre - fTopXCentre, fYMax + 5 - fTopYMin); } add(f, fTop, topShift); fXMin = xpart(min(f)); real fYMin = ypart(min(f)); real fYMax = ypart(max(f)); real fYCentre = fYMin + (fYMax - fYMin) / 2; frame left = multiplier; real leftYMin = ypart(min(left)); real leftYMax = ypart(max(left)); real leftYCentre = leftYMin + (leftYMax - leftYMin) / 2; real leftXMax = xpart(max(left)); pair leftShift = (fXMin - 6 - leftXMax, fYCentre - leftYCentre); add(f, left, leftShift); return f; } frame chainShape(int stage, frame bottomMultiplier, frame bottomLeftFrame, int bottomNormalExpFracOrRootFrac, frame bottomDashFrame, frame bottomRightFrame, frame bottomTopFrame, frame topMultiplier, frame topLeftFrame, int topNormalExpFracOrRootFrac, frame topDashFrame, frame topRightFrame, frame topTopFrame, frame byProdFrame, int i) { picture pic; path bottomDashE = ellipse(bottomDashFrame,0mm,1mm, dash); picture emptyBottom; draw(emptyBottom, bottomDashE, dash); draw(bottomDashFrame, bottomDashE, dash); frame bottomFrame; if (stage == 4) { // frame bottomFrame = makeChain(emptyBottom, bottomLeftFrame, bottomRightFrame, 30, 30); } else if (stage == 0 | stage == 3 | stage == 5) { } else { bottomDashFrame = emptyBottom.fit(); // bottomFrame = makeChain(false, bottomDashText, bottomLeftString, bottomRightString, 30, 30); } if (bottomNormalExpFracOrRootFrac == 0) { bottomFrame = makeChain(bottomDashFrame, bottomLeftFrame, bottomRightFrame, 30, 30); } else if (bottomNormalExpFracOrRootFrac == 1) { bottomFrame = makeExpChain(bottomDashFrame, bottomLeftFrame, bottomRightFrame, 30, 20); } else if (bottomNormalExpFracOrRootFrac == 2) { bottomFrame = makeFractionChain(bottomMultiplier, bottomLeftFrame, bottomDashFrame, bottomRightFrame, bottomTopFrame, false, 30, 20); } else if (bottomNormalExpFracOrRootFrac == 3) { bottomFrame = makeFractionChain(bottomMultiplier, bottomLeftFrame, bottomDashFrame, bottomRightFrame, bottomTopFrame, true, 30, 20); } else { } path bottomE = ellipse(bottomFrame, -4mm,3mm, invisible); if (stage == 0 | stage == 5) { draw (bottomFrame, bottomE); } real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameWidth = bottomFrameMax - bottomFrameMin; real bottomCentre = bottomFrameMin + bottomFrameWidth/2; bottomArrowX[i] = bottomFrameMin + bottomFrameWidth/2; picture bottomLevelPic; real bottomFrameHeightMax = ypart(max(bottomFrame)); real bottomFrameHeight = ypart(size(bottomFrame)); real bottomSpecialVerticalShift = bottomFrameHeight/2 - bottomFrameHeightMax; add(bottomLevelPic,bottomFrame,(0,bottomSpecialVerticalShift)); bottomArrowY[i] = - bottomFrameHeight/2 - 0; path byProdE = ellipse(byProdFrame, 0mm,0mm); real byProdMin = xpart(min(byProdFrame)); real byProdMax = xpart(max(byProdFrame)); real byProdWidth = byProdMax - byProdMin; real byProdCentre = byProdMin + byProdWidth/2; real byProdShift = bottomFrameMax + 20 - byProdMin; if (stage == 0 | stage == 2 | stage == 3) { add(bottomLevelPic,byProdFrame,(byProdShift,0)); } add(pic,bottomLevelPic,(0,0)); real oneThreeWidth = bottomFrameMin + byProdShift + byProdMax; path topDashE = ellipse(topDashFrame,0mm,1mm, dash); picture emptyTop; draw(emptyTop, topDashE, dash); draw(topDashFrame, topDashE, dash); frame topFrame; if (stage == 4 | stage == 5) { topDashFrame = emptyTop.fit(); // topFrame = makeChain(topDashPic, topLeftString, topRightString, 30, 30); } else if (stage == 0) { // topFrame = makeChain(topDashText, topLeftString, topRightString, 30, 30); // frame topFrame = makeSpecialChain1(topDashPic); } else { // topFrame = makeChain(false, topDashText, topLeftString, topRightString, 30, 30); } if (topNormalExpFracOrRootFrac == 0) { topFrame = makeChain(topDashFrame, topLeftFrame, topRightFrame, 30, 30); } else if (topNormalExpFracOrRootFrac == 1) { topFrame = makeExpChain(topDashFrame, topLeftFrame, topRightFrame, 30, 20); } else if (topNormalExpFracOrRootFrac == 2) { topFrame = makeFractionChain(topMultiplier, topLeftFrame, topDashFrame, topRightFrame, topTopFrame, false, 30, 20); } else if (topNormalExpFracOrRootFrac == 3) { topFrame = makeFractionChain(topMultiplier, topLeftFrame, topDashFrame, topRightFrame, topTopFrame, true, 30, 20); } else { } path topE = ellipse(topFrame,-4mm,3mm, invisible); if (stage == 0 | stage == 5) { draw (topFrame, topE); } real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameWidth = topFrameMax - topFrameMin; real topFrameHeightMax = ypart(max(topFrame)); real topFrameHeight = ypart(size(topFrame)); real topSpecialVerticalShift = topFrameHeight/2 - topFrameHeightMax; real topCentre = topFrameMin + topFrameWidth/2; real twoShift = oneThreeWidth/2 - topFrameWidth/2 - topFrameMin; topArrowX[i] = twoShift + topFrameMin + topFrameWidth/2; topArrowY[i] = topFrameHeight/2 - 0; add(pic,topFrame,(twoShift,height + topSpecialVerticalShift)); frame picFrame = pic.fit(); path topEShifted = shift(twoShift,height + topSpecialVerticalShift)*topE; path topDashEShifted = shift(twoShift,height + topSpecialVerticalShift)*topDashE; path bottomEShifted = shift(0, 0 + bottomSpecialVerticalShift)*bottomE; path byProdEShifted = shift(byProdShift, 0)*byProdE; path p = shift(twoShift,height + topSpecialVerticalShift)*(0,0) --shift(byProdShift,0)*(0,0); path pDash = shift(twoShift,height + topSpecialVerticalShift)*(topCentre,0) --shift(0, bottomSpecialVerticalShift)*(bottomCentre,0); path pDashJoin; if (stage == 0 | stage == 5) { pDashJoin = intersectionpoint(pDash,topEShifted)--intersectionpoint(pDash,bottomEShifted); draw(picFrame, pDashJoin, dash); } path pJoin; if (stage == 0 | stage == 2 | stage == 3) { pJoin = intersectionpoint(p,topDashEShifted)--intersectionpoint(p,byProdEShifted); draw(picFrame, pJoin); } bottomLeft[i] = xpart(min(bottomLevelPic)); bottomRight[i] = xpart(max(bottomLevelPic)); topLeft[i] = twoShift + topFrameMin; topRight[i] = twoShift + topFrameMax; return picFrame; } frame prodShapeIn(bool twist=false, frame oneLeftFrame, frame oneRightFrame, frame twoLeftFrame, frame twoRightFrame, frame threeLeftFrame, frame threeRightFrame, int i) { picture pic; picture prodOne; // frame oneLeftFrame = oneLeftString.fit(); path oneLeftE = ellipse(oneLeftFrame, -0mm,1mm); draw (oneLeftFrame, oneLeftE); real oneLeftFrameMin = xpart(min(oneLeftFrame)); real oneLeftFrameMax = xpart(max(oneLeftFrame)); real oneLeftFrameWidth = oneLeftFrameMax - oneLeftFrameMin; real oneLeftCentre = oneLeftFrameMin + oneLeftFrameWidth/2; add(prodOne,oneLeftFrame); // frame oneRightFrame = oneRightString.fit(); path oneRightE = ellipse(oneRightFrame, -0mm,1mm); draw (oneRightFrame, oneRightE); real oneRightFrameMin = xpart(min(oneRightFrame)); real oneRightFrameMax = xpart(max(oneRightFrame)); real oneRightFrameWidth = oneRightFrameMax - oneRightFrameMin; real oneInShift = oneLeftFrameMax + 9 - oneRightFrameMin; real oneRightCentre = oneRightFrameMin + oneRightFrameWidth/2 + oneInShift; add(prodOne,oneRightFrame,(oneInShift,0)); picture prodTwo; // frame twoLeftFrame = twoLeftString.fit(); path twoLeftE = ellipse(twoLeftFrame, -0mm,1mm); draw (twoLeftFrame, twoLeftE); real twoLeftFrameMin = xpart(min(twoLeftFrame)); real twoLeftFrameMax = xpart(max(twoLeftFrame)); real twoLeftFrameWidth = twoLeftFrameMax - twoLeftFrameMin; real twoLeftCentre = twoLeftFrameMin + twoLeftFrameWidth/2; add(prodTwo,twoLeftFrame); // frame twoRightFrame = twoRightString.fit(); path twoRightE = ellipse(twoRightFrame, -0mm,1mm); draw (twoRightFrame, twoRightE); real twoRightFrameMin = xpart(min(twoRightFrame)); real twoRightFrameMax = xpart(max(twoRightFrame)); real twoRightFrameWidth = twoRightFrameMax - twoRightFrameMin; real twoInShift = twoLeftFrameMax + 9 - twoRightFrameMin; real twoRightCentre = twoRightFrameMin + twoRightFrameWidth/2 + twoInShift; add(prodTwo,twoRightFrame,(twoInShift,0)); picture prodThree; // frame threeLeftFrame = threeLeftString.fit(); path threeLeftE = ellipse(threeLeftFrame, -0mm,1mm); draw (threeLeftFrame, threeLeftE); real threeLeftFrameMin = xpart(min(threeLeftFrame)); real threeLeftFrameMax = xpart(max(threeLeftFrame)); real threeLeftFrameWidth = threeLeftFrameMax - threeLeftFrameMin; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2; add(prodThree,threeLeftFrame); // frame threeRightFrame = threeRightString.fit(); path threeRightE = ellipse(threeRightFrame, -0mm,1mm); draw (threeRightFrame, threeRightE); real threeRightFrameMin = xpart(min(threeRightFrame)); real threeRightFrameMax = xpart(max(threeRightFrame)); real threeRightFrameWidth = threeRightFrameMax - threeRightFrameMin; real threeInShift = threeLeftFrameMax + 9 - threeRightFrameMin; real threeRightCentre = threeRightFrameMin + threeRightFrameWidth/2 + threeInShift; add(prodThree,threeRightFrame,(threeInShift,0)); frame oneFrame=prodOne.fit(); path oneE = ellipse(oneFrame, 0mm,1mm); draw (oneFrame, oneE); add(pic,oneFrame); oneFrame=pic.fit(); real oneMin = xpart(min(oneFrame)); real oneMax = xpart(max(oneFrame)); real oneWidth = oneMax - oneMin; frame threeFrame=prodThree.fit(); ellipse(threeFrame,0mm,1mm); picture p; add(p,threeFrame); threeFrame = p.fit(); real threeMin = xpart(min(threeFrame)); real threeMax = xpart(max(threeFrame)); real threeShift = oneMax - threeMin + 35; add(pic,threeFrame,(threeShift, 0)); real oneThreeWidth = oneMin + threeShift + threeMax; frame twoFrame=prodTwo.fit(); ellipse(twoFrame,0mm,1mm); real twoMin = xpart(min(twoFrame)); real twoMax = xpart(max(twoFrame)); real twoWidth = twoMax - twoMin; real twoShift = oneThreeWidth/2 - twoWidth/2 - twoMin; add(pic,twoFrame,(twoShift,height)); path oneLeftEShifted = shift(0,0)*oneLeftE; path oneRightEShifted = shift(twoInShift,0)*oneRightE; path twoLeftEShifted = shift(twoShift,height)*twoLeftE; path twoRightEShifted = shift(twoShift + twoInShift,height)*twoRightE; path threeLeftEShifted = shift(threeShift,0)*threeLeftE; path threeRightEShifted = shift(threeShift + threeInShift,0)*threeRightE; pair twoLeftCentreShifted = shift(twoShift,height)*(twoLeftCentre, 0); pair twoRightCentreShifted = shift(twoShift,height)*(twoRightCentre, 0); pair bottomLeftCentre; pair bottomRightCentre; path bottomLeftE; path bottomRightE; if (twist){ bottomLeftCentre = shift(threeShift,0)*(threeLeftCentre, 0); bottomRightCentre = shift(0,0)*(oneRightCentre, 0); bottomLeftE = threeLeftEShifted; bottomRightE = oneRightEShifted; } else { bottomLeftCentre = shift(0,0)*(oneLeftCentre, 0); bottomRightCentre = shift(threeShift,0)*(threeRightCentre, 0); bottomLeftE = oneLeftEShifted; bottomRightE = threeRightEShifted; } path pTwoLeft = twoLeftCentreShifted--bottomLeftCentre; path pTwoRight = twoRightCentreShifted--bottomRightCentre; path pTwoLeftJoin = intersectionpoint(pTwoLeft,twoLeftEShifted)--intersectionpoint(pTwoLeft,bottomLeftE); path pTwoRightJoin = intersectionpoint(pTwoRight,twoRightEShifted)--intersectionpoint(pTwoRight,bottomRightE); draw(pic, pTwoLeftJoin); draw(pic, pTwoRightJoin); real plusPoint = oneMax + 17; label(pic,scale(textScale)*"$+$",(plusPoint,0)); frame picFrame = pic.fit(); bottomLeft[i] = xpart(min(picFrame)); bottomRight[i] = xpart(max(picFrame)); topLeft[i] = twoShift + twoMin; topRight[i] = twoShift + twoMax; return picFrame; } frame prodShapeInLeft(bool open, frame leftBottomMultiplier, frame leftBottomLeftFrame, int leftBottomNormalExpFracOrRootFrac, frame leftBottomDashFrame, frame leftBottomRightFrame, frame leftBottomTopFrame, frame leftTopMultiplier, frame leftTopLeftFrame, int leftTopNormalExpFracOrRootFrac, frame leftTopDashFrame, frame leftTopRightFrame, frame leftTopTopFrame, frame leftByProdFrame, frame oneRightFrame, frame twoRightFrame, frame threeLeftFrame, frame threeRightFrame, int i) { picture pic; picture prodOne; path leftBottomDashE = ellipse(leftBottomDashFrame,0mm,1mm, dash); picture emptyLeftBottom; draw(emptyLeftBottom, leftBottomDashE, dash); draw(leftBottomDashFrame, leftBottomDashE, dash); frame leftBottomFrame; // if (expBottom) { // leftBottomFrame = makeExpChain(leftBottomDashFrame, 0, 0); // } else { // leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); // } // frame leftBottomFrame = makeChain(emptyLeftBottom.fit(), leftBottomLeftFrame, leftBottomRightFrame, 30, 30); if (leftBottomNormalExpFracOrRootFrac == 0) { leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); } else if (leftBottomNormalExpFracOrRootFrac == 1) { leftBottomFrame = makeExpChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 2) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, false, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 3) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, true, 30, 20); } else { } path leftBottomE = ellipse(leftBottomFrame, 2mm,1mm, invisible); draw (leftBottomFrame, leftBottomE); real leftBottomFrameMin = xpart(min(leftBottomFrame)); real leftBottomFrameMax = xpart(max(leftBottomFrame)); real leftBottomFrameWidth = leftBottomFrameMax - leftBottomFrameMin; real leftBottomCentre = leftBottomFrameMin + leftBottomFrameWidth/2; real leftBottomFrameHeightMax = ypart(max(leftBottomFrame)); real leftBottomFrameHeight = ypart(size(leftBottomFrame)); real leftBottomSpecialVerticalShift = leftBottomFrameHeight/2 - leftBottomFrameHeightMax; add(prodOne, leftBottomFrame,(0,leftBottomSpecialVerticalShift)); path leftByProdE = ellipse(leftByProdFrame, 0mm,0mm); draw (leftBottomFrame, leftBottomE); real leftByProdMin = xpart(min(leftByProdFrame)); real leftByProdMax = xpart(max(leftByProdFrame)); real leftByProdWidth = leftByProdMax - leftByProdMin; real leftByProdCentre = leftByProdMin + leftByProdWidth/2; real leftByProdShift = leftBottomFrameMax + 20 - leftByProdMin; add(prodOne,leftByProdFrame,(leftByProdShift,0)); path oneRightE = ellipse(oneRightFrame, 0mm,0mm); draw (oneRightFrame, oneRightE); real oneRightFrameMin = xpart(min(oneRightFrame)); real oneRightFrameMax = xpart(max(oneRightFrame)); real oneRightFrameWidth = oneRightFrameMax - oneRightFrameMin; real oneInShift = leftByProdShift + leftByProdMax + 20 - oneRightFrameMin; real oneRightCentre = oneRightFrameMin + oneRightFrameWidth/2 + oneInShift; add(prodOne,oneRightFrame,(oneInShift,0)); picture prodTwo; path leftTopDashE = ellipse(leftTopDashFrame,0mm,1mm, dash); picture emptyLeftTop; draw(emptyLeftTop, leftTopDashE, dash); draw(leftTopDashFrame, leftTopDashE, dash); frame leftTopFrame; // if (expTop) { // leftTopFrame = makeExpChain(leftTopDashFrame, 0, 0); // } else { // leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); // } // frame leftTopFrame = makeChain(emptyLeftTop.fit(), leftTopLeftFrame, leftTopRightFrame, 30, 30); if (leftTopNormalExpFracOrRootFrac == 0) { leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); } else if (leftTopNormalExpFracOrRootFrac == 1) { leftTopFrame = makeExpChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 2) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, false, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 3) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, true, 30, 20); } else { } path leftTopE = ellipse(leftTopFrame, 2mm,1mm, invisible); draw (leftTopFrame, leftTopE); // frame leftTopFrame = makeSpecialChain1(leftTopDashPic); real leftTopFrameMin = xpart(min(leftTopFrame)); real leftTopFrameMax = xpart(max(leftTopFrame)); real leftTopFrameWidth = leftTopFrameMax - leftTopFrameMin; real leftTopFrameHeightMax = ypart(max(leftTopFrame)); real leftTopFrameHeight = ypart(size(leftTopFrame)); real leftTopSpecialVerticalShift = leftTopFrameHeight/2 - leftTopFrameHeightMax; real leftTopCentre = leftTopFrameMin + leftTopFrameWidth/2; add(prodTwo,leftTopFrame,(0,0)); path twoRightE = ellipse(twoRightFrame, 0mm,0mm); draw (twoRightFrame, twoRightE); real twoRightFrameMin = xpart(min(twoRightFrame)); real twoRightFrameMax = xpart(max(twoRightFrame)); real twoRightFrameWidth = twoRightFrameMax - twoRightFrameMin; real twoInShift = leftTopFrameMax + 20 - twoRightFrameMin; real twoRightCentre = twoRightFrameMin + twoRightFrameWidth/2 + twoInShift; add(prodTwo,twoRightFrame,(twoInShift,0)); picture prodThree; path threeLeftE = ellipse(threeLeftFrame, 0mm,0mm); draw (threeLeftFrame, threeLeftE); real threeLeftFrameMin = xpart(min(threeLeftFrame)); real threeLeftFrameMax = xpart(max(threeLeftFrame)); real threeLeftFrameWidth = threeLeftFrameMax - threeLeftFrameMin; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2; add(prodThree,threeLeftFrame,(0,0)); path threeRightE = ellipse(threeRightFrame, 0mm,0mm); draw (threeRightFrame, threeRightE); real threeRightFrameMin = xpart(min(threeRightFrame)); real threeRightFrameMax = xpart(max(threeRightFrame)); real threeRightFrameWidth = threeRightFrameMax - threeRightFrameMin; real threeRightCentre = threeRightFrameMin + threeRightFrameWidth/2; real threeInShift = threeLeftFrameMax + 20 - threeRightFrameMin; real threeRightCentre = threeRightFrameMin + threeRightFrameWidth/2 + threeInShift; add(prodThree,threeRightFrame,(threeInShift,0)); frame oneFrame=prodOne.fit(); frame threeFrame=prodThree.fit(); frame twoFrame=prodTwo.fit(); if (open == false) { path oneE = ellipse(oneFrame, -4mm,0mm); draw (oneFrame, oneE); path twoE = ellipse(twoFrame, 0mm,0mm); draw (twoFrame, twoE); path threeE = ellipse(threeFrame, 0mm,2mm); draw (threeFrame, threeE); } add(pic,oneFrame); oneFrame=pic.fit(); real oneMin = xpart(min(oneFrame)); real oneMax = xpart(max(oneFrame)); real oneWidth = oneMax - oneMin; real threeMin = xpart(min(threeFrame)); real threeMax = xpart(max(threeFrame)); real threeShift = oneMax - threeMin + 35; add(pic,threeFrame,(threeShift, 0)); real oneThreeWidth = oneMin + threeShift + threeMax; real twoMin = xpart(min(twoFrame)); real twoMax = xpart(max(twoFrame)); real twoWidth = twoMax - twoMin; real twoShift = oneThreeWidth/2 - twoWidth/2 - twoMin; add(pic,twoFrame,(twoShift,height)); pair leftBottomCentreShifted = shift(0,0)*(leftBottomCentre, 0); pair leftByProdCentreShifted = shift(leftByProdShift,0)*(leftByProdCentre, 0); pair leftTopCentreShifted = shift(twoShift,height)*(leftTopCentre, 0); pair leftTopDashCentreShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*(0, 0); path leftTopEShifted = shift(twoShift, height + leftTopSpecialVerticalShift)*leftTopE; path leftTopDashEShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*leftTopDashE; path leftBottomEShifted = shift(0, 0 + leftBottomSpecialVerticalShift)*leftBottomE; path leftByProdEShifted = shift(leftByProdShift, 0)*leftByProdE; path oneRightEShifted = shift(oneInShift,0)*oneRightE; path twoRightEShifted = shift(twoShift + twoInShift, height)*oneRightE; pair twoRightCentreShifted = shift(twoShift,height)*twoRightCentre; path threeLeftEShifted = shift(threeShift,0)*threeLeftE; path threeRightEShifted = shift(threeShift + threeInShift,0)*threeLeftE; pair threeRightCentreShifted = shift(threeShift,0)*threeRightCentre; path leftDashLine = leftTopCentreShifted--leftBottomCentreShifted; path leftByProdLine = leftTopDashCentreShifted--leftByProdCentreShifted; path leftDashLineSeg = intersectionpoint(leftDashLine,leftTopEShifted)--intersectionpoint(leftDashLine,leftBottomEShifted); path leftByProdLineSeg = intersectionpoint(leftByProdLine,leftTopDashEShifted)--intersectionpoint(leftByProdLine,leftByProdEShifted); draw(pic, leftDashLineSeg, dash); draw(pic, leftByProdLineSeg); path rightLine = twoRightCentreShifted--threeRightCentreShifted; path rightLineSeg = intersectionpoint(rightLine,twoRightEShifted)--intersectionpoint(rightLine,shift(0,-5)*threeRightEShifted); draw(pic, rightLineSeg); real plusPoint = oneMax + 17; label(pic,scale(textScale)*"$+$",(plusPoint,0)); frame picFrame = pic.fit(); bottomLeft[i] = xpart(min(picFrame)); bottomRight[i] = xpart(max(picFrame)); topLeft[i] = twoShift + twoMin; topRight[i] = twoShift + twoMax; return picFrame; } frame prodShapeInRight(bool open, frame oneLeftFrame, frame oneRightFrame, frame twoLeftFrame, frame threeLeftFrame, frame bottomMultiplier, frame bottomLeftFrame, int bottomNormalExpFracOrRootFrac, frame bottomDashFrame, frame bottomRightFrame, frame bottomTopFrame, frame topMultiplier, frame topLeftFrame, int topNormalExpFracOrRootFrac, frame topDashFrame, frame topRightFrame, frame topTopFrame, frame byProdFrame, int i) { picture pic; picture prodOne; // frame oneLeftFrame = oneLeftString.fit(); path oneLeftE = ellipse(oneLeftFrame, 0mm,0mm); draw (oneLeftFrame, oneLeftE); real oneLeftFrameMin = xpart(min(oneLeftFrame)); real oneLeftFrameMax = xpart(max(oneLeftFrame)); real oneLeftFrameWidth = oneLeftFrameMax - oneLeftFrameMin; real oneLeftCentre = oneLeftFrameMin + oneLeftFrameWidth/2; add(prodOne,oneLeftFrame); // frame oneRightFrame = oneRightString.fit(); path oneRightE = ellipse(oneRightFrame, 0mm,0mm); draw (oneRightFrame, oneRightE); real oneRightFrameMin = xpart(min(oneRightFrame)); real oneRightFrameMax = xpart(max(oneRightFrame)); real oneRightFrameWidth = oneRightFrameMax - oneRightFrameMin; real oneInShift = oneLeftFrameMax + 20 - oneRightFrameMin; real oneRightCentre = oneRightFrameMin + oneRightFrameWidth/2 + oneInShift; add(prodOne,oneRightFrame,(oneInShift,0)); picture prodTwo; path topDashE = ellipse(topDashFrame,0mm,1mm,dash); picture emptyTop; draw(emptyTop, topDashE, dash); // frame topFrame = makeChain(emptyTop, topLeftFrame, topRightFrame, 30, 30); draw(topDashFrame, topDashE, dash); frame topFrame; // if (expTop) { // topFrame = makeExpChain(topDashFrame, 0, 0); // } else { topFrame = makeChain(topDashFrame, topLeftFrame, topRightFrame, 0, 0); // } path topE = ellipse(topFrame, 0mm,1mm, invisible); draw (topFrame, topE); real topFrameMin = xpart(min(topFrame)); real topFrameMax = xpart(max(topFrame)); real topFrameWidth = topFrameMax - topFrameMin; real topFrameHeightMax = ypart(max(topFrame)); real topFrameHeight = ypart(size(topFrame)); real topSpecialVerticalShift = topFrameHeight/2 - topFrameHeightMax; real topCentre = topFrameMin + topFrameWidth/2; add(prodTwo,topFrame,(0,topSpecialVerticalShift)); path twoLeftE = ellipse(twoLeftFrame, 0mm,0mm); draw (twoLeftFrame, twoLeftE); real twoLeftFrameMin = xpart(min(twoLeftFrame)); real twoLeftFrameMax = xpart(max(twoLeftFrame)); real twoLeftFrameWidth = twoLeftFrameMax - twoLeftFrameMin; real twoLeftCentre = twoLeftFrameMin + twoLeftFrameWidth/2; real twoInShift = topFrameMin - 20 - twoLeftFrameMax; real twoLeftCentre = twoLeftFrameMin + twoLeftFrameWidth/2 + twoInShift; add(prodTwo,twoLeftFrame,(twoInShift,0)); picture prodThree; path bottomDashE = ellipse(bottomDashFrame,0mm,1mm,dash); picture emptyBottom; draw(emptyBottom, topDashE, dash); draw(bottomDashFrame, bottomDashE, dash); frame bottomFrame; // if (expBottom) { // bottomFrame = makeExpChain(bottomDashFrame, 0, 0); // } else { bottomFrame = makeChain(bottomDashFrame, bottomLeftFrame, bottomRightFrame, 0, 0); // } // frame bottomFrame = makeChain(emptyBottom, bottomLeftFrame, bottomRightFrame, 0, 0); path bottomE = ellipse(bottomFrame, 0mm,1mm, invisible); draw (bottomFrame, bottomE); real bottomFrameMin = xpart(min(bottomFrame)); real bottomFrameMax = xpart(max(bottomFrame)); real bottomFrameWidth = bottomFrameMax - bottomFrameMin; real bottomCentre = bottomFrameMin + bottomFrameWidth/2; real bottomFrameHeightMax = ypart(max(bottomFrame)); real bottomFrameHeight = ypart(size(bottomFrame)); real bottomSpecialVerticalShift = bottomFrameHeight/2 - bottomFrameHeightMax; add(prodThree, bottomFrame,(0,bottomSpecialVerticalShift)); path byProdE = ellipse(byProdFrame, 0mm,0mm); draw (bottomFrame, bottomE); real byProdMin = xpart(min(byProdFrame)); real byProdMax = xpart(max(byProdFrame)); real byProdWidth = byProdMax - byProdMin; real byProdCentre = byProdMin + byProdWidth/2; real byProdShift = bottomFrameMax + 20 - byProdMin; add(prodThree,byProdFrame,(byProdShift,0)); path threeLeftE = ellipse(threeLeftFrame, 0mm,0mm); draw (threeLeftFrame, threeLeftE); real threeLeftFrameMin = xpart(min(threeLeftFrame)); real threeLeftFrameMax = xpart(max(threeLeftFrame)); real threeLeftFrameWidth = threeLeftFrameMax - threeLeftFrameMin; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2; real threeInShift = bottomFrameMin - 20 - threeLeftFrameMax; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2 + threeInShift; add(prodThree,threeLeftFrame,(threeInShift,0)); frame oneFrame=prodOne.fit(); frame threeFrame=prodThree.fit(); frame twoFrame=prodTwo.fit(); if (open == false) { path oneE = ellipse(oneFrame, 0mm,2mm); draw (oneFrame, oneE); path twoE = ellipse(twoFrame, 0mm,0mm); draw (twoFrame, twoE); path threeE = ellipse(threeFrame, 0mm,0mm); draw (threeFrame, threeE); } add(pic,oneFrame); oneFrame=pic.fit(); real oneMin = xpart(min(oneFrame)); real oneMax = xpart(max(oneFrame)); real oneWidth = oneMax - oneMin; real threeMin = xpart(min(threeFrame)); real threeMax = xpart(max(threeFrame)); real threeShift = oneMax - threeMin + 35; add(pic,threeFrame,(threeShift, 0)); real oneThreeWidth = oneMin + threeShift + threeMax; real twoMin = xpart(min(twoFrame)); real twoMax = xpart(max(twoFrame)); real twoWidth = twoMax - twoMin; real twoShift = oneThreeWidth/2 - twoWidth/2 - twoMin; add(pic,twoFrame,(twoShift,height)); path oneLeftEShifted = shift(0,0)*oneLeftE; path oneRightEShifted = shift(oneInShift,0)*oneRightE; path twoLeftEShifted = shift(twoShift + twoInShift,height)*twoLeftE; path topEShifted = shift(twoShift,height + topSpecialVerticalShift)*topE; path topDashEShifted = shift(twoShift,height + topSpecialVerticalShift)*topDashE; path threeLeftEShifted = shift(threeShift,0)*threeLeftE; path bottomEShifted = shift(threeShift, 0 + bottomSpecialVerticalShift)*bottomE; path byProdEShifted = shift(threeShift + byProdShift, 0)*byProdE; pair oneLeftCentreShifted = shift(0,0)*(oneLeftCentre, 0); pair twoLeftCentreShifted = shift(twoShift,height)*(twoLeftCentre, 0); pair twoRightCentreShifted = shift(twoShift,height)*(topCentre, 0); pair bottomLeftCentre = shift(0,0)*(oneLeftCentre, 0); pair bottomRightCentre = shift(threeShift,0)*(bottomCentre, 0); pair byProdCentreShifted = shift(threeShift + byProdShift,0)*(byProdCentre, 0); path bottomLeftE = oneLeftEShifted; path bottomRightE = bottomEShifted; path pTwoLeft = twoLeftCentreShifted--oneLeftCentreShifted; path pTwoLeftJoin = intersectionpoint(pTwoLeft,twoLeftEShifted)--intersectionpoint(pTwoLeft,bottomLeftE); draw(pic, pTwoLeftJoin); path pDash = twoRightCentreShifted--bottomRightCentre; path p = shift(twoShift,height + topSpecialVerticalShift)*(topCentre,0) --byProdCentreShifted; path pDashJoin = intersectionpoint(pDash,topEShifted)--intersectionpoint(pDash,bottomEShifted); path pJoin = intersectionpoint(p,topDashEShifted)--intersectionpoint(p,byProdEShifted); draw(pic, pJoin); draw(pic, pDashJoin, dash); // draw(pic, p); // draw(pic, pDash, dash); // draw(pic, topEShifted); // draw(pic, bottomEShifted); // draw(pic, topDashEShifted); // draw(pic, byProdEShifted); real plusPoint = oneMax + 17; label(pic,scale(textScale)*"$+$",(plusPoint,0)); frame picFrame = pic.fit(); bottomLeft[i] = xpart(min(picFrame)); bottomRight[i] = xpart(max(picFrame)); topLeft[i] = twoShift + twoMin; topRight[i] = twoShift + twoMax; return picFrame; } frame prodShapeInBoth( bool open, frame leftBottomMultiplier, frame leftBottomLeftFrame, int leftBottomNormalExpFracOrRootFrac, frame leftBottomDashFrame, frame leftBottomRightFrame, frame leftBottomTopFrame, frame leftTopMultiplier, frame leftTopLeftFrame, int leftTopNormalExpFracOrRootFrac, frame leftTopDashFrame, frame leftTopRightFrame, frame leftTopTopFrame, frame leftByProdFrame, frame oneRightFrame, frame threeLeftFrame, frame rightBottomMultiplier, frame rightBottomLeftFrame, int rightBottomNormalExpFracOrRootFrac, frame rightBottomDashFrame, frame rightBottomRightFrame, frame rightBottomTopFrame, frame rightTopMultiplier, frame rightTopLeftFrame, int rightTopNormalExpFracOrRootFrac, frame rightTopDashFrame, frame rightTopRightFrame, frame rightTopTopFrame, frame rightByProdFrame, int i) { picture pic; picture prodOne; path leftBottomDashE = ellipse(leftBottomDashFrame,0mm,1mm, dash); draw(leftBottomDashFrame, leftBottomDashE, dash); frame leftBottomFrame; // if (expLeftBottom) { // leftBottomFrame = makeExpChain(leftBottomDashFrame, 0, 0); // } else { // leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); // leftBottomFrame = makeFractionChain(makeText("$\frac{1}{2}$",1.4,(0,0)).fit(), leftBottomLeftFrame, //leftBottomDashFrame, leftBottomRightFrame, makeText("$1$",1,(0,0)).fit(), false, 30, 30); // } if (leftBottomNormalExpFracOrRootFrac == 0) { leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); } else if (leftBottomNormalExpFracOrRootFrac == 1) { leftBottomFrame = makeExpChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 2) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, false, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 3) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, true, 30, 20); } else { } path leftBottomE = ellipse(leftBottomFrame, -3mm,1mm, invisible); draw (leftBottomFrame, leftBottomE); real leftBottomFrameMin = xpart(min(leftBottomFrame)); real leftBottomFrameMax = xpart(max(leftBottomFrame)); real leftBottomFrameWidth = leftBottomFrameMax - leftBottomFrameMin; real leftBottomCentre = leftBottomFrameMin + leftBottomFrameWidth/2; real leftBottomFrameHeightMax = ypart(max(leftBottomFrame)); real leftBottomFrameHeight = ypart(size(leftBottomFrame)); real leftBottomSpecialVerticalShift = leftBottomFrameHeight/2 - leftBottomFrameHeightMax; add(prodOne, leftBottomFrame,(0,leftBottomSpecialVerticalShift)); path leftByProdE = ellipse(leftByProdFrame, 0mm,0mm); draw (leftBottomFrame, leftBottomE); real leftByProdMin = xpart(min(leftByProdFrame)); real leftByProdMax = xpart(max(leftByProdFrame)); real leftByProdWidth = leftByProdMax - leftByProdMin; real leftByProdCentre = leftByProdMin + leftByProdWidth/2; real leftByProdShift = leftBottomFrameMax + 20 - leftByProdMin; add(prodOne,leftByProdFrame,(leftByProdShift,0)); path oneRightE = ellipse(oneRightFrame, 0mm,0mm); draw (oneRightFrame, oneRightE); real oneRightFrameMin = xpart(min(oneRightFrame)); real oneRightFrameMax = xpart(max(oneRightFrame)); real oneRightFrameWidth = oneRightFrameMax - oneRightFrameMin; real oneInShift = leftByProdShift + leftByProdMax + 20 - oneRightFrameMin; real oneRightCentre = oneRightFrameMin + oneRightFrameWidth/2 + oneInShift; add(prodOne,oneRightFrame,(oneInShift,0)); picture prodThree; path rightBottomDashE = ellipse(rightBottomDashFrame,0mm,1mm, dash); draw(rightBottomDashFrame, rightBottomDashE, dash); frame rightBottomFrame; // if (expRightBottom) { // rightBottomFrame = makeExpChain(rightBottomDashFrame, 0, 0); // } else { // rightBottomFrame = makeChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 30); // rightBottomFrame = makeFractionChain(makeText("$-\frac{1}{2}$",1.4,(0,0)).fit(), rightBottomLeftFrame, //rightBottomDashFrame, rightBottomRightFrame, makeText("$1$",1,(0,0)).fit(), false, 30, 30); // } if (rightBottomNormalExpFracOrRootFrac == 0) { rightBottomFrame = makeChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 30); } else if (rightBottomNormalExpFracOrRootFrac == 1) { rightBottomFrame = makeExpChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 20); } else if (rightBottomNormalExpFracOrRootFrac == 2) { rightBottomFrame = makeFractionChain(rightBottomMultiplier, rightBottomLeftFrame, rightBottomDashFrame, rightBottomRightFrame, rightBottomTopFrame, false, 30, 20); } else if (rightBottomNormalExpFracOrRootFrac == 3) { rightBottomFrame = makeFractionChain(rightBottomMultiplier, rightBottomLeftFrame, rightBottomDashFrame, rightBottomRightFrame, rightBottomTopFrame, true, 30, 20); } else { } path rightBottomE = ellipse(rightBottomFrame, -3mm,1mm, invisible); draw (rightBottomFrame, rightBottomE); real rightBottomFrameMin = xpart(min(rightBottomFrame)); real rightBottomFrameMax = xpart(max(rightBottomFrame)); real rightBottomFrameWidth = rightBottomFrameMax - rightBottomFrameMin; real rightBottomCentre = rightBottomFrameMin + rightBottomFrameWidth/2; real rightBottomFrameHeightMax = ypart(max(rightBottomFrame)); real rightBottomFrameHeight = ypart(size(rightBottomFrame)); real rightBottomSpecialVerticalShift = rightBottomFrameHeight/2 - rightBottomFrameHeightMax; add(prodThree, rightBottomFrame,(0,rightBottomSpecialVerticalShift)); path rightByProdE = ellipse(rightByProdFrame, 0mm,0mm); draw (rightBottomFrame, rightBottomE); real rightByProdMin = xpart(min(rightByProdFrame)); real rightByProdMax = xpart(max(rightByProdFrame)); real rightByProdWidth = rightByProdMax - rightByProdMin; real rightByProdCentre = rightByProdMin + rightByProdWidth/2; real rightByProdShift = rightBottomFrameMax + 20 - rightByProdMin; add(prodThree,rightByProdFrame,(rightByProdShift,0)); path threeLeftE = ellipse(threeLeftFrame, 0mm,0mm); draw (threeLeftFrame, threeLeftE); real threeLeftFrameMin = xpart(min(threeLeftFrame)); real threeLeftFrameMax = xpart(max(threeLeftFrame)); real threeLeftFrameWidth = threeLeftFrameMax - threeLeftFrameMin; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2; real threeInShift = rightBottomFrameMin - 20 - threeLeftFrameMax; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2 + threeInShift; add(prodThree,threeLeftFrame,(threeInShift,0)); picture prodTwo; path leftTopDashE = ellipse(leftTopDashFrame,0mm,1mm, dash); draw(leftTopDashFrame, leftTopDashE, dash); frame leftTopFrame; // if (expLeftTop) { // leftTopFrame = makeExpChain(leftTopDashFrame, 0, 0); // } else { // leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); // } if (leftTopNormalExpFracOrRootFrac == 0) { leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); } else if (leftTopNormalExpFracOrRootFrac == 1) { leftTopFrame = makeExpChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 2) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, false, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 3) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, true, 30, 20); } else { } path leftTopE = ellipse(leftTopFrame, -3mm,1mm, invisible); draw (leftTopFrame, leftTopE); // frame leftTopFrame = makeSpecialChain1(leftTopDashFrame); real leftTopFrameMin = xpart(min(leftTopFrame)); real leftTopFrameMax = xpart(max(leftTopFrame)); real leftTopFrameWidth = leftTopFrameMax - leftTopFrameMin; real leftTopFrameHeightMax = ypart(max(leftTopFrame)); real leftTopFrameHeight = ypart(size(leftTopFrame)); real leftTopSpecialVerticalShift = leftTopFrameHeight/2 - leftTopFrameHeightMax; real leftTopCentre = leftTopFrameMin + leftTopFrameWidth/2; add(prodTwo,leftTopFrame,(0,0)); path rightTopDashE = ellipse(rightTopDashFrame,0mm,1mm, dash); draw(rightTopDashFrame, rightTopDashE, dash); frame rightTopFrame; // if (expRightTop) { // rightTopFrame = makeExpChain(rightTopDashFrame, 0, 0); // } else { // rightTopFrame = makeChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 30); // } if (rightTopNormalExpFracOrRootFrac == 0) { rightTopFrame = makeChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 30); } else if (rightTopNormalExpFracOrRootFrac == 1) { rightTopFrame = makeExpChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 20); } else if (rightTopNormalExpFracOrRootFrac == 2) { rightTopFrame = makeFractionChain(rightTopMultiplier, rightTopLeftFrame, rightTopDashFrame, rightTopRightFrame, rightTopTopFrame, false, 30, 20); } else if (rightTopNormalExpFracOrRootFrac == 3) { rightTopFrame = makeFractionChain(rightTopMultiplier, rightTopLeftFrame, rightTopDashFrame, rightTopRightFrame, rightTopTopFrame, true, 30, 20); } else { } path rightTopE = ellipse(rightTopFrame, -3mm,1mm, invisible); draw (rightTopFrame, rightTopE); // frame rightTopFrame = makeSpecialChain1(rightTopDashFrame); real rightTopFrameMin = xpart(min(rightTopFrame)); real rightTopFrameMax = xpart(max(rightTopFrame)); real rightTopFrameWidth = rightTopFrameMax - rightTopFrameMin; real rightTopFrameHeightMax = ypart(max(rightTopFrame)); real rightTopFrameHeight = ypart(size(rightTopFrame)); real rightTopSpecialVerticalShift = rightTopFrameHeight/2 - rightTopFrameHeightMax; real twoInShift = leftTopFrameMax + 20 - rightTopFrameMin; real rightTopCentre = twoInShift + rightTopFrameMin + rightTopFrameWidth/2; add(prodTwo,rightTopFrame,(twoInShift,0)); frame oneFrame=prodOne.fit(); frame threeFrame=prodThree.fit(); frame twoFrame=prodTwo.fit(); if (open == false) { path oneE = ellipse(oneFrame, 0mm,0mm); draw (oneFrame, oneE); path twoE = ellipse(twoFrame, 0mm,0mm); draw (twoFrame, twoE); path threeE = ellipse(threeFrame, 0mm,0mm); draw (threeFrame, threeE); } add(pic,oneFrame); oneFrame=pic.fit(); real oneMin = xpart(min(oneFrame)); real oneMax = xpart(max(oneFrame)); real oneWidth = oneMax - oneMin; real threeMin = xpart(min(threeFrame)); real threeMax = xpart(max(threeFrame)); real threeShift = oneMax - threeMin + 35; add(pic,threeFrame,(threeShift, 0)); real oneThreeWidth = oneMin + threeShift + threeMax; real twoMin = xpart(min(twoFrame)); real twoMax = xpart(max(twoFrame)); real twoWidth = twoMax - twoMin; real twoShift = oneThreeWidth/2 - twoWidth/2 - twoMin; add(pic,twoFrame,(twoShift,height)); pair leftBottomCentreShifted = shift(0,0)*(leftBottomCentre, 0); pair leftByProdCentreShifted = shift(leftByProdShift,0)*(leftByProdCentre, 0); pair leftTopCentreShifted = shift(twoShift,height)*(leftTopCentre, 0); pair leftTopDashCentreShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*(0, 0); path leftTopEShifted = shift(twoShift, height + leftTopSpecialVerticalShift)*leftTopE; path leftTopDashEShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*leftTopDashE; path leftBottomEShifted = shift(0, 0 + leftBottomSpecialVerticalShift)*leftBottomE; path leftByProdEShifted = shift(leftByProdShift, 0)*leftByProdE; path oneRightEShifted = shift(oneInShift,0)*oneRightE; path threeLeftEShifted = shift(threeShift,0)*threeLeftE; pair rightBottomCentreShifted = shift(threeShift,0)*(rightBottomCentre, 0); pair rightByProdCentreShifted = shift(threeShift + rightByProdShift,0)*(rightByProdCentre, 0); pair rightTopCentreShifted = shift(twoShift,height)*(rightTopCentre, 0); pair rightTopDashCentreShifted = shift(twoShift + twoInShift, height + rightTopSpecialVerticalShift)*(0, 0); path rightTopEShifted = shift(twoShift + twoInShift,height + rightTopSpecialVerticalShift)*rightTopE; path rightTopDashEShifted = shift(twoShift + twoInShift,height + rightTopSpecialVerticalShift)*rightTopDashE; path rightBottomEShifted = shift(threeShift, 0 + rightBottomSpecialVerticalShift)*rightBottomE; path rightByProdEShifted = shift(threeShift + rightByProdShift, 0)*rightByProdE; path leftDashLine = leftTopCentreShifted--leftBottomCentreShifted; path leftByProdLine = leftTopDashCentreShifted--leftByProdCentreShifted; path leftDashLineSeg = intersectionpoint(leftDashLine,leftTopEShifted)--intersectionpoint(leftDashLine,leftBottomEShifted); path leftByProdLineSeg = intersectionpoint(leftByProdLine,leftTopDashEShifted)--intersectionpoint(leftByProdLine,leftByProdEShifted); draw(pic, leftDashLineSeg, dash); draw(pic, leftByProdLineSeg); path rightDashLine = rightTopCentreShifted--rightBottomCentreShifted; path rightByProdLine = rightTopDashCentreShifted--rightByProdCentreShifted; path rightDashLineSeg = intersectionpoint(rightDashLine,rightTopEShifted)--intersectionpoint(rightDashLine,rightBottomEShifted); path rightByProdLineSeg = intersectionpoint(rightByProdLine,rightTopDashEShifted)--intersectionpoint(rightByProdLine,rightByProdEShifted); draw(pic, rightDashLineSeg, dash); draw(pic, rightByProdLineSeg); real plusPoint = oneMax + 17; label(pic,scale(textScale)*"$+$",(plusPoint,0)); frame picFrame = pic.fit(); bottomLeft[i] = xpart(min(picFrame)); bottomRight[i] = xpart(max(picFrame)); topLeft[i] = twoShift + twoMin; topRight[i] = twoShift + twoMax; return picFrame; } frame doubleChainShape( bool open, frame leftBottomMultiplier, frame leftBottomLeftFrame, int leftBottomNormalExpFracOrRootFrac, frame leftBottomDashFrame, frame leftBottomRightFrame, frame leftBottomTopFrame, frame leftTopMultiplier, frame leftTopLeftFrame, int leftTopNormalExpFracOrRootFrac, frame leftTopDashFrame, frame leftTopRightFrame, frame leftTopTopFrame, frame leftByProdFrame, frame oneRightFrame, frame threeLeftFrame, frame rightBottomMultiplier, frame rightBottomLeftFrame, int rightBottomNormalExpFracOrRootFrac, frame rightBottomDashFrame, frame rightBottomRightFrame, frame rightBottomTopFrame, frame rightTopMultiplier, frame rightTopLeftFrame, int rightTopNormalExpFracOrRootFrac, frame rightTopDashFrame, frame rightTopRightFrame, frame rightTopTopFrame, frame rightByProdFrame, int i) { picture pic; picture prodOne; path leftBottomDashE = ellipse(leftBottomDashFrame,0mm,1mm, dashdotted); draw(leftBottomDashFrame, leftBottomDashE, dash); frame leftBottomFrame; // if (expLeftBottom) { // leftBottomFrame = makeExpChain(leftBottomDashFrame, 0, 0); // } else { // leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); // leftBottomFrame = makeFractionChain(makeText("$\frac{1}{2}$",1.4,(0,0)).fit(), leftBottomLeftFrame, //leftBottomDashFrame, leftBottomRightFrame, makeText("$1$",1,(0,0)).fit(), false, 30, 30); // } if (leftBottomNormalExpFracOrRootFrac == 0) { leftBottomFrame = makeChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 30); } else if (leftBottomNormalExpFracOrRootFrac == 1) { leftBottomFrame = makeExpChain(leftBottomDashFrame, leftBottomLeftFrame, leftBottomRightFrame, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 2) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, false, 30, 20); } else if (leftBottomNormalExpFracOrRootFrac == 3) { leftBottomFrame = makeFractionChain(leftBottomMultiplier, leftBottomLeftFrame, leftBottomDashFrame, leftBottomRightFrame, leftBottomTopFrame, true, 30, 20); } else { } path leftBottomE = ellipse(leftBottomFrame, -3mm,1mm, invisible); draw (leftBottomFrame, leftBottomE); real leftBottomFrameMin = xpart(min(leftBottomFrame)); real leftBottomFrameMax = xpart(max(leftBottomFrame)); real leftBottomFrameWidth = leftBottomFrameMax - leftBottomFrameMin; real leftBottomCentre = leftBottomFrameMin + leftBottomFrameWidth/2; real leftBottomFrameHeightMax = ypart(max(leftBottomFrame)); real leftBottomFrameHeight = ypart(size(leftBottomFrame)); real leftBottomSpecialVerticalShift = leftBottomFrameHeight/2 - leftBottomFrameHeightMax; add(prodOne, leftBottomFrame,(0,leftBottomSpecialVerticalShift)); path leftByProdE = ellipse(leftByProdFrame, 0mm,0mm); draw (leftBottomFrame, leftBottomE); real leftByProdMin = xpart(min(leftByProdFrame)); real leftByProdMax = xpart(max(leftByProdFrame)); real leftByProdWidth = leftByProdMax - leftByProdMin; real leftByProdCentre = leftByProdMin + leftByProdWidth/2; real leftByProdShift = leftBottomFrameMax + 20 - leftByProdMin; add(prodOne,leftByProdFrame,(leftByProdShift,0)); path oneRightE = ellipse(oneRightFrame, 0mm,0mm); draw (oneRightFrame, oneRightE); real oneRightFrameMin = xpart(min(oneRightFrame)); real oneRightFrameMax = xpart(max(oneRightFrame)); real oneRightFrameWidth = oneRightFrameMax - oneRightFrameMin; real oneInShift = leftByProdShift + leftByProdMax + 20 - oneRightFrameMin; real oneRightCentre = oneRightFrameMin + oneRightFrameWidth/2 + oneInShift; add(prodOne,oneRightFrame,(oneInShift,0)); picture prodThree; path rightBottomDashE = ellipse(rightBottomDashFrame,0mm,1mm, dash); draw(rightBottomDashFrame, rightBottomDashE, dash); frame rightBottomFrame; // if (expRightBottom) { // rightBottomFrame = makeExpChain(rightBottomDashFrame, 0, 0); // } else { // rightBottomFrame = makeChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 30); // rightBottomFrame = makeFractionChain(makeText("$-\frac{1}{2}$",1.4,(0,0)).fit(), rightBottomLeftFrame, //rightBottomDashFrame, rightBottomRightFrame, makeText("$1$",1,(0,0)).fit(), false, 30, 30); // } if (rightBottomNormalExpFracOrRootFrac == 0) { rightBottomFrame = makeChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 30); } else if (rightBottomNormalExpFracOrRootFrac == 1) { rightBottomFrame = makeExpChain(rightBottomDashFrame, rightBottomLeftFrame, rightBottomRightFrame, 30, 20); } else if (rightBottomNormalExpFracOrRootFrac == 2) { rightBottomFrame = makeFractionChain(rightBottomMultiplier, rightBottomLeftFrame, rightBottomDashFrame, rightBottomRightFrame, rightBottomTopFrame, false, 30, 20); } else if (rightBottomNormalExpFracOrRootFrac == 3) { rightBottomFrame = makeFractionChain(rightBottomMultiplier, rightBottomLeftFrame, rightBottomDashFrame, rightBottomRightFrame, rightBottomTopFrame, true, 30, 20); } else { } path rightBottomE = ellipse(rightBottomFrame, -3mm,1mm, invisible); draw (rightBottomFrame, rightBottomE); real rightBottomFrameMin = xpart(min(rightBottomFrame)); real rightBottomFrameMax = xpart(max(rightBottomFrame)); real rightBottomFrameWidth = rightBottomFrameMax - rightBottomFrameMin; real rightBottomCentre = rightBottomFrameMin + rightBottomFrameWidth/2; real rightBottomFrameHeightMax = ypart(max(rightBottomFrame)); real rightBottomFrameHeight = ypart(size(rightBottomFrame)); real rightBottomSpecialVerticalShift = rightBottomFrameHeight/2 - rightBottomFrameHeightMax; add(prodThree, rightBottomFrame,(0,rightBottomSpecialVerticalShift)); path rightByProdE = ellipse(rightByProdFrame, 0mm,0mm); draw (rightBottomFrame, rightBottomE); real rightByProdMin = xpart(min(rightByProdFrame)); real rightByProdMax = xpart(max(rightByProdFrame)); real rightByProdWidth = rightByProdMax - rightByProdMin; real rightByProdCentre = rightByProdMin + rightByProdWidth/2; real rightByProdShift = rightBottomFrameMax + 20 - rightByProdMin; add(prodThree,rightByProdFrame,(rightByProdShift,0)); path threeLeftE = ellipse(threeLeftFrame, 0mm,0mm); draw (threeLeftFrame, threeLeftE); real threeLeftFrameMin = xpart(min(threeLeftFrame)); real threeLeftFrameMax = xpart(max(threeLeftFrame)); real threeLeftFrameWidth = threeLeftFrameMax - threeLeftFrameMin; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2; real threeInShift = rightBottomFrameMin - 20 - threeLeftFrameMax; real threeLeftCentre = threeLeftFrameMin + threeLeftFrameWidth/2 + threeInShift; add(prodThree,threeLeftFrame,(threeInShift,0)); picture prodTwo; path leftTopDashE = ellipse(leftTopDashFrame,0mm,1mm, dash); draw(leftTopDashFrame, leftTopDashE, dash); frame leftTopFrame; // if (expLeftTop) { // leftTopFrame = makeExpChain(leftTopDashFrame, 0, 0); // } else { // leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); // } if (leftTopNormalExpFracOrRootFrac == 0) { leftTopFrame = makeChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 30); } else if (leftTopNormalExpFracOrRootFrac == 1) { leftTopFrame = makeExpChain(leftTopDashFrame, leftTopLeftFrame, leftTopRightFrame, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 2) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, false, 30, 20); } else if (leftTopNormalExpFracOrRootFrac == 3) { leftTopFrame = makeFractionChain(leftTopMultiplier, leftTopLeftFrame, leftTopDashFrame, leftTopRightFrame, leftTopTopFrame, true, 30, 20); } else { } path leftTopE = ellipse(leftTopFrame, -3mm,1mm, invisible); draw (leftTopFrame, leftTopE); // frame leftTopFrame = makeSpecialChain1(leftTopDashFrame); real leftTopFrameMin = xpart(min(leftTopFrame)); real leftTopFrameMax = xpart(max(leftTopFrame)); real leftTopFrameWidth = leftTopFrameMax - leftTopFrameMin; real leftTopFrameHeightMax = ypart(max(leftTopFrame)); real leftTopFrameHeight = ypart(size(leftTopFrame)); real leftTopSpecialVerticalShift = leftTopFrameHeight/2 - leftTopFrameHeightMax; real leftTopCentre = leftTopFrameMin + leftTopFrameWidth/2; add(prodTwo,leftTopFrame,(0,0)); path rightTopDashE = ellipse(rightTopDashFrame,0mm,1mm, dash); draw(rightTopDashFrame, rightTopDashE, dash); frame rightTopFrame; // if (expRightTop) { // rightTopFrame = makeExpChain(rightTopDashFrame, 0, 0); // } else { // rightTopFrame = makeChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 30); // } if (rightTopNormalExpFracOrRootFrac == 0) { rightTopFrame = makeChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 30); } else if (rightTopNormalExpFracOrRootFrac == 1) { rightTopFrame = makeExpChain(rightTopDashFrame, rightTopLeftFrame, rightTopRightFrame, 30, 20); } else if (rightTopNormalExpFracOrRootFrac == 2) { rightTopFrame = makeFractionChain(rightTopMultiplier, rightTopLeftFrame, rightTopDashFrame, rightTopRightFrame, rightTopTopFrame, false, 30, 20); } else if (rightTopNormalExpFracOrRootFrac == 3) { rightTopFrame = makeFractionChain(rightTopMultiplier, rightTopLeftFrame, rightTopDashFrame, rightTopRightFrame, rightTopTopFrame, true, 30, 20); } else { } path rightTopE = ellipse(rightTopFrame, -3mm,1mm, invisible); draw (rightTopFrame, rightTopE); // frame rightTopFrame = makeSpecialChain1(rightTopDashFrame); real rightTopFrameMin = xpart(min(rightTopFrame)); real rightTopFrameMax = xpart(max(rightTopFrame)); real rightTopFrameWidth = rightTopFrameMax - rightTopFrameMin; real rightTopFrameHeightMax = ypart(max(rightTopFrame)); real rightTopFrameHeight = ypart(size(rightTopFrame)); real rightTopSpecialVerticalShift = rightTopFrameHeight/2 - rightTopFrameHeightMax; real twoInShift = leftTopFrameMax + 20 - rightTopFrameMin; real rightTopCentre = twoInShift + rightTopFrameMin + rightTopFrameWidth/2; add(prodTwo,rightTopFrame,(twoInShift,0)); frame oneFrame=prodOne.fit(); frame threeFrame=prodThree.fit(); frame twoFrame=prodTwo.fit(); if (open == false) { path oneE = ellipse(oneFrame, 0mm,0mm); draw (oneFrame, oneE); path twoE = ellipse(twoFrame, 0mm,0mm); draw (twoFrame, twoE); path threeE = ellipse(threeFrame, 0mm,0mm); draw (threeFrame, threeE); } add(pic,oneFrame); oneFrame=pic.fit(); real oneMin = xpart(min(oneFrame)); real oneMax = xpart(max(oneFrame)); real oneWidth = oneMax - oneMin; real threeMin = xpart(min(threeFrame)); real threeMax = xpart(max(threeFrame)); real threeShift = oneMax - threeMin + 35; add(pic,threeFrame,(threeShift, 0)); real oneThreeWidth = oneMin + threeShift + threeMax; real twoMin = xpart(min(twoFrame)); real twoMax = xpart(max(twoFrame)); real twoWidth = twoMax - twoMin; real twoShift = oneThreeWidth/2 - twoWidth/2 - twoMin; add(pic,twoFrame,(twoShift,height)); pair leftBottomCentreShifted = shift(0,0)*(leftBottomCentre, 0); pair leftByProdCentreShifted = shift(leftByProdShift,0)*(leftByProdCentre, 0); pair leftTopCentreShifted = shift(twoShift,height)*(leftTopCentre, 0); pair leftTopDashCentreShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*(0, 0); path leftTopEShifted = shift(twoShift, height + leftTopSpecialVerticalShift)*leftTopE; path leftTopDashEShifted = shift(twoShift,height + leftTopSpecialVerticalShift)*leftTopDashE; path leftBottomEShifted = shift(0, 0 + leftBottomSpecialVerticalShift)*leftBottomE; path leftByProdEShifted = shift(leftByProdShift, 0)*leftByProdE; path oneRightEShifted = shift(oneInShift,0)*oneRightE; path threeLeftEShifted = shift(threeShift,0)*threeLeftE; pair rightBottomCentreShifted = shift(threeShift,0)*(rightBottomCentre, 0); pair rightByProdCentreShifted = shift(threeShift + rightByProdShift,0)*(rightByProdCentre, 0); pair rightTopCentreShifted = shift(twoShift,height)*(rightTopCentre, 0); pair rightTopDashCentreShifted = shift(twoShift + twoInShift, height + rightTopSpecialVerticalShift)*(0, 0); path rightTopEShifted = shift(twoShift + twoInShift,height + rightTopSpecialVerticalShift)*rightTopE; path rightTopDashEShifted = shift(twoShift + twoInShift,height + rightTopSpecialVerticalShift)*rightTopDashE; path rightBottomEShifted = shift(threeShift, 0 + rightBottomSpecialVerticalShift)*rightBottomE; path rightByProdEShifted = shift(threeShift + rightByProdShift, 0)*rightByProdE; path leftDashLine = leftTopCentreShifted--leftBottomCentreShifted; path leftByProdLine = leftTopDashCentreShifted--leftByProdCentreShifted; path leftDashLineSeg = intersectionpoint(leftDashLine,leftTopEShifted)--intersectionpoint(leftDashLine,leftBottomEShifted); path leftByProdLineSeg = intersectionpoint(leftByProdLine,leftTopDashEShifted)--intersectionpoint(leftByProdLine,leftByProdEShifted); draw(pic, leftDashLineSeg, dash); draw(pic, leftByProdLineSeg); path rightDashLine = rightTopCentreShifted--rightBottomCentreShifted; path rightByProdLine = rightTopDashCentreShifted--rightByProdCentreShifted; path rightDashLineSeg = intersectionpoint(rightDashLine,rightTopEShifted)--intersectionpoint(rightDashLine,rightBottomEShifted); path rightByProdLineSeg = intersectionpoint(rightByProdLine,rightTopDashEShifted)--intersectionpoint(rightByProdLine,rightByProdEShifted); draw(pic, rightDashLineSeg, dash); draw(pic, rightByProdLineSeg); real plusPoint = oneMax + 17; label(pic,scale(textScale)*"$+$",(plusPoint,0)); frame picFrame = pic.fit(); bottomLeft[i] = xpart(min(picFrame)); bottomRight[i] = xpart(max(picFrame)); topLeft[i] = twoShift + twoMin; topRight[i] = twoShift + twoMax; return picFrame; }