MaplePrimes Posts

MaplePrimes Posts are for sharing your experiences, techniques and opinions about Maple, MapleSim and related products, as well as general interests in math and computing.

Latest Post
  • Latest Posts Feed
  • The ideas here are to allow 3D plotting commands such as plot3d to handle a `size` option similarly to how 2D plotting commands do so, and for the plots:-display command to also handle it for 3D plots.

    The size denotes the dimensions of the inlined plotting window, and not the relative lengths of the three axes.

    I'd be interested in any new problems introduced with this, eg. export, etc.

    restart;

    #
    # Using ToInert/FromInert
    #
    # This might go in an initialzation file.
    #
    try
      __ver:=(u->:-parse(u[7..:-StringTools:-Search(",",u)-1]))(:-sprintf("%s",:-kernelopts(':-version')));
      if __ver>=18.0 and __ver<=2019.2 then
        __KO:=:-kernelopts(':-opaquemodules'=false);
        :-unprotect(:-Plot:-Options:-Verify:-ProcessParameters);
        __KK:=ToInert(eval(:-Plot:-Options:-Verify:-ProcessParameters)):
        __LL:=[:-op([1,2,1,..],__KK)]:
        __NN:=:-nops(:-remove(:-type,[:-op([1,..],__KK)],
                              ':-specfunc(:-_Inert_SET)'))
              +:-select(:-has,[:-seq([__i,__LL[__i]],
                                     __i=1..:-nops(__LL))],
                        "size")[1][1];
        if :-has(:-op([5,2,2,2,1],__KK),:-_Inert_PARAM(__NN)) then
          __KK:=:-subsop([5,2,2,2,1]
                         =:-subs([:-_Inert_PARAM(__NN)=:-NULL],
                                  :-op([5,2,2,2,1],__KK)),__KK);
          :-Plot:-Options:-Verify:-ProcessParameters:=
          :-FromInert(:-subsop([5,2,2,3,1]
                      =:-subs([:-_Inert_STRING("size")=:-NULL],
                              :-op([5,2,2,3,1],__KK)),__KK));
          :-print("3D size patch done");
        else
          :-print("3D size patch not appropriate; possibly already done");
        end if;
      else
        :-print(sprintf("3D size patch not appropriate for version %a"),__ver);
      end if;
    catch:
      :-print("3D size patch failed");
    finally
      :-protect(:-Plot:-Options:-Verify:-ProcessParameters);
      :-kernelopts(':-opaquemodules'=__KO);
    end try:

    "3D size patch done"

     

    P := plot3d(sin(x)*y^2, x=-Pi..Pi, y=-1..1, size=[150,150],
                font=[Times,5], labels=["","",""]):
    P;

    plots:-display(P, size=[300,300], font=[Times,10]);

    #
    # inherited from the contourplot3d (the plot3d is unset).
    #
    plots:-display(
      plots:-contourplot3d(sin(x)*y^2, x=-Pi..Pi, y=-1..1,
                           thickness=3, contours=20, size=[800,800]),
      plot3d(sin(x)*y^2, x=-Pi..Pi, y=-1..1, color="Gray",
             transparency=0.1, style=surface)
    );

    # Some options should still act as 2D-plot-specific.
    #
    try plot3d(sin(x)*y^2, x=-Pi..Pi, y=-1..1, legend="Q");
        print("Not OK");
    catch:
    if StringTools:-FormatMessage(lastexception[2..-1])
       ="the legend option is not available for 3-D plots"
    then print("OK"); else print("Not OK"); error; end if; end try;

    "OK"

     

    Download 3Dsize_hotedit.mw

    If this works fine then it might be a candidate for inclusion in an initialization file, so that it's
    automatically available.

    I was trying to display a Physics[Vectors] vector name in a 3dplot with an up arrow
    on it. I found that this old 2008 trick still works in MAPLE 2018.

     


     

    restart;

    with(plots):
    with(Physics[Vectors]):

    # Using MAPLE 2018.2

    a:=arrow([-1,1,1],view=[-1.5..1.5,-1.5..1.5,-1.5..1.5]):

    v_;
    t:= textplot3d([-1.1,1.1,1,v_]):
    display(a,t);

    v_

     

     

    # I found this on an old 2008 post
    t:= textplot3d([-1.1,1.1,1,typeset(`#mover(mi(` || v ||  `),mo("→"))`)]):
    display(a,t);

     


     

    Download VectorTypeSetting.mw

    Application of MapleSim in Science and Engineering: a simulationbased approach

    In this research work I show the methods of embedded components together with modeling and simulation carried out with Maple and MapleSim for the main areas of science and engineering (mathematics, physics, civil, mechanical etc); These two latest scientific softwares belonging to the company Maplesoft. Designed to be generated and used by teachers of education, as well as by university teachers and engineers; the results are highly optimal since the times saved in calculations are invested in analyzes and interpretations; among other benefits; in this way we can use our applications in the cloud since web technology supports Maple code with procedural and component syntax.

    FAST_UNT_2020.pdf

    kinematics_curvilinear_updated_2020.mw

    Lenin AC

    Ambassador of Maple

     

     The Joint Mathematics Meetings are taking place next week (January 1518) in Denver, CO. This meeting is a must-attend for anyone interested in learning about innovative mathematical research, advancing mathematical achievement, providing the communication and tools to progress in the field, encouraging mathematical research, and connecting with the mathematical community.

    Maplesoft will at booth #1100  in the networking area (located just outside the exhibit hall doors). Stop by our booth or the networking area to chat with me and other members of the Maplesoft team, pick up some free Maplesoft swag or win some prizes. We’ve got some good ones!

    There are also several interesting Maple-related talks and events happening this week. 

    Attend our Workshop - Maple: Math Software for Teaching, Learning and Research

    Thursday January 16th, 2020

    Centennial Ballroom AHYATT Denver Colorado

    Catered Reception: 6:00PM6:30PM
    Training Workshop: 6:30PM8:00PM

    Are you new to the Maple world and interested in finding out what Maple can do for you? Are you an old hand at Maple but curious about the many new features we’ve added in the past few years? Come join us for an interactive workshop that will guide you through Maple’s capabilities, with an emphasis on our latest additions.

    The topics we’ll be covering include:

    • Our natural math notation for input and output
    • Tools for creating interactive documents that incorporate math, text and graphics
    • An overview of our vast library containing packages for advanced mathematics research scientific and engineering applications
    • A brief look at Maple’s powerful programming language|
    • Online and mobile tools that augment the Maple experience

    Register herewww.com/ 

    We are also 3 show floor talks, at the end of Aisle 600 inside the exhibits:

    The Maple Companion App

     January 15

    3:00 pm -3:55 pm

    Using Maple to Enhance Teaching and Learning

     January 16

    11:00 am-11:55 am

    The Maple Companion App

    January 17

    11:00 am- 11:55 am

     

    If you are attending the Joint Math Meetings and plan on presenting anything on Maple, please let me know and I'll add it to our list!


    See you there!

    Charlotte 

    with(plots):
    S:=cat("Happy New Year 2020!   "$3):
    N:=length(S): a:=0.77*Pi: h:=2*Pi/N:
    display(seq(textplot([cos(a-k*h), sin(a-k*h),S[k+1]], 
            rotation=-Pi/2+a-k*h, 'font'=["times","roman",24]), k=0..N-4), axes=none);
    

    When plotted, these parametric equations say "happy new year" (and were constructed with this worksheet)

    x := piecewise(t <= 58, -15.0*sin(1.43 + 0.650*t) - 14.8*sin(-1.64 + 0.703*t) - 1.28*sin(-2.97 + 1.25*t) - 11.9*sin(-1.58 + 0.540*t) - 1.07*sin(-1.60 + 1.35*t) - 3.85*sin(-2.09 + 1.41*t) - 7.13*sin(1.13 + 1.73*t) - 4.40*sin(1.32 + 1.30*t) - 26.3*sin(1.53 + 0.380*t) - 9.42*sin(-4.65 + 0.433*t) - 3.43*sin(1.42 + 2.06*t) - 7.57*sin(-1.77 + 2.11*t) - 2.65*sin(-4.34 + 0.323*t) - 1.95*sin(-4.57 + 2.54*t) - 5.39*sin(-1.38 + 2.60*t) - 49.2*sin(1.52 + 0.487*t) - 0.754*sin(-4.38 + 2.87*t) - 9.67*sin(-1.58 + 2.65*t) - 7.88*sin(-4.59 + 1.95*t) - 2.39*sin(-1.67 + 2.71*t) - 15.1*sin(1.53 + 0.108*t) - 39.0*sin(1.47 + 0.757*t) - 1.80*sin(1.37 + 2.22*t) - 4.22*sin(-1.95 + 0.973*t) - 7.72*sin(-1.44 + 2.17*t) - 8.80*sin(-1.66 + 0.813*t) - 3.59*sin(1.13 + 1.57*t) - 15.4*sin(-1.64 + 1.62*t) - 6.70*sin(1.36 + 1.19*t) - 791.*sin(-1.57 + 0.0540*t) - 2.55*sin(-1.55 + 1.89*t) - 6.92*sin(-1.87 + 1.68*t) - 3.95*sin(1.17 + 1.08*t) - 44.1*sin(-1.67 + 1.14*t) - 25.8*sin(1.51 + 0.597*t) - 31.4*sin(1.42 + 1.46*t) - 96.8*sin(-1.59 + 0.162*t) - 18.7*sin(1.53 + 0.217*t) - 7.87*sin(-4.66 + 2.98*t) - 4.99*sin(1.22 + 3.03*t) - 6.92*sin(1.43 + 2.44*t) - 48.3*sin(1.47 + 1.03*t) - 24.2*sin(1.48 + 1.52*t) - 9.58*sin(1.43 + 2.49*t) - 4.29*sin(1.33 + 2.27*t) - 6.34*sin(1.22 + 2.33*t) - 12.0*sin(1.45 + 2.00*t) - 0.388*sin(-1.25 + 2.92*t) - 2.74*sin(-1.43 + 1.79*t) - 6.71*sin(-1.66 + 1.84*t) - 0.713*sin(-3.63 + 2.38*t) - 43.1*sin(-1.59 + 0.271*t) - 2.51*sin(1.12 + 2.76*t) - 1.29*sin(-3.92 + 2.82*t) - 21.3*sin(-1.70 + 0.867*t) - 12.4*sin(1.50 + 0.920*t), 58 < t and t <= 84, -500 - 321.*sin(-8.608 + 0.121*t) - 7.18*sin(-12.408 + 0.241*t) - 57.1*sin(-22.608 + 0.361*t) - 21.9*sin(-26.682 + 0.484*t) - 21.3*sin(-33.474 + 0.603*t) - 50.2*sin(-43.800 + 0.725*t) - 20.6*sin(-50.760 + 0.845*t) - 41.5*sin(-54.756 + 0.967*t) - 9.74*sin(-61.89 + 1.09*t) - 41.1*sin(-72.03 + 1.21*t) - 2.49*sin(-78.88 + 1.33*t) - 3.30*sin(-83.227 + 1.45*t) - 6.73*sin(-89.99 + 1.57*t) - 5.88*sin(-96.59 + 1.69*t) - 16.4*sin(-106.99 + 1.81*t) - 1.61*sin(-111.8982 + 1.93*t) - 1.84*sin(-117.970 + 2.05*t) - 0.464*sin(-127.83 + 2.17*t) - 1.64*sin(-134.90 + 2.30*t) - 3.94*sin(-142.37 + 2.41*t) - 2.35*sin(-149.22 + 2.54*t) - 2.72*sin(-154.3362 + 2.66*t) - 8.41*sin(-160.453 + 2.78*t) - 4.39*sin(-171.17 + 2.90*t), 84 < t, -300 - 2.66*sin(-205.04 + 2.41*t) - 1.26*sin(-207.397 + 2.46*t) - 2.21*sin(-196.59 + 2.31*t) - 2.31*sin(-166.83 + 1.96*t) - 48.9*sin(-39.688 + 0.452*t) - 0.697*sin(-252.158 + 3.01*t) - 2.51*sin(-179.22 + 2.11*t) - 1.57*sin(-222.14 + 2.66*t) - 0.745*sin(-226.24 + 2.71*t) - 49.4*sin(-10.020 + 0.100*t) - 0.289*sin(-159.628 + 1.91*t) - 95.9*sin(-32.358 + 0.402*t) - 60.0*sin(-43.928 + 0.502*t) - 3.76*sin(-73.736 + 0.854*t) - 3.05*sin(-183.97 + 2.16*t) - 0.629*sin(-158.50 + 1.86*t) - 9.25*sin(-49.272 + 0.603*t) - 4.46*sin(-74.716 + 0.904*t) - 10.4*sin(-79.040 + 0.955*t) - 2.65*sin(-103.67 + 1.21*t) - 1.99*sin(-145.57 + 1.71*t) - 1.52*sin(-197.315 + 2.36*t) - 0.685*sin(-258.12 + 3.06*t) - 1.04*sin(-247.58 + 2.96*t) - 64.8*sin(-18.514 + 0.201*t) - 68.5*sin(-31.278 + 0.352*t) - 579.*sin(-5.8068 + 0.0502*t) - 6.52*sin(-95.20 + 1.11*t) - 5.03*sin(-96.28 + 1.16*t) - 0.396*sin(-211.620 + 2.51*t) - 7.28*sin(-150.00 + 1.76*t) - 2.42*sin(-153.92 + 1.81*t) - 10.4*sin(-112.11 + 1.31*t) - 24.8*sin(-85.95 + 1.00*t) - 3.91*sin(-124.83 + 1.46*t) - 1.69*sin(-185.369 + 2.21*t) - 1.18*sin(-189.238 + 2.26*t) - 16.6*sin(-56.662 + 0.653*t) - 1.33*sin(-222.31 + 2.61*t) - 0.593*sin(-238.70 + 2.81*t) - 1.88*sin(-233.58 + 2.76*t) - 3.91*sin(-133.01 + 1.56*t) - 4.94*sin(-134.16 + 1.61*t) - 9.59*sin(-128.89 + 1.51*t) - 1.02*sin(-240.2714 + 2.86*t) - 2.15*sin(-247.83 + 2.91*t) - 5.52*sin(-90.85 + 1.06*t) - 3.83*sin(-171.25 + 2.01*t) - 0.523*sin(-171.66 + 2.06*t) - 0.284*sin(-141.80 + 1.66*t) - 23.2*sin(-11.174 + 0.151*t) - 1.58*sin(-114.615 + 1.36*t) - 2.67*sin(-120.75 + 1.41*t) - 5.83*sin(-19.524 + 0.251*t) - 13.7*sin(-23.774 + 0.301*t) - 14.8*sin(-107.89 + 1.26*t) - 15.5*sin(-60.842 + 0.703*t) - 37.7*sin(-65.176 + 0.754*t) - 2.02*sin(-217.95 + 2.56*t) - 13.2*sin(-69.466 + 0.804*t) - 37.7*sin(-45.052 + 0.553*t)):

    y := piecewise(t <= 58, -28.1*sin(1.45 + 1.62*t) - 2.23*sin(-2.39 + 1.89*t) - 17.8*sin(-1.51 + 1.19*t) - 4.85*sin(-1.61 + 2.38*t) - 2.52*sin(1.55 + 1.95*t) - 20.0*sin(1.55 + 2.11*t) - 24.8*sin(-1.62 + 2.00*t) - 19.9*sin(-1.81 + 2.06*t) - 4.22*sin(-0.422 + 2.60*t) - 6.94*sin(1.47 + 2.87*t) - 61.1*sin(1.49 + 0.323*t) - 13.9*sin(-4.68 + 0.540*t) - 3.97*sin(0.00256 + 2.33*t) - 69.8*sin(1.53 + 0.487*t) - 59.6*sin(1.50 + 0.813*t) - 132.*sin(-1.65 + 0.867*t) - 26.7*sin(-1.76 + 1.52*t) - 53.1*sin(1.40 + 1.57*t) - 139.*sin(1.57 + 0.0540*t) - 3.75*sin(-2.34 + 3.03*t) - 8.03*sin(1.24 + 1.73*t) - 22.9*sin(-4.61 + 0.217*t) - 16.7*sin(-1.67 + 0.703*t) - 23.3*sin(-1.82 + 1.68*t) - 78.9*sin(-4.70 + 0.271*t) - 2.72*sin(-2.38 + 2.49*t) - 3.45*sin(1.10 + 2.54*t) - 2.07*sin(-0.489 + 2.22*t) - 13.1*sin(-1.82 + 2.27*t) - 60.6*sin(-1.62 + 1.08*t) - 5.27*sin(1.55 + 2.44*t) - 4.17*sin(1.46 + 2.82*t) - 33.1*sin(-1.80 + 1.46*t) - 2.15*sin(-1.58 + 0.757*t) - 3.94*sin(-3.86 + 2.65*t) - 8.88*sin(1.51 + 1.79*t) - 9.97*sin(1.52 + 1.84*t) - 105.*sin(1.48 + 1.03*t) - 15.2*sin(-4.67 + 1.25*t) - 101.*sin(1.51 + 0.380*t) - 11.0*sin(-4.59 + 0.433*t) - 86.7*sin(1.50 + 0.973*t) - 170.*sin(1.53 + 0.597*t) - 41.2*sin(1.51 + 0.650*t) - 20.4*sin(-1.67 + 1.30*t) - 47.9*sin(-1.70 + 1.35*t) - 15.8*sin(-1.66 + 2.71*t) - 8.61*sin(-1.71 + 2.76*t) - 25.7*sin(-1.64 + 0.108*t) - 70.9*sin(1.55 + 0.162*t) - 0.668*sin(-2.42 + 2.92*t) - 4.78*sin(-4.60 + 2.98*t) - 106.*sin(1.49 + 0.920*t) - 17.6*sin(1.53 + 1.41*t) - 8.82*sin(1.05 + 2.17*t) - 113.*sin(-1.67 + 1.14*t), t <= 84, -800 - 7.30*sin(-171.17 + 2.90*t) - 3.28*sin(-6.550 + 0.121*t) - 1.46*sin(-17.878 + 0.241*t) - 20.4*sin(-22.438 + 0.361*t) - 28.9*sin(-29.862 + 0.484*t) - 9.13*sin(-36.364 + 0.603*t) - 45.3*sin(-40.650 + 0.725*t) - 97.4*sin(-50.770 + 0.845*t) - 13.1*sin(-54.916 + 0.967*t) - 80.8*sin(-61.97 + 1.09*t) - 39.1*sin(-71.92 + 1.21*t) - 42.8*sin(-78.87 + 1.33*t) - 108.*sin(-85.97 + 1.45*t) - 10.6*sin(-92.80 + 1.57*t) - 49.8*sin(-99.94 + 1.69*t) - 15.4*sin(-103.75 + 1.81*t) - 24.2*sin(-113.90 + 1.93*t) - 8.96*sin(-123.18 + 2.05*t) - 1.59*sin(-127.14 + 2.17*t) - 14.1*sin(-137.59 + 2.30*t) - 6.51*sin(-142.35 + 2.41*t) - 7.98*sin(-145.83 + 2.54*t) - 6.40*sin(-153.721 + 2.66*t) - 1.23*sin(-164.36 + 2.78*t), 84 < t, -1400 - 128.*sin(-32.358 + 0.402*t) - 68.5*sin(-43.928 + 0.502*t) - 2.55*sin(-242.18 + 2.86*t) - 6.86*sin(-219.136 + 2.61*t) - 5.76*sin(-222.904 + 2.66*t) - 2.39*sin(-226.835 + 2.71*t) - 101.*sin(-11.164 + 0.151*t) - 8.69*sin(-231.548 + 2.76*t) - 146.*sin(-31.268 + 0.352*t) - 8.30*sin(-179.37 + 2.11*t) - 2.68*sin(-261.69 + 3.06*t) - 10.4*sin(-162.98 + 1.91*t) - 30.1*sin(-73.606 + 0.854*t) - 24.1*sin(-77.946 + 0.904*t) - 10.0*sin(-146.01 + 1.71*t) - 72.5*sin(-69.416 + 0.804*t) - 8.91*sin(-85.97 + 1.00*t) - 8.58*sin(-175.51 + 2.06*t) - 27.4*sin(-109.01 + 1.31*t) - 16.8*sin(-113.17 + 1.36*t) - 162.*sin(-5.7968 + 0.0502*t) - 3.69*sin(-205.52 + 2.41*t) - 7.62*sin(-207.006 + 2.46*t) - 131.*sin(-53.522 + 0.653*t) - 95.3*sin(-60.882 + 0.703*t) - 8.53*sin(-197.627 + 2.36*t) - 1.74*sin(-247.32 + 2.91*t) - 27.2*sin(-121.51 + 1.46*t) - 51.7*sin(-49.332 + 0.603*t) - 8.81*sin(-104.925 + 1.26*t) - 10.2*sin(-100.703 + 1.21*t) - 9.35*sin(-183.90 + 2.16*t) - 7.82*sin(-188.20 + 2.21*t) - 42.8*sin(-26.964 + 0.301*t) - 16.8*sin(-48.312 + 0.553*t) - 15.2*sin(-9.980 + 0.100*t) - 213.*sin(-18.524 + 0.201*t) - 39.4*sin(-19.584 + 0.251*t) - 6.28*sin(-87.85 + 1.06*t) - 3.71*sin(-117.623 + 1.41*t) - 4.92*sin(-196.77 + 2.31*t) - 1.25*sin(-255.21 + 3.01*t) - 5.13*sin(-248.529 + 2.96*t) - 8.69*sin(-141.43 + 1.66*t) - 11.5*sin(-167.26 + 1.96*t) - 13.0*sin(-171.19 + 2.01*t) - 4.12*sin(-159.23 + 1.86*t) - 3.66*sin(-212.23 + 2.51*t) - 0.810*sin(-83.380 + 0.955*t) - 3.11*sin(-65.516 + 0.754*t) - 1.38*sin(-139.34 + 1.61*t) - 9.07*sin(-188.885 + 2.26*t) - 52.6*sin(-39.678 + 0.452*t) - 6.81*sin(-125.917 + 1.51*t) - 24.7*sin(-130.128 + 1.56*t) - 4.16*sin(-215.362 + 2.56*t) - 11.8*sin(-92.283 + 1.11*t) - 16.6*sin(-96.32 + 1.16*t) - 6.39*sin(-147.108 + 1.76*t) - 7.61*sin(-154.46 + 1.81*t) - 4.28*sin(-235.566 + 2.81*t)):

    plot( [ x, y, t = 0 .. 146 ], scaling = constrained, discont = [ usefdiscont ], axes = boxed, thickness = 5, size = [600, 600]);

     

    Here is a little animation to wish all of you a Merry Christmas

    FireWorks.mw


    Here we simulate the motion of a container with a flat bottom that can slide on a horizontal surface subject to dry friction (Coulomb friction).  Installed inside the container is an ordinary mass/spring/damper system where the mass slides horizontally.  We impart an initial velocity to the container.  That sets the mass into motion which then affects the container's motion.  Under certain conditions the container will undergo a stick-slip motion which is evident in the simulation.

    This simulation very roughly approximates the motion of a partially filled bucket of water that slides on the floor when kicked.  The idea arose in a discussoin with Carl Love and mmcdara:
    https://www.mapleprimes.com/posts/211677-Mass-Spring-Conveyor-Belt-And-Dry-Friction

    In the animation below, the container is shown in dark color when it slides against the floor, and light color when it sticks.

    Worksheet: slosh.mw

     

    Here is an animation of a mass-spring system where the mass slides horizontally on a steadily moving conveyor belt.

    The contact between the block of mass and the belt is of the dry friction kind (Coulomb's friction). Consequently the block periodically sticks to the belt and moves forward with it until the force of the stretching spring overcomes the force of friction and yanks it back, making it to slip against the belt. In the animation the block is shown in a dark color while slipping, and a light color while sticking.

    The fully executed Maple worksheet can be slow to load and requires a good deal of memory. Therefore I have attached two versions which are identical in all respects except that in one of them I have removed the Maple output to make is easy to load if your computer has limitations.

    Download worksheet (no Maple output) block-sliding-on-conveyor-belt-stripped.mw

    Doiwnload worksheet (with Maple output) (sorry, exceeds MaplePrime's size limit)

    Hi, 

    This is more of an open discussion than a real question. Maybe it would gain to be displaced in the post section?

    Working with discrete random variables I found several inconsistencies or errors.
    In no particular order: 

    • The support of a discrete RV is not defined correctly (a real range instead of a countable set)
    • The plot of the probability function (which, in my opinion, would gain to be renamed "Probability Mass Function, see https://en.wikipedia.org/wiki/Probability_mass_function) is not correct.
    • The  ProbabiliytFunction of a discrte rv of EmpiricalDistribution can be computed at any point, but its formal expression doesn't exist (or at least is not accessible).
    • Defining the discrete rv "toss of a fair dice"  with EmpiricalDistribution and DiscreteUniform gives different results.


    The details are given in the attached file and I do hope that the companion text is clear enough to point the issues.
    I believe there is no major issues here, but that Maple suffers of some lack of consistencies in the treatment of discrete (at least some) rvs. Nothing that could easily be fixed.


    As I said above, if some think this question has no place here and ought to me moved to the post section, please feel free to do it.

    Thanks for your attention.


     

    restart:

    with(Statistics):


    Two alternate ways to define a discrete random variable on a finite set
    of equally likely outcomes.

    Universe    := [$1..6]:
    toss_1_dice := RandomVariable(EmpiricalDistribution(Universe));
    TOSS_1_DICE := RandomVariable(DiscreteUniform(1, 6));

    _R

     

    _R0

    (1)


    Let's look to the ProbabilityFunction of each RV

    ProbabilityFunction(toss_1_dice, x);
    ProbabilityFunction(TOSS_1_DICE, x);

    "_ProbabilityFunction[Typesetting:-mi("x",italic = "true",mathvariant = "italic")]"

     

    piecewise(x < 1, 0, x <= 6, 1/6, 6 < x, 0)

    (2)


    It looks like the procedure ProbabilityFunction is not an attribute of RV with EmpiticalDistribution.
    Let's verify

    law := [attributes(toss_1_dice)][3]:
    lprint(exports(law))

    Conditions, ParentName, Parameters, CDF, DiscreteValueMap, Mean, Median, Mode, ProbabilityFunction, Quantile, Specialize, Support, RandomSample, RandomVariate

     


    Clearly ProbabilityFunction is an attribute of toss_1_dice.

    In fact it appears the explanation of the difference of behaviours relies upon different definitions
    of the set of outcomes of toss_1_dice and TOSS_1_DICE

    LAW := [attributes(TOSS_1_DICE)][3]:
    exports(LAW):

    law:-Conditions;
    LAW:-Conditions;

    [(Vector(6, {(1) = 1, (2) = 2, (3) = 3, (4) = 4, (5) = 5, (6) = 6}))::rtable]

     

    [1 < 6]

    (3)


    From :-Conditions one can see that toss_1_dice is realy a discrete RV defined on a countable set of outcomes,
    but that nothing is said about the set over which TOSS_1_DICE is defined.

    The truly discrete definition of toss_1_dice is confirmed here :
    (the second result is correct

    ProbabilityFinction(toss_1_dice, x) = {0 if x < 1, 0 if x > 6, 1/6 if x::integer, 0 otherwise

    ProbabilityFunction~(toss_1_dice, Universe);
    ProbabilityFunction~(toss_1_dice, [seq(0..7, 1/2)]);

    [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]

     

    [0, 0, 1/6, 0, 1/6, 0, 1/6, 0, 1/6, 0, 1/6, 0, 1/6, 0, 0]

    (4)


    One can also see that the Support of both of these RVs are wrong

    (see for instance https://en.wikipedia.org/wiki/Discrete_uniform_distribution)

    There should be {1, 2, 3, 4, 5, 6}, not a RealRange.

    Support(toss_1_dice);
    Support(TOSS_1_DICE);

    RealRange(1, 6)

     

    RealRange(1, 6)

    (5)

     

    0

     

    {1, 2, 3, 4, 5, 6}

     

     


    Now this is the surprising ProbabilityFunction of TOSS_1_DICE.
    This obviously wrong result probably linked to the weak definition of the conditions for this RB.

    # plot(ProbabilityFunction(TOSS_1_DICE, x), x=0..7);
    plot(ProbabilityFunction(TOSS_1_DICE, x), x=0..7, discont=true)

     


    These differences of treatments raise a lot of questions :
        -  Why is a DiscreteUniform RV not defined on a countable set?
        -  Why does the ProbabilityFunction of an EmpiricalDistribution return no result
            if its second parameter is not set to one  its outcomes.

     All this without even mentioning the wrong plot shown above.
     

    I believe something which would work like the module below would be much better than what is done

    right now

     

    EmpiricalRV := module()
    export MassDensityFunction, PlotMassDensityFunction, Support:

    MassDensityFunction := proc(rv, x)
      local u, v, N:
      u := [attributes(rv)][3]:
      if u:-ParentName = EmpiricalDistribution then
        v := op([1, 1], u:-Conditions);
        N := numelems(v):
        return piecewise(op(op~([seq([x=v[n], 1/N], n=1..N)])), 0)
      else
        error "The random variable does not have an EmpiricalDistribution"
      end if
    end proc:

    PlotMassDensityFunction := proc(rv, x1, x2)
      local u, v, a, b:
      u := [attributes(rv)][3]:
      if u:-ParentName = EmpiricalDistribution then
        v := op([1, 1], u:-Conditions);
        a := select[flatten](`>=`, v, x1);
        b := select[flatten](`<=`, a, x2);
        PLOT(seq(CURVES([[n, 0], [n, 1/numelems(v)]], COLOR(RGB, 0, 0, 1), THICKNESS(3)), n in b), VIEW(x1..x2, default))
      else
        error "The random variable does not have an EmpiricalDistribution"
      end if
    end proc:

    Support := proc(rv, x1, x2)
      local u, v, a, b:
      u := [attributes(rv)][3]:
      if u:-ParentName = EmpiricalDistribution then
        v := op([1, 1], u:-Conditions);
        return {entries(v, nolist)}
      else
        error "The random variable does not have an EmpiricalDistribution"
      end if
    end proc:

    end module:
     

    EmpiricalRV:-MassDensityFunction(toss_1_dice, x);
     

    piecewise(x = 1, 1/6, x = 2, 1/6, x = 3, 1/6, x = 4, 1/6, x = 5, 1/6, x = 6, 1/6, 0)

    (6)

    f := unapply(EmpiricalRV:-MassDensityFunction(toss_1_dice, x), x):
    f(2);
    f(5/2);
     

    1/6

     

    0

    (7)

    EmpiricalRV:-PlotMassDensityFunction(toss_1_dice, 0, 7);

     

     


     

    Download Discrete_RV.mw

     

     

    We need a check-off box for Maple Companion in the Products category of Question and Post headers.

    While you're looking at that, there's also a bug that the Product indication gets stripped off when converting a Post to a Question, which is a common Moderator action.

    Here is two solutions with Maple of the problem A2 of  Putnam Mathematical Competition 2019 . The first solution is entirely based on the use of the  geometry  package; the second solution does not use this package. Since the triangle is defined up to similarity, without loss of generality, we can set its vertices  A(0,0) , B(1,0) , C(x0,y0)  and then calculate the parameters  x0, y0  using the conditions of the problem. 


     

    The problem

    A2: In the triangle ∆ABC, let G be the centroid, and let I be the center of the
    inscribed circle. Let α and β be the angles at the vertices A and B, respectively.
    Suppose that the segment IG is parallel to AB and that  β = 2*arctan(1/3).  Find α.
     

    # Solution 1 with the geometry package
    restart;

    # Calculation

    with(geometry):
    local I:
    point(A,0,0): point(B,1,0): point(C,x0,y0):
    assume(y0>0,-y0*(-1+x0-((1-x0)^2+y0^2)^(1/2))+y0*((x0^2+y0^2)^(1/2)+x0) <> 0):
    triangle(t,[A,B,C]):
    incircle(ic,t, 'centername'=I):
    Cn:=coordinates(I):
    centroid(G,t):
    CG:=coordinates(G):
    a:=-expand(tan(2*arctan(1/3))):
    solve({Cn[2]=CG[2],y0/(x0-1)=a}, explicit);
    point(C,eval([x0,y0],%)):
    answer=FindAngle(line(AB,[A,B]),line(AC,[A,C]));

    # Visualization (G is the point of medians intersection)

    triangle(t,[A,B,C]):
    incircle(ic,t, 'centername'=I):
    centroid(G,t):
    segment(s,[I,G]):
    median(mB,B,t): median(mC,C,t):
    draw([A(symbol=solidcircle,color=black),B(symbol=solidcircle,color=black),C(symbol=solidcircle,color=black),I(symbol=solidcircle,color=green),G(symbol=solidcircle,color=blue),t(color=black),s(color=red,thickness=2),ic(color=green),mB(color=blue,thickness=0),mC(color=blue,thickness=0)], axes=none, size=[800,500], printtext=true,font=[times,20]);

    I

     

    Warning, The imaginary unit, I, has been renamed _I

     

    Warning, solve may be ignoring assumptions on the input variables.

     

    {x0 = 0, y0 = 3/4}

     

    answer = (1/2)*Pi

     

     


    # Solution 2 by a direct calculation

    # Calculation

    restart;
    local I;
    sinB:=y0/sqrt(x0^2+y0^2):
    cosB:=x0/sqrt(x0^2+y0^2):
    Sol1:=eval([x,y],solve({y=-(x-1)/3,y=(sinB/(1+cosB))*x}, {x,y})):
    tanB:=expand(tan(2*arctan(1/3))):
    Sol2:=solve({y0/3=Sol1[2],y0=-tanB*(x0-1)},explicit);
    A:=[0,0]: B:=[1,0]: C:=eval([x0,y0],Sol2[2]):
    AB:=<(B-A)[]>: AC:=<(C-A)[]>:
    answer=arccos(AB.AC/sqrt(AB.AB)/sqrt(AC.AC));

    # Visualization

    with(plottools): with(plots):
    ABC:=curve([A,B,C,A]):
    I:=simplify(eval(Sol1,Sol2[2]));
    c:=circle(I,eval(Sol1[2],Sol2[2]),color=green):
    G:=(A+B+C)/~3;
    IG:=line(I,G,color=red,thickness=2):
    P:=pointplot([A,B,C,I,G], color=[black$3,green,blue], symbol=solidcircle):
    T:=textplot([[A[],"A"],[B[],"B"],[C[],"C"],[I[],"I"],[G[],"G"]], font=[times,20], align=[left,below]):
    M:=plot([[(C+t*~((A+B)/2-C))[],t=0..1],[(B+t*~((A+C)/2-B))[],t=0..1]], color=blue, thickness=0):
    display(ABC,c,IG,P,T,M, scaling=constrained, axes=none,size=[800,500]);

    I

     

    Warning, The imaginary unit, I, has been renamed _I

     

    {x0 = 1, y0 = 0}, {x0 = 0, y0 = 3/4}

     

    answer = (1/2)*Pi

     

    [1/4, 1/4]

     

    [1/3, 1/4]

     

     

     


     

    Download Putnam.mw

     

    Maple can easily solve the B4 problem of the Putnam Mathematical Competition 2019  link

     

    B4.  Let F be the set of functions f(x,y) that are twice continuously differentiable for x≥1, y≥1 and that satisfy the following two equations:
        x*(diff(f(x, y), x))+y*(diff(f(x, y), y)) = x*y*ln(x*y)

    x^2*(diff(f(x, y), x, x))+y^2*(diff(f(x, y), y, y)) = x*y

     

    For each f2F, let

     

    "m(f) = min[s>=1]  (f(s+1,s+1)-f(s+1,s)-f(s,s+1)+f(s,s))"

     

    Determine m(f), and show that it is independent of the choice of f.


     

    # Solution

    pdsolve({
    x*diff(f(x,y),x)+y*diff(f(x,y),y) = x*y*ln(x*y),
    x^2*diff(f(x,y),x,x)+y^2*diff(f(x,y),y,y) = x*y
    });

    {f(x, y) = (1/2)*(x*y+2*_C1)*ln(x*y)-(1/2)*x*y-2*_C1*ln(x)+_C2}

    (1)

    f:=unapply(rhs(%[]), x,y);

    proc (x, y) options operator, arrow; (1/2)*(y*x+2*_C1)*ln(y*x)-(1/2)*y*x-2*_C1*ln(x)+_C2 end proc

    (2)

    h := f(s+1, s+1) - f(s+1, s) - f(s, s+1) + f(s, s);

    (1/2)*((s+1)^2+2*_C1)*ln((s+1)^2)-(1/2)*(s+1)^2-(s*(s+1)+2*_C1)*ln(s*(s+1))+s*(s+1)+(1/2)*(s^2+2*_C1)*ln(s^2)-(1/2)*s^2

    (3)

    minimize(h, s=1..infinity);

    (4+2*_C1)*ln(2)-1/2-(2+2*_C1)*ln(2)

    (4)

    answer = simplify(%);

    answer = 2*ln(2)-1/2

    (5)

     


    Download putnam2019-b4.mw

    Hi, 

    As an amusement,  I decided several months ago to develop some procedures to fill a simple polygon* by hatches or simple textures.

    * A simple polygon is a polygon  whose sides either do not intersect or either have a common vertex.

    This work started with the very simple observation that if I was capable to hatch or texture a triangle, I will be too to hatch or texture any simple polygon once triangulated.
    I also did some work to extend this work to non-simple polygons but there remains some issues to fix (which explains while it is not deliverd here).

    The main ideat I used for hatching and texturing is based upon the description of each triangles by a set of 3 inequalities that any interior point must verify.
    A hatch of this triangle is thius a segment whose each point is interior.
    The closely related idea is used for texturing. Given a simple polygon, periodically replicated to form the texture, the set of points of each replicate that are interior to a given triangle must verify a set of inequalities (the 3 that describe the triangle, plus N if the pattern of the texture is a simple polygon with N sides).

    Unfortunately I never finalise this work.
    Recently @Christian Wolinski asked a question about texturing that reminded me this "ancient" work of mine.
    So I decided to post it as it is, programatically imperfect, lengthy to run, and most of all french-written for a large part.
    I guess it is a quite unorthodox way to proceed but some here could be interested by this work to take it back and improve it.

    The module named "trianguler" (= triangulate) is a translation into Maple of Frederic Legrand's Python code (full reference given in the worksheet).
    I added my own procedure "hachurer" (= hatching) to this module.
    The texturing part is not included in this module for it was still in development.

    A lot of improvements can be done that I could list, but I prefer not to be too intrusive in your evaluation of this work. So make your own idea about it and do not hesitate to ask me any informations you might need (in particular translation questions).


    PS: this work has been done with Maple 2015.2
     

    restart:


    Reference: http://www.f-legrand.fr/scidoc/docmml/graphie/geometrie/polygone/polygone.html
                        (in french)
                        reference herein : M. de Berg, O. Cheong, M. van Kreveld, M. Overmars,  
                                                     Computational geometry,  (Springer, 2010)

    Direct translation of the Frederic Legrand's Python code


    Meaning of the different french terms

    voisin_sommet  (n, i, di)
            let L the list [1, ..., n] where n is the number of vertices
            This procedure returns the index of the neighbour (voisin) of the vertex (sommet) i when L is rotated by di

    equation_droite  (P0, P1, M)
            Let P0 and P1 two vertices and M an arbitrary point.
            Let (P0, P1) the vector originated at P0 and ending at P1 (idem for (P0, M)) and u__Z the unitary vector in the Z direction.
            This procedure returns (P0, P1) o (P0, M) . u__Z

    point_dans_triangle  (triangle, M) P1, P2]
            This procedure returns "true" if point M is within (strictly) the  triangle "triangle" and "false" if not.

    sommet_distance_maximale  (polygone, P0, P1, P2, indices)    
            Given a polygon (polygone) threes vertices P0, P1 and P2 and a list of indices , this procedure returns
            the vertex of the polygon "polygone" which verifies: 1/ this vertex is strictly within
            the triangle [P0, P1, P2] and 2/ it is the farthest from side [P1, P2] amid all the vertices that verifies point 1/.
            If there is no such vertex the procedure returns NULL.

    sommet_gauche (polygone)
            This procedure returns the index of the leftmost ("gauche" means "left") vertex in polygon "polygone".
            If more than one vertices have the same minimum abscissa value then only the first one is returned.

    nouveau_polygone(polygone,i_debut,i_fin)
            This procedure creates a new polygon from index i_debut (could be translated by i_first) to i_end (i_last)

    trianguler_polygone_recursif(polygone)
            This procedure recursively divides a polygon in two parts A and B from its leftmost vertex.
             If A (B) is a triangle the list "liste_triangles" (mening "list of triangles") is augmented by A (B);
             if not the procedure executes recursively on A and B.

    trianguler_polygone(polygone)
             This procedure triangulates the polygon "polygon"

    hachurer(shapes, hatch_angle, hatch_number, hatch_color)
             This procedure generates stes of hatches of different angles, colors and numbers


    Limitations:
       1/ "polygone" is a simply connected polygon
       2/  two different sides S and S', either do not intersect or either have a common vertex

    trianguler := module()
    export voisin_sommet, equation_droite, interieur_forme, point_dans_triangle, sommet_distance_maximale,
           sommet_gauche, nouveau_polygone, trianguler_polygone_recursif, trianguler_polygone, hachurer:

    #-------------------------------------------------------------------
    voisin_sommet := (n, i, di) -> ListTools:-Rotate([$1..n], di)[i]:



    #-------------------------------------------------------------------
    equation_droite := proc(P0, P1, M) (P1[1]-P0[1])*(M[2]-P0[2]) - (P1[2]-P0[2])*(M[1]-P0[1]) end proc:


    #-------------------------------------------------------------------
    interieur_forme := proc(forme, M)
      local N:
      N := numelems(forme);
      { seq( equation_droite(forme[n], forme[piecewise(n=N, 1, n+1)], M) >= 0, n=1..N) }
    end proc:


    #-------------------------------------------------------------------
    point_dans_triangle := proc(triangle, M)
      `and`(
              is( equation_droite(triangle[1], triangle[2], M) > 0 ),
              is( equation_droite(triangle[2], triangle[3], M) > 0 ),
              is( equation_droite(triangle[3], triangle[1], M) > 0 )
           )
    end proc:



    #-------------------------------------------------------------------
    sommet_distance_maximale := proc(polygone, P0, P1, P2, indices)
      local n, distance, j, i, M, d;

      n        := numelems(polygone):
      distance := 0:
      j        := NULL:

      for i from 1 to n do
        if `not`(member(i, indices)) then
          M := polygone[i];
          if point_dans_triangle([P0, P1, P2], M) then
            d := abs(equation_droite(P1, P2, M)):
            if d > distance then
              distance := d:
              j := i
            end if:
          end if:
        end if:
      end do:
      return j:
    end proc:


    #-------------------------------------------------------------------
    sommet_gauche := polygone -> sort(polygone, key=(x->x[1]), output=permutation)[1]:



    #-------------------------------------------------------------------
    nouveau_polygone := proc(polygone, i_debut, i_fin)
      local n, p, i:

      n := numelems(polygone):
      p := NULL:
      i := i_debut:

      while i <> i_fin do
        p := p, polygone[i]:
        i := voisin_sommet(n, i, 1)
      end do:
      p := [p, polygone[i_fin]]
    end proc:



    #-------------------------------------------------------------------
    trianguler_polygone_recursif := proc(polygone)
      local n, j0, j1, j2, P0, P1, P2, j, polygone_1, polygone_2:
      global liste_triangles:
      n  := numelems(polygone):
      j0 := sommet_gauche(polygone):
      j1 := voisin_sommet(n, j0, +1):
      j2 := voisin_sommet(n, j0, -1):
      P0 := polygone[j0]:
      P1 := polygone[j1]:
      P2 := polygone[j2]:
      j  := sommet_distance_maximale(polygone, P0, P1, P2, [j0, j1, j2]):

      if `not`(j::posint) then
        liste_triangles := liste_triangles, [P0, P1, P2]:
        polygone_1      := nouveau_polygone(polygone,j1,j2):
        if numelems(polygone_1) = 3 then
          liste_triangles := liste_triangles, polygone_1:
        else
          thisproc(polygone_1)
        end if:

      else
        polygone_1 := nouveau_polygone(polygone, j0, j ):
        polygone_2 := nouveau_polygone(polygone, j , j0):
        if numelems(polygone_1) = 3 then
          liste_triangles := liste_triangles, polygone_1:
        else
          thisproc(polygone_1)
        end if:
        if numelems(polygone_2) = 3 then
          liste_triangles := liste_triangles, polygone_2:
        else
          thisproc(polygone_2)
        end if:
      end if:

      return [liste_triangles]:
    end proc:


    #-------------------------------------------------------------------
    trianguler_polygone := proc(polygone)
      trianguler_polygone_recursif(polygone):
      return liste_triangles:
    end proc:


    #-------------------------------------------------------------------
    hachurer := proc(shapes, hatch_angle::list, hatch_number::list, hatch_color::list)

    local A, La, Lp;
    local N, P, _sides, L_sides, Xshape, ch, rel, p_rel, n, sol, p_range:
    local AllHatches, window, p, _segment:
    local NT, ka, N_Hatches, p_range_t, nt, shape, p_hatches, WhatHatches:

    #-----------------------------------------------------------------
    # internal functions:
    #
    # La(x, y, alpha, p) is the implicit equation of a straight line of angle alpha relatively
    #                    to the horizontal axis and intercept p
    #
    # Lp(x, y, P) is the implicit equation of a straight line passing through points P[1] and P[2]
    #
    # interieur_triangle(triangle, M)

    La := (x, y, alpha, p) -> cos(alpha)*x - sin(alpha)*y + p;
    Lp := proc(x, y, P::list) (x-P[1][1])*(P[2][2]-P[1][2]) - (y-P[1][2])*(P[2][1]-P[1][1] = 0) end proc;


    p_range    := [+infinity, -infinity]:
    NT         := numelems(shapes):

    AllHatches := NULL:

    for ka from 1 to numelems(hatch_angle) do
      A         := hatch_angle[ka]:
      N_Hatches := hatch_number[ka]:
      p_range_t := NULL:
      _sides    := []:
      L_sides   := []:
      rel       := []:
      for nt from 1 to NT do

        shape := shapes[nt]:
        # _sides  : two points description of the sides of the shape
        # L_sides : implicit equations of the straight lines that support the sides

        N        := [1, 2, 3];
        P        := [2, 3, 1];
        _sides   := [ _sides[] , [ seq([shape[n], shape[P[n]]], n in N) ] ];
        L_sides  := [ L_sides[], Lp~(x, y, _sides[-1]) ];

        # Inequalities that define the interior of the shape

        rel := [ rel[], trianguler:-interieur_forme(shape, [x, y]) ];
      
        # Given the orientation of the hatches we search here the extreme values of
        # the intercept p for wich a straight line of equation La(x, y, alpha, p)
        # cuts the shape.
        
        p_rel := NULL:
        
        for n from 1 to numelems(L_sides[-1]) do
          sol   := solve({La(x, y, A, q), lhs(L_sides[-1][n])} union rel[-1], [x, y]);
          p_rel := p_rel, `if`(sol <> [], [rhs(op(1, %)), rhs(op(3, %))], [+infinity, -infinity]);
        end do:
        p_range_t := p_range_t, evalf(min(op~(1, [p_rel]))..max(op~(2, [p_rel])));
        p_range   := evalf(min(op~(1, [p_rel]), op(1, p_range))..max(op~(2, [p_rel]), op(2, p_range)));

      end do: # end of the loop over triangles

      p_range_t := [p_range_t]:
      p_hatches := [seq(p_range, (op(2, p_range)-op(1, p_range))/N_Hatches)]:
      # Building of the hatches
      #
      # This construction is far from being optimal.
      # Here again the main goal was to obtain the hatches with a minimum effort
      # if algorithmic development.

      window      := min(op~(1..shape))..max(op~(1..shape)):
      WhatHatches := map(v -> map(u -> if verify(u, v, 'interval'('closed') ) then u end if, p_hatches), p_range_t):

      for nt from 1 to NT do
        for p in WhatHatches[nt] do
          _segment := []:
          for n from 1 to numelems(L_sides[nt]) do
             _segment := _segment, evalf( solve({La(x, y, A, p), lhs(L_sides[nt][n])} union rel[nt], [x, y]) );
          end do;
          map(u -> u[], [_segment]);
          AllHatches := AllHatches, plot(map(u -> rhs~(u), %), color=hatch_color[ka]):
        end do:
      end do;

    end do: # end of loop over hatch angles

    plots:-display(
      PLOT(POLYGONS(polygone, COLOR(RGB, 1$3))),
      AllHatches,
      scaling=constrained
    )

    end proc:

    end module:

     

    Legrand's example (see reference above)

     

     

    global liste_triangles:
    liste_triangles := NULL:

    polygone := [[0,0],[0.5,-1],[1.5,-0.2],[2,-0.5],[2,0],[1.5,1],[0.3,0],[0.5,1]]:

    trianguler:-trianguler_polygone(polygone):

    PLOT(seq(POLYGONS(u, COLOR(RGB, rand()/10^12, rand()/10^12, rand()/10^12)), u in liste_triangles), VIEW(0..2, -2..2))

     

    trianguler:-hachurer([liste_triangles], [-Pi/4, Pi/4], [40, 40], [red, blue])
     

     

    F := (P, a, b) -> map(p -> [p[1]+a, p[2]+b], P):

    MOTIF  := [[0, 0], [0.05, 0], [0.05, 0.05], [0, 0.05]];
    motifs := [ seq(seq(F(MOTIF, 0+i*0.075, 0+j*0.075), i=0..26), j=-14..13) ]:

    plots:-display(
      plot([polygone[], polygone[1]], color=red, filled),
      map(u -> plot([u[], u[1]], color=blue, filled, scaling=constrained), motifs)
    ):

    texture    := NULL:
    rel_motifs := map(u -> trianguler:-interieur_forme(u, [x, y]), motifs):
      
    for ref in liste_triangles do
      ref;
      #
      # the three lines below are used to define REF counter clockwise
      #
      g           := trianguler:-sommet_gauche(ref):
      bas         := sort(op~(2, ref), output=permutation);
      REF         := ref[[g, op(map(u -> if u<>g then u end if, bas))]];
      rel_ref     := trianguler:-interieur_forme(REF, [x, y]): #print(ref, REF, rel_ref);
      texture_ref := map(u -> plots:-inequal(rel_ref union u, x=0..2, y=-1..1, color=blue, 'nolines'), rel_motifs):
      texture     := texture, texture_ref:
    end do:

    plots:-display(
      plot([polygone[], polygone[1]], color=red, scaling=constrained),
      texture
    )

    [[0, 0], [0.5e-1, 0], [0.5e-1, 0.5e-1], [0, 0.5e-1]]

     

     

    MOTIF  := [[0, 0], [0.05, 0], [0.05, 0.05], [0, 0.05]];
    motifs := [ seq(seq(F(MOTIF, piecewise(j::odd, 0.05, 0.1)+i*0.1, 0+j*0.05), i=-0.2..20), j=-20..20) ]:
    plots:-display(
      plot([polygone[], polygone[1]], color=red, filled),
      map(u -> plot([u[], u[1]], color=blue, filled, scaling=constrained), motifs)
    ):

    texture    := NULL:
    rel_motifs := map(u -> trianguler:-interieur_forme(u, [x, y]), motifs):
      
    for ref in liste_triangles do
      ref;
      g := trianguler:-sommet_gauche(ref):
      bas := sort(op~(2, ref), output=permutation);
      REF := ref[[g, op(map(u -> if u<>g then u end if, bas))]];
      rel_ref     := trianguler:-interieur_forme(REF, [x, y]): #print(ref, REF, rel_ref);
      texture_ref := map(u -> plots:-inequal(rel_ref union u, x=0..2, y=-1..1, color=blue, 'nolines'), rel_motifs):
      texture     := texture, texture_ref:
    end do:

    plots:-display(
      plot([polygone[], polygone[1]], color=red, scaling=constrained),
      texture
    )

    [[0, 0], [0.5e-1, 0], [0.5e-1, 0.5e-1], [0, 0.5e-1]]

     

     

    MOTIF  := [[0, 0], [0.4, 0], [0.4, 0.14], [0, 0.14]]:
    motifs := [ seq(seq(F(MOTIF, piecewise(j::odd, 0.4, 0.2)+i*0.4, 0+j*0.14), i=-1..4), j=-8..7) ]:


    plots:-display(
      plot([polygone[], polygone[1]], color=red, filled),
      map(u -> plot([u[], u[1]], color=blue, filled, scaling=constrained), motifs)
    ):

    palettes := ColorTools:-PaletteNames():
    ColorTools:-GetPalette("HTML"):

    couleurs := [SandyBrown, PeachPuff, Peru, Linen, Bisque, Burlywood, Tan, AntiqueWhite,      NavajoWhite, BlanchedAlmond, PapayaWhip, Moccasin, Wheat]:

    nc   := numelems(couleurs):
    roll := rand(1..nc):

    motifs_nb      := numelems(motifs):
    motifs_couleur := [ seq(cat("HTML ", couleurs[roll()]), n=1..motifs_nb) ]:

    texture    := NULL:
    rel_motifs := map(u -> trianguler:-interieur_forme(u, [x, y]), motifs):
      
    for ref in liste_triangles do
      ref;
      g := trianguler:-sommet_gauche(ref):
      bas := sort(op~(2, ref), output=permutation);
      REF := ref[[g, op(map(u -> if u<>g then u end if, bas))]];
      rel_ref     := trianguler:-interieur_forme(REF, [x, y]): #print(ref, REF, rel_ref);
      texture_ref := map(n -> plots:-inequal(rel_ref union rel_motifs[n], x=0..2, y=-1..1, color=motifs_couleur[n], 'nolines'), [$1..motifs_nb]):
      texture     := texture, texture_ref:
    end do:

    plots:-display(
      plot([polygone[], polygone[1]], color=red, scaling=constrained),
      texture
    )

     

    MOTIF  := [ seq(0.1*~[cos(Pi/6+Pi/3*i), sin(Pi/6+Pi/3*i)], i=0..5) ]:
    motifs := [ seq(seq(F(MOTIF, i*0.2*cos(Pi/6)+piecewise(j::odd, 0, 0.08), j*0.3*sin(Pi/6)), i=0..12), j=-6..6) ]:


    plots:-display(
      plot([polygone[], polygone[1]], color=red, filled),
      map(u -> plot([u[], u[1]], color=blue, filled, scaling=constrained), motifs)
    ):


    motifs_nb      := numelems(motifs):
    motifs_couleur := [ seq(`if`(n::even, yellow, brown) , n=1..motifs_nb) ]:

    texture    := NULL:
    rel_motifs := map(u -> trianguler:-interieur_forme(u, [x, y]), motifs):
      
    for ref in liste_triangles do
      ref;
      g := trianguler:-sommet_gauche(ref):
      bas := sort(op~(2, ref), output=permutation);
      REF := ref[[g, op(map(u -> if u<>g then u end if, bas))]];
      rel_ref     := trianguler:-interieur_forme(REF, [x, y]): #print(ref, REF, rel_ref);
      texture_ref := map(n -> plots:-inequal(rel_ref union rel_motifs[n], x=0..2, y=-1..1, color=motifs_couleur[n], 'nolines'), [$1..motifs_nb]):
      texture     := texture, texture_ref:
    end do:

    plots:-display(
      plot([polygone[], polygone[1]], color=red, scaling=constrained),
      texture
    )

     

     


     

    Download Triangulation_Hatching_Texturing.mw

    We recently had a question about using some of the plotting commands in Maple to draw things. We were feeling creative and thought why not take it a step further and draw something in 3D.

    Using the geom3d, plottools, and plots packages we decided to make a gingerbread house.

    To make the base of the house we decided to use 2 cubes, as these would give us additional lines and segments for the icing on the house.

    point(p__1,[2,3,2]):
    point(p__2,[3,3,2]):
    cube(c1,p__1,2):
    cube(c2,p__2,2):
    base:=draw([c1,c2],color=tan);

    Using the same cubes but changing the style to be wireframe and point we made some icing lines and decorations for the gingerbread house.

    base_decor1:=draw([c1,c2],style=wireframe,thickness=3,color=red,transparency=0.2):
    base_decor2:=draw([c1,c2],style=wireframe,thickness=10,color=green,linestyle=dot):
    base_decor3:=draw([c1,c2],style=point,thickness=2,color="Silver",symbol=sphere):
    base_decor:=display(base_decor1,base_decor2,base_decor3);

    To create the roof we found the vertices of the cubes and used those to find the top corners of the base.

    v1:=vertices(c1):
    v2:=vertices(c2):
    pc1:=seq(point(pc1||i,v1[i]),i=1..nops(v1)):
    pc2:=seq(point(pc2||i,v2[i]),i=1..nops(v2)):
    topCorners:=[pc1[5],pc1[6],pc2[1],pc2[2]]:
    d1:=draw(topCorners):

    Using these top corners we found the midpoints (where the peak of the roof would be) and added the roof height to the coordinates.

    midpoint(lc1,topCorners[1],topCorners[2]):
    detail(lc1);

    point(cc1,[-(2*sqrt(3))/3 + 2, (2*sqrt(3))/3 + 3+1, 2]):
    d3:=draw(cc1):
    
    midpoint(lc2,topCorners[3],topCorners[4]):
    detail(lc2);

    point(cc2,[(2*sqrt(3))/3 + 3, (2*sqrt(3))/3 + 3+1, 2]):
    d4:=draw(cc2):

    With the midpoints and vertices at the front and rear of the house we made two triangles for the attic of the gingerbread house.

    triangle(tf,[topCorners[1],topCorners[2],cc1]):
    front:=draw(tf,color=brown):
    
    triangle(tb,[topCorners[3],topCorners[4],cc2]):
    back:=draw(tb,color=tan):

    Using these same points again we made more triangles to be the roof.

    triangle(trl,[cc1,cc2,pc1[5]]):
    triangle(trh,[pc2[2],pc1[6],cc1]):
    triangle(tll,[cc1,cc2,pc2[2]]):
    triangle(tlh,[pc2[1],pc1[5],cc2]):
    roof:=draw([trl,trh,tll,tlh],color="Chocolate");

    Our gingerbread house now had four walls, a roof, and icing, but no door. Creating the door was as easy as making a parallelepiped, but what is a door without more icing?

    door:=display(plottools:-parallelepiped([1,0,0],[0,1.2,0],[0,0,0.8],[0.8,1.9,1.6]),color="DarkRed"):
    door_decor1:=display(plottools:-parallelepiped([1,0,0],[0,1.2,0],[0,0,0.8],[0.8,1.9,1.6]),color="Gold",style=line):
    door_decor2:=display(plottools:-parallelepiped([1,0,0],[0,1.2,0],[0,0,0.8],[0.8,1.9,1.6]),color="Silver", style=line,linestyle=dot,thickness=5):
    door_decor:=display(door_decor1,door_decor2):

    Now having a door we could have left it like this, but what better way to decorate a gingerbread house than with candy canes? Naturally, if we were going to have one candy cane we were going to have lots of candy canes. To facilitate this we made a candy cane procedure.

    candy_pole:=proc(c:=[0,0,0], {segR:=0.1}, {segH:=0.1}, {segn:=7}, {tilt_theta:=0}, {theta:=0}, {arch:=true}, {flip:=false})
    local cane1,cane2,cane_s,cane_c,cane0,cane,i,cl,cd,ch, cane_a,tmp,cane_ac,cane_a1,cane00,cane01,cane02,cane_a1s,tmp2,cane_a2s:
    uses plots,geom3d:
    cl:=c[1]:
    cd:=c[2]:
    ch:=c[3]:
    cane1:=plottools:-cylinder([cd, ch, cl], segR, segH,style=surface):
    
    cane2:=display(plottools:-rotate(cane1,Pi/2,[[cd,ch,cl],[cd+1,ch,cl]])):
    cane_s:=[cane2,seq(display(plottools:-translate(cane2,0,segH*i,0)),i=1..segn-1)]:
    cane_c:=seq(ifelse(type(i,odd),red,white),i=1..segn):
    
    cane0:=display(cane_s,color=[cane_c]):
    
    if arch then
    
    cane_a:=plottools:-translate(cane2,0,segH*segn-segH/2,0):
    tmp:=i->plottools:-rotate(cane_a,i*Pi/24, [ [cd,ch+segH*segn-segH/2,cl+segR*2] , [cd+1,ch+segH*segn-segH/2,cl+segR*2] ] ):
    
    cane_ac:=seq(ifelse(type(i,odd),red,white),i=1..24):
    
                    cane_a1s:=seq(plottools:-translate(tmp(i),0,segH*i/12,segR*i/4),i=1..12):
    
    tmp2:=i->plottools:-rotate(cane_a1s[12],i*Pi/24,[[cd,ch+segH*segn-0.05,cl+segR*2],[cd+1,ch+segH*segn-0.05,cl+segR*2]]):
    
    cane_a2s:=seq(plottools:-translate(tmp2(i),0,-segH*i/500,segR*i/4),i=1..12):
    cane_a1:=display(cane_a1s,cane_a2s,color=[cane_ac]):
    cane00:=display(cane0,cane_a1);
    
                    if flip then
    
    cane01:=plottools:-rotate(cane00,tilt_theta,[[cd,ch,cl],[cd+1,ch,cl]]):
    cane02:=plottools:-rotate(cane01,theta,[[cd,ch,cl],[cd,ch+1,cl]]):
    cane:=plottools:-reflect(cane01,[[cd,ch,cl],[cd,ch+1,cl]]):
    
                    else
    
    cane01:=plottools:-rotate(cane00,tilt_theta,[[cd,ch,cl],[cd+1,ch,cl]]):
    cane:=plottools:-rotate(cane01,theta,[[cd,ch,cl],[cd,ch+1,cl]]):
    
                    end if:
    
                    return cane:
    
    else
    
                    cane:=plottools:-rotate(cane0,tilt_theta,[[cd,ch,cl],[cd+1,ch,cl]]):
    
                    return cane:
    
    end if:
    
    end proc:

    With this procedure we decided to add candy canes to the front, back, and sides of the gingerbread house. In addition we added two candy poles.

    Candy Canes in front of the house:

    cane1:=candy_pole([1.2,0,2],segn=9,arch=false):
    cane2:=candy_pole([2.8,0,2],segn=9,arch=false):
    cane3:=candy_pole([2.7,0.8,3.3],segn=9,segR=0.05,tilt_theta=-Pi/7):
    cane4:=candy_pole([1.3,0.8,3.3],segn=9,segR=0.05,tilt_theta=-Pi/7,flip=true):
    front_canes:=display(cane1,cane2,cane3,cane4):

    Candy Canes at the back of the house:

    caneb3:=candy_pole([1.5,4.2,2.5],segn=15,segR=0.05,tilt_theta=-Pi/3,flip=true):
    caneb4:=candy_pole([2.5,4.2,2.5],segn=15,segR=0.05,tilt_theta=-Pi/3):}
    back_canes:=display(caneb3,caneb4):

    Candy Canes at the left of the house:

    canel1:=candy_pole([0.8,1.5,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    canel2:=candy_pole([0.8,2.5,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    canel3:=candy_pole([0.8,4,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    left_canes:=display(canel1,canel2,canel3):

    Candy Canes at the right of the house:

    caner1:=candy_pole([3.2,1.5,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    caner2:=candy_pole([3.2,2.5,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    caner3:=candy_pole([3.2,4,2.5],segn=15,segR=0.05,tilt_theta=-Pi/7,theta=Pi/2):
    right_canes:=display(caner1,caner2,caner3):
    
    canes:=display(front_canes,back_canes,right_canes,left_canes):

    With these canes in place all that was left was to create the ground and display our Gingerbread House.

    ground:=display(plottools:-parallelepiped([5,0,0],[0,0.5,0],[0,0,4],[0,1.35,0]),color="DarkGreen"):
    
    display([door,door_decor,d1,base,base_decor,d3,d4,front,back,roof,ground,canes],orientation=[-100,0,95]);

    You can download the full worksheet creating the gingerbread house below:

    Geometry_Gingerbread.mw

    First 38 39 40 41 42 43 44 Last Page 40 of 308