Message Boards Message Boards

0
|
6742 Views
|
2 Replies
|
1 Total Likes
View groups...
Share
Share this post:

dynamically draw arrows

Posted 11 years ago
Hello,
I am new to Mathematica. I trying do a interactive application.
I need to move some points with mouse, update them positions and draw them and update the position of another points that depend by them.
I have problem with my function drawSystemReference that should draw some arrows at the update coordinate positions.
I post the full code of my application.
 (* create vertex list *)
 CreatePointList := (
   ph1 = Table[{t, 0}, {t, 0, 1,
      0.1}];                                            (* (0,0) -> (1,
   0) *)
   ph2 = Table[{1, t}, {t, 0, 0.3,
      0.1}];                                       (* (1,0) -> (1,
   0.3) *)
   ph3 = Table[{1 - t, 0.3}, {t, 0, 1,
     0.1}];                                (* (1,0.3) -> (0,0.3) *)
  ph4 = Table[{0, 0.3 - t}, {t, 0, 0.3,
     0.1}];                        (* (0,0.3) -> (0,0) *)
  l = Join[ph1, ph2, ph3, ph4]; l)
listVertex = CreatePointList;
(* create bones list initial position *)
listBonesRest = {{0.1, 0.15}, {0.35, 0.15}, {0.65, 0.15}, {0.9, 0.15} }
(* create bones list *)
listBones = {{0.1, 0.15}, {0.35, 0.15}, {0.65, 0.15}, {0.9, 0.15} }
(* matrici identità world space per i bones *)
matrix1 = {{1, 0}, {0, 1}};
lmatrixBones = {matrix1, matrix1, matrix1, matrix1};

NearPoint[list_, mpos_ ] :=
  Nearest[list -> Range[Length[list]],
   mpos]; (* trova l'indice del punto della lista list piu' vicino a \
mpos *)
(* trova gli indici dei k elementi della lista piu' vicini *)
NearestK[list_, k_, pos_] :=
  Nearest[list -> Range[Length[list]], pos, k];
 
  CreateVertexAttribute[listV_, listB_, k_] := Module[{l = {}},
   Do[
    x = listV[[i]];
    nearP = NearestK[listB, k, x];
    sumDist = 0;
    Table[
     sumDist += Norm[  x - listB[ [     nearP[[j]]      ]]  ], {j, 1,
      Length[nearP]}];
    l = Append[l,
      Table[{nearP[[j]],
        Norm[  x - listB[ [   nearP[[j]]  ]]  ]/sumDist}, {j, 1,
        Length[nearP]} ]],
    {i, 1, Length[listV]}
    ]; l];

vGraph = CreateVertexAttribute[listVertex, listBones, 2];



Attributes[calculateNewVertexPositions] = {HoldAll};
calculateNewVertexPositions[listV_, listB_, listBRest_, graph_] :=
  Module[{l = {}},
   Do[
    x = listV[[i]];
    vpos = {0, 0};
    Table[wi := graph[[i, j, 2]] ; ibone := graph[[i, j, 1]];
     vpos += wi*x - listBRest[[ibone]] + listB[[ibone]], {j, 1,
      Length[ graph[[i]] ]}];
    l = Append[l, vpos],
    {i, 1, Length[listV]}
    ]; l];
   
    Attributes[drawSystemReference] = {HoldAll};
drawSystemReference[listDerivedPos_, listMatrix_] := (
   Table[  { 
     Arrow[    { listDerivedPos[[i]],
       listDerivedPos[[i]] + listMatrix[[i]].{0.1, 0} }   ]  ,
      Arrow[    { listDerivedPos[[i]],
       listDerivedPos[[i]] +
        listMatrix[[i]].{0.0, 0.1} }   ]    }, {i, 1,
     Length[listDerivedPos]}]);
    
     (* this is ok, I draw the reference system *)
     Graphics[drawSystemReference[listBones, lmatrixBones]]
    
     (* it's a wrong result... *)
Graphics[drawSystemReference[Dynamic[listBones],
  Dynamic[lmatrixBones]]]
 
  Attributes[updatePointList] = {HoldFirst};
updatePointList[list_, mpos_] := (index = NearPoint[list, mpos][[1]];
  list[[index]] =
   mpos) (* aggiorna l'elemento della lista piu' vicino a mpos con \
mpos *)

(* my main program *)
drawNode[pt_] := ({PointSize[Large], Point[pt]});

DynamicModule[{ lv = listVertex, lvr = listVertex, lb = listBones,
  lbr = listBonesRest, vg = vGraph, lmb = lmatrixBones},
Graphics[{EventHandler[{drawSystemReference[Dynamic[lb],
      Dynamic[lmb]], drawNode[Dynamic[lb]], PointSize[Large], Red,
     Point[Dynamic[lv]],
     Line[Dynamic[lv]]}, ImageSize -> Large,
    "MouseClicked" :> (updatePointList[lb, MousePosition["Graphics"]]),
    "MouseDragged" :> (updatePointList[lb, MousePosition["Graphics"]];
      lv = calculateNewVertexPositions[lvr, lb, lbr, vg])]}]]
I have problem with the function drawSystemReference. if I run this command in Mathematica
Graphics[drawSystemReference[listBones, lmatrixBones]]
 I get the expected result, while if I run this command
Graphics[drawSystemReference[Dynamic[listBones], Dynamic[lmatrixBones]]]
I did not understand why I get a different result. I would like call drawSystemReference every time the listBones and lmatrixBones are changed. How can do it?

Thanks in advance. 
Daniel.
POSTED BY: daniel
2 Replies
Posted 11 years ago
Thanks you very much William, now work!!!!! I am going to read the reference you suggest.
POSTED BY: daniel
Posted 11 years ago
Try this:
Graphics[Dynamic[drawSystemReference[listBones, lmatrixBones]]]

Basically, you want to make sure that you wrap Dynamic around the right parts of your expression. In your example above, you were giving your function Dynamic objects when it expected the List data, and what you want is to make the drawSystemReference expression a Dynamic object that will update when any of its dependent symbols (i.e. listBones and lmatrixBones) are updated.

Here's a good explanation of how to place Dynamic expressions:

http://reference.wolfram.com/mathematica/tutorial/IntroductionToDynamic.html#1063215934

This is part of a set of four must-read tutorials if you plan on using any Dynamic functionality or building any kind of interface in Mathematica. Below I've linked the main Guide page for Dynamic as well as these four Tutorial pages.

http://reference.wolfram.com/mathematica/guide/DynamicInteractivityLanguage.html

http://reference.wolfram.com/mathematica/tutorial/IntroductionToDynamic.html
http://reference.wolfram.com/mathematica/tutorial/AdvancedDynamicFunctionality.html

http://reference.wolfram.com/mathematica/tutorial/IntroductionToManipulate.html
http://reference.wolfram.com/mathematica/tutorial/AdvancedManipulateFunctionality.html
POSTED BY: William Rummler
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract