# How to draw rectangle in mathematica with arrow

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.

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.

Thanks, Nitin

-

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];
g = Graph[{1 -> 2, 2 -> 3, 3 -> 4, 4 -> 1},
VertexCoordinates -> #,
EdgeShapeFunction -> ef1] & /@ coord;
Show[Plot[f[x], {x, 0, 5}, Frame -> True], g]


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).

-
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]}]]


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.

-
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}};


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

-
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