1
$\begingroup$

I am working on an a Ray Tracer for optical lens. Currently my code takes in a list of lens data:

{{'Number','Number', {'Number','Number'},'Number','Number'}, ... } 

And a list of ray data:

{{'Number',{'Number','Number'}}, ... }

My problem is getting the data in this form for arbitrarily many rays and lenses. I can use the controls I learned from the documentation just fine for a predetermined number of rays and lens. However I would like this adjustable.

Ideally, the user would be able to select the number and then be able to input the specifications accordingly. The problem is that I can not figure out how to implement this.

Does anyone have any advice on which controls allow for more arbitrary inputs?

This is what I am working with. As you can see it is painfully long and limited.

Manipulate[Pause[1];Show[beamSysIter[{{a1,{x1,y1}},{a2,{x2,y2}},{a3,{x3,y3}},{a4,{x4,y4}},{a5,{x5,y5}},{a6,{x6,y6}},{a7,{x7,y7}},{a8,{x8,y8}},{a9,{x9,y9}}}, {{RL1,RR1,{Cx1,Cy1}, d1,h1},{RL2,RR2,{Cx2,Cy2}, d2,h2},{RL3,RR3,{Cx3,Cy3}, d3,h3},{RL4,RR4,{Cx4,Cy4}, d4,h4},{RL5,RR4,{Cx5,Cy5}, d5,h5}}, axl, axu, ayl, ayu, maxLens,maxRays]],OpenerView[{"Lens1", Column[{Control[{RL1,3}],Control[{RR1,-3}],Control[{Cx1,.0}],Control[{Cy1,.0}],{Control[{d1,.4}]},Control[{h1,3/2}]}]}] ,OpenerView[{"Lens2", Column[{Control[{RL2,3}],Control[{RR2,-3}],Control[{Cx2,2}],Control[{Cy2,.0}],{Control[{d2,.4}]},Control[{h2,3/2}]}]}] ,OpenerView[{"Lens3", Column[{Control[{RL3,3}],Control[{RR3,-3}],Control[{Cx3,4}],Control[{Cy3,.0}],{Control[{d3,.4}]},Control[{h3,3/2}]}]}] ,OpenerView[{"Lens4", Column[{Control[{RL4,3}],Control[{RR4,-3}],Control[{Cx4,6}],Control[{Cy4,.0}],Control[{C43,.0}],{Control[{d4,.4}]},Control[{h4,3/2}]}]}] ,OpenerView[{"Lens5", Column[{Control[{RL5,3}],Control[{RR5,-3}],Control[{Cx5,.0}],Control[{Cy5,.0}],Control[{d5,.4}],Control[{h5,3/2}]}]}] ,OpenerView[{"Graph", Column[{Control[{maxLens,3}],Control[{maxRays,3}],Control[{axl,-3}],Control[{axu,15}],Control[{ayl,-3}],Control[{ayu,3}]}]}],OpenerView[{"Ray1", Column[{Control[{a1,0}],Control[{x1,-1}],Control[{y1,.1}]}]}],OpenerView[{"Ray2", Column[{{Control[{a2,0}]},{Control[{x2,-1}]},Column[{Control[{y2,-.1}]}]}]}],OpenerView[{"Ray3", Column[{{Control[{a3,0}]},{Control[{x3,-1}]},Column[{Control[{y3,.5}]}]}]}],OpenerView[{"Ray4", Column[{{Control[{a4,0}]},{Control[{x4,-1}]},Column[{Control[{y4,-.5}]}]}]}],OpenerView[{"Ray5", Column[{{Control[{a5,0}]},{Control[{x5,-1}]},Column[{Control[{y5,-.5}]}]}]}],OpenerView[{"Ray6", Column[{{Control[{a6,0}]},{Control[{x6,-1}]},Column[{Control[{y6,-.5}]}]}]}],OpenerView[{"Ray7", Column[{{Control[{a7,0}]},{Control[{x7,-1}]},Column[{Control[{y7,-.5}]}]}]}],OpenerView[{"Ray8", Column[{{Control[{a8,0}]},{Control[{x8,-1}]},Column[{Control[{y8,-.5}]}]}]}],OpenerView[{"Ray9", Column[{{Control[{a9,0}]},{Control[{x9,-1}]},Column[{Control[{y9,-.5}]}]}]}],ControlPlacement -> Left, ContinuousAction -> False]

The updated GUI with Kuba's code.

gui[]:=DynamicModule[{lenses={},rays={}, axl,axu,ayl,ayu}, Panel@Grid[{{Panel@Dynamic[beamSysIter[Column@lenses,Column@rays,Column@{xl,axu,ayl,ayu}]],TabView[{"Lenses"->repeatedController[Dynamic@lenses,lensController{0{0,0}},"Lens"],"Rays">repeatedController[Dynamic@rays,rayController, {0,0,{0,0},0,0}, "Ray"],"Graph spec"->graphSpecController[Dynamic[{axl, axu, ayl, ayu}]]}]}},Alignment->{Left,Top}],Initialization:>{}
]

    repeatedController[Dynamic[var_], controller_:Slider, def_:0,lbl_String:""]:= DynamicModule[{n = Length[var]},
  Column[{
    Button["+", AppendTo[var, def]; n++;],
    Dynamic[
     Delete[var, #]]}]
          }, True] &@i, {i, n}]
      , Alignment -> {Left, Center}],
     TrackedSymbols :> {n}
     ]


    }, BaseStyle -> 
    ButtonBoxOptions -> {ImageSize -> All, FrameMargins -> 5, 
      ContentPadding -> False}]
  ];

  graphSpecController[spec:Dynamic[{__Symbol}]]:= Column[ Slider /@ Thread @ spec ]

  lensController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"a", "x", "y"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2,1},{2,2}}
        }, Alignment->{Center,Center},Spacings->{0,0}]

  ];

  rayController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"RL", "RR", "Cx","Cy","d1","h1"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2},{3,1},{3,2},{4},{5}}
        },Column[Table[OpenerView[{StringTemplate["`` ``"][lbl,#], 
Row[{controller[Dynamic[var[[#]]]],Button["-", n--; var =Delete[var, #]]}]
          }, True] &@i, {i, n}]
      , Alignment -> {Left, Center}],
     TrackedSymbols :> {n}
     ]


    }, BaseStyle -> 
    ButtonBoxOptions -> {ImageSize -> All, FrameMargins -> 5, 
      ContentPadding -> False}]
  ];

  graphSpecController[spec:Dynamic[{__Symbol}]]:= Column[ Slider /@ Thread @ spec ]

  lensController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"a", "x", "y"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2,1},{2,2}}
        }, Alignment->{Center,Center},Spacings->{0,0}]

  ];

  rayController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"RL", "RR", "Cx","Cy","d1","h1"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2},{3,1},{3,2},{4},{5}}
        }, 
$\endgroup$
1

1 Answer 1

0
$\begingroup$

Combining knowledge from linked answers here is an example which should be easy to customize further:

gui[]

enter image description here

gui[]:=DynamicModule[{lenses={},rays={}, axl,axu,ayl,ayu}
, Panel@Grid[{{
    Panel@Dynamic[
    beamSysIter[
     Column@lenses,
Column@rays,
Column@{axl,axu,ayl,ayu}]
  ]
,
TabView[
{"Lenses"->repeatedController[Dynamic@lenses, lensController, {0,{0,0}}, "Lens"],
"Rays"->repeatedController[Dynamic@rays,rayController, {0,0,{0,0},0,0}, "Ray"],
"Graph spec"->graphSpecController[Dynamic[{axl, axu, ayl, ayu}]]}
]
 }},Alignment->{Left,Top}]
 ,
Initialization:>{}
]

repeatedController[Dynamic[var_], controller_:Slider, def_:0, lbl_String:""]:= DynamicModule[{n = Length[var]},
  Column[{
    Button["+", AppendTo[var, def]; n++;],
    Dynamic[
     Column[
      Table[
        OpenerView[{StringTemplate["`` ``"][lbl,#], 
          Row[{controller[Dynamic[var[[#]]]],Button["-", n--; var = Delete[var, #]]}]
          }, True] &@i, {i, n}]
      , Alignment -> {Left, Center}],
     TrackedSymbols :> {n}
     ]


    }, BaseStyle -> 
    ButtonBoxOptions -> {ImageSize -> All, FrameMargins -> 5, 
      ContentPadding -> False}]
  ];

  graphSpecController[spec:Dynamic[{__Symbol}]]:= Column[ Slider /@ Thread @ spec ]

  lensController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"a", "x", "y"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2,1},{2,2}}
        }, Alignment->{Center,Center},Spacings->{0,0}]

  ];

  rayController[Dynamic[var_]]:=DynamicModule[{temp=var}
  , 
      Grid[{
        {"RL", "RR", "Cx","Cy","d1","h1"}, 
        InputField[Dynamic[temp[[##]],{Automatic, (var = temp)&}], ImageSize->50]& @@@ {{1},{2},{3,1},{3,2},{4},{5}}
        }, Alignment->{Center,Center},Spacings->{0,0}]

  ]
$\endgroup$
3
  • $\begingroup$ I began work on this again. However, I am not getting it to work with your gui. For some reason the calculation does not work. Should I add more details? $\endgroup$ Jul 23, 2018 at 0:53
  • $\begingroup$ @CharlesDake if you have a quick question ask here, if not create a separate topic, make sure you narrowed the problem etc. I am not very available this week but you will likely get help from others. $\endgroup$
    – Kuba
    Jul 23, 2018 at 6:18
  • $\begingroup$ I added my revison to your code. It seems to work. I can barely input one ray and a lens before it becomes unbearably slow. It seems to be reevaluating the system too often. This is a rather computationally heavy task too. Would it be possible to add an update button? I am not sure how to. I used update for my manipulate and that was a huge improvement to ease of use. $\endgroup$ Jul 23, 2018 at 19:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.