From 886b80249b26e7c83297a3183ca1a4c3778c0271 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 20 May 2011 15:26:01 -0400 Subject: [PATCH] Add stickfigure-test.asy and allow independent leg and arm movement. --- asymptote/Makefile | 2 +- asymptote/stickfigure-test.asy | 46 ++++++++++++ asymptote/stickfigure.asy | 127 ++++++++++++++++++++++----------- 3 files changed, 133 insertions(+), 42 deletions(-) create mode 100644 asymptote/stickfigure-test.asy diff --git a/asymptote/Makefile b/asymptote/Makefile index ebac727..a76cdb7 100644 --- a/asymptote/Makefile +++ b/asymptote/Makefile @@ -16,7 +16,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -MODULES = Circ ElectroMag Mechanics +MODULES = Circ ElectroMag Mechanics stickfigure all : pdfs pngs diff --git a/asymptote/stickfigure-test.asy b/asymptote/stickfigure-test.asy new file mode 100644 index 0000000..b5eba83 --- /dev/null +++ b/asymptote/stickfigure-test.asy @@ -0,0 +1,46 @@ +import stickfigure; + +real u = 6cm; + +StickFigure s = StickFigure(standsOn=(0,0), height=u/2); + +s.draw(); +dot("crown", s.crownPos(), N, red); +dot("head", s.headPos(), E, red); +dot("right shoulder", s.shoulderPos(), E, red); +dot("left shoulder", s.shoulderPos(leftSide=true), W, red); +dot("right hand", s.handPos(), E, red); +dot("left hand", s.handPos(leftSide=true), W, red); +dot("right foot", s.footPos(), E, red); +dot("left foot", s.footPos(leftSide=true), W, red); +dot("stands on", s.standsOnPos(), S, red); + +s.standsOn((u,0)); +s.draw(); +dot("chin", s.chinPos(), E, red); +dot("neck base", s.neckBasePos(), W, red); +dot("tail", s.tailPos(), E, red); +dot("center", s.center, W, red); +dot("stands on", s.standsOnPos(), S, red); + +s.rightArmAngle = 30; +s.leftArmAngle = 40; +s.rightLegAngle = -20; +s.leftLegAngle = -30; +s.standsOn((0,-u)); +s.draw(); +draw(s.footPos()--s.footPos(leftSide=true), dashed); +dot("stands on", s.standsOnPos(), S, red); +dot("center", s.center, E, red); +dot("$30^\circ$ arm angle", s.handPos(), E); +dot("$40^\circ$ arm angle", s.handPos(leftSide=true), W); +dot("$-20^\circ$ leg angle", s.footPos(), E); +dot("$-30^\circ$ leg angle", s.footPos(leftSide=true), W); + +s.rightLegAngle = s.leftLegAngle = -45; +s.rightArmAngle = -60; +s.standsOn((u, -u)); +s.outline = blue; +s.fill = red; +s.draw(); +label("blue outline, red fill", s.crownPos(), N); diff --git a/asymptote/stickfigure.asy b/asymptote/stickfigure.asy index 242b39e..527cbb6 100644 --- a/asymptote/stickfigure.asy +++ b/asymptote/stickfigure.asy @@ -24,64 +24,105 @@ struct StickFigure { real neckHeightRatio; real torsoHeightRatio; real shoulderHeightRatio; + real legHeightRatio; + real centerTorsoRatio; real armTorsoRatio; - real armAngle; + real rightArmAngle; + real leftArmAngle; + real rightLegAngle; + real leftLegAngle; pen outline; pen fill; - + void operator init(pair standsOn=(0,0), real height=10mm) { - this.center = standsOn+(0,height/2); this.height = height; this.headHeightRatio = 0.2; this.neckHeightRatio = 0.1; this.torsoHeightRatio = 0.28; this.shoulderHeightRatio = 0.1; + /* at shoulder width, a leg takes this much height: + * 1 - head - neck - torso (opposite legAngle) + * and this much width: + * shoulder/2 (adjavent legAngle) + */ + this.rightLegAngle = -aTan( + 2*(1-this.headHeightRatio-this.neckHeightRatio-this.torsoHeightRatio) + /this.shoulderHeightRatio); + this.leftLegAngle = rightLegAngle; + this.legHeightRatio = this.shoulderHeightRatio/2/Cos(this.rightLegAngle); + this.centerTorsoRatio = 0.2; this.armTorsoRatio = 1.2; - this.armAngle = -70; + this.rightArmAngle = -70; + this.leftArmAngle = -70; this.outline = currentpen; this.fill = currentpen; + + this.center = standsOn + + (0, this.height*(this.legHeightRatio*Sin(-this.rightLegAngle) + +this.torsoHeightRatio*this.centerTorsoRatio)); } - pair crownPos() { - return this.center + (0,this.height/2); + /* center a fixed torso fraction (centerTorsoRatio) above tail. + * Everything else located from that point. + */ + + pair tailPos() { + return this.center + - (0,this.height*this.torsoHeightRatio*this.centerTorsoRatio); } - + + pair neckBasePos() { + return this.tailPos() + (0,this.height*this.torsoHeightRatio); + } + pair chinPos() { - return this.crownPos() - (0,this.height*this.headHeightRatio); + return this.neckBasePos() + (0,this.height*this.neckHeightRatio); + } + + pair crownPos() { + return this.chinPos() + (0,this.height*this.headHeightRatio); } - + pair headPos() { return (this.crownPos() + this.chinPos())/2; } - - pair neckBasePos() { - return this.chinPos() - (0,this.height*this.neckHeightRatio); - } - pair shoulderPos(bool rightSide=true) { + pair shoulderPos(bool leftSide=false) { real sign = 1; - if (rightSide == false) + if (leftSide == true) sign = -1; return this.neckBasePos() + (sign*this.height*this.shoulderHeightRatio/2,0); } - - pair handPos(bool rightSide=true) { - pair dArm = this.height*this.torsoHeightRatio*this.armTorsoRatio * dir(armAngle); - if (rightSide == false) - dArm = (-dArm.x, dArm.y); - return this.shoulderPos(rightSide=rightSide) + dArm; + + pair handPos(bool leftSide=false) { + real len = this.height*this.torsoHeightRatio*this.armTorsoRatio; + real ang; + if (leftSide == true) { + ang = 180 - this.leftArmAngle; + } else{ + ang = this.rightArmAngle; + } + return this.shoulderPos(leftSide=leftSide) + len * dir(ang); } - pair tailPos() { - return this.neckBasePos() - (0,this.height*this.torsoHeightRatio); - } - - pair footPos(bool rightSide=true) { - real legHeightRatio = 1.0 - this.headHeightRatio - this.neckHeightRatio - torsoHeightRatio; - pair dLeg = (this.height*this.shoulderHeightRatio/2, -this.height*legHeightRatio); - if (rightSide == false) - dLeg = (-dLeg.x, dLeg.y); - return this.tailPos() + dLeg; + + pair footPos(bool leftSide=false) { + real len = this.height*this.legHeightRatio; + real ang; + if (leftSide == true) { + ang = 180 - this.leftLegAngle; + } else{ + ang = this.rightLegAngle; + } + return this.tailPos() + len * dir(ang); + } + + pair standsOnPos() { + return (this.footPos() + this.footPos(leftSide=true))/2; + } + + void standsOn(pair pos) { + this.center += pos - this.standsOnPos(); } void draw(picture pic=currentpicture) { @@ -94,17 +135,21 @@ struct StickFigure { --this.neckBasePos() --this.tailPos(); path armsAndShoulders = - this.handPos(rightSide=true) - --this.shoulderPos(rightSide=true) - --this.shoulderPos(rightSide=false) - --this.handPos(rightSide=false); + this.handPos(leftSide=false) + --this.shoulderPos(leftSide=false) + --this.shoulderPos(leftSide=true) + --this.handPos(leftSide=true); path legs = - this.footPos(rightSide=true) + this.footPos(leftSide=false) --this.tailPos() - --this.footPos(rightSide=false); - draw(pic, armsAndShoulders, outline); - draw(pic, legs, outline); - draw(pic, neckAndTorso, outline); - filldraw(pic, head, fill, outline); + --this.footPos(leftSide=true); + draw(pic, armsAndShoulders, this.outline); + draw(pic, legs, this.outline); + draw(pic, neckAndTorso, this.outline); + dot(this.handPos(leftSide=false), this.fill); + dot(this.handPos(leftSide=true), this.fill); + dot(this.footPos(leftSide=false), this.fill); + dot(this.footPos(leftSide=true), this.fill); + filldraw(pic, head, this.fill, this.outline); } } -- 2.26.2