Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I have a basic question but i cant seem to find an answer for it.

How do i draw a rectangle in mathematica with either clockwise or counterclockwise arrow heads. enter image description here

In this picture i know two points i.e. (xmin,ymin) and (xmax,ymax). I want to stepwise quench my system and show it in this picture and hence many rectangles between min and max.

Rectangle command doesnt seem to provide an answer. And i want to do it with very many points, hence couple of answers that are available in forum are not so useful.

(-1+X+1/(1/3+(-3.+3 X)/(3 (1.*10^-18+4.5*10^-12 (2+X)+2.59808*10^-9 Sqrt[4.*10^-12-4 (-1+X)^3+1.*10^-6 (8-(-20+X) X)])^(1/3))+333333. (1.*10^-18+4.5*10^-12 (2+X)+2.59808*10^-9 Sqrt[4.*10^-12-4 (-1+X)^3+1.*10^-6 (8-(-20+X) X)])^(1/3)))/X

This is the plotted function f.

Now i want to select two X values say X=1.1 and X=3 and divide interval into N parts X = {X1, X2, X3, X4, X5} and directed rectangle between each of the two consecutive values.

Because i cant do it in mathematica i drew it in paint and it looks something like this with clockwise arrows for each rectangle.

enter image description here

Thanks, Nitin

share|improve this question

3 Answers 3

up vote 5 down vote accepted

Because using Graph is fun:

f[x_] := Sqrt@x
x = {1.1, 1.6, 2.2, 2.4, 3}; (* put any thing you want here *)
coord = {First@#, {First@#[[2]], Last@#[[1]]}, Last@#, {First@#[[1]], Last@#[[2]]}} & /@
         Partition[{#, f@#} & /@ x, 2, 1];
ef1[el_, ___] := {Arrowheads@0.03, Arrow[el]}
g = Graph[{1 -> 2, 2 -> 3, 3 -> 4, 4 -> 1}, 
          VertexCoordinates -> #, 
          EdgeShapeFunction -> ef1] & /@ coord;
Show[Plot[f[x], {x, 0, 5}, Frame -> True], g]

enter image description here

Then you can play with EdgeStyle or VertexStyle in g to have fancy colors (or see Graph's Options for more details) and with Arrowheads to have bigger/smaller heads.


Additions regarding coord (as requested in the comments):

If you consider that {{x1,y1},{x2,y2},{x3,y3}} are the coordinates of the three first points crossing f@x you need to group them in order to create two rectangles:

rectgroups = Partition[{{x1,y1},{x2,y2},{x3,y3}}, 2, 1]

{{{x1, y1}, {x2, y2}}, {{x2, y2}, {x3, y3}}}

with {{x1, y1}, {x2, y2}} and {{x2, y2}, {x3, y3}} forming two rectangles by their opposed coordinates.

The problem here is that in order to draw a rectangle while using VertexCoordinates (it's in fact not the case with Rectangle) you need the four points defining your rectangle. Thus:

makerect = {First@#, {First@#[[2]], Last@#[[1]]}, Last@#, {First@#[[1]], Last@#[[2]]}}&;
makerect /@ rectgroups

{{{x1, y1}, {x2, y1}, {x2, y2}, {x1, y2}}, {{x2, y2}, {x3, y2}, {x3, y3}, {x2, y3}}}

gives you the two other coordinates needed to define the rectangles ({x2,y1} and {x1,y2} in the first case).

share|improve this answer
    
Awesome, thanks a lot. If possible can you please explain how you defined coord, i mean the logic and meaning of the way u defined it. –  nitin Mar 10 at 21:44

Arrow works for this, because the option Arrowheads can be specified to create arrowheads in the way that you want. rm -rf helped write the code (see comment), and it goes like this:

arrowRectangle[s_, {{xmin_, ymin_}, {xmax_, ymax_}}] := With[
  {a = Abs[xmax - xmin], b = Abs[ymax - ymin]}, {
   Arrowheads[Thread[{s, 0.5 {a/2, a + b/2, 3 a/2 + b, 2 a + 3 b/2}/(a + b)}]], 
   Arrow@{{xmin, ymin}, {xmax, ymin}, {xmax, ymax}, {xmin, ymax}, {xmin, ymin}}
   }]
f[x_] := x^2
pts[lower_, upper_, n_] := Partition[{#, f[#]} & /@ Range[lower, upper, (upper - lower)/n], 2, 1]
Show[Plot[f[x], {x, 0, 5}], Graphics[{arrowRectangle[0.04, #] & /@ pts[1, 5, 3]}]]

arrowheads

0.04 is the arrowhead size and might need to be adapted depending on the plot. The formula inside Arrowheads determines each midpoint. This is because the second argument of Arrowheads, the position, goes from 0 to 1 during the length of the entire line. The denominator is the length of the entire line, and each element in the list the distance from the beginning of the line to each midpoint.

share|improve this answer
    
thanks but this approach will be really tedious if i have many points. –  nitin Mar 10 at 15:25
    
@nitin I don't see why. Just Arrow[coords[Sequence@@#]]&/@points should work. If you elaborate your question with sample points I might be able to help. –  Pickett Mar 10 at 15:29
    
@Pickett I have edited question. –  nitin Mar 10 at 15:41
    
@Pickett The positioning of the arrowhead is off because you need to pick the midpoints of each side. Perhaps this would be better: arrowRectangle[s_, {{xmin_, ymin_}, {xmax_, ymax_}}] := With[{a = Abs[xmax - xmin], b = Abs[ymax - ymin]}, {Arrowheads[Thread[{s, 0.5 {a/2, a + b/2, 3 a/2 + b, 2 a + 3 b/2}/(a + b)}]], Arrow@{{xmin, ymin}, {xmax, ymin}, {xmax, ymax}, {xmin, ymax}, {xmin, ymin}}}] While this works well in isolation, combining with the plot makes it sensitive to arrow head sizes. –  rm -rf Mar 10 at 16:46
    
@rm-rf Yeah, that's really good. Thanks. –  Pickett Mar 10 at 21:30

The following function allows you to place one arrow anywhere along a line within a set of points:

arrowedline[pts_, where_: 0.75] := {
  Line@pts, PointSize@0.02,
  Arrow /@ 
   Most@Flatten[({##, ## + where (RotateLeft[##] - ##)} &@pts), {2}]
  }

Example:

p = {{0, 0}, {1, 0}, {1, 1}, {0, 1}, {0, 0}};

Mathematica graphics

You can change the direction of the arrows by changing the order of the points. Additional work is needed to streamline customizing the arrowheads.

share|improve this answer
    
Sorry, didn't read all of what the OP wants. Out of time at the moment but will update when I get a chance (or delete when someone posts a better answer....) –  bobthechemist Mar 10 at 16:08

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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