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 list of line segments stored in the form:

{ {{x11,y11},{x12,y12}} , {{x21,y21},{x22,y22}} , ... , {{xn1,yn1},{xn2,yn2}} }

Now I want to rotate all of them by 90 degrees about their own centers. To do that I wrote a pure function like this

{{{0, -1}, {1, 0}}.(#[[1]] - (#[[1]] + #[[2]])/2) + (#[[1]] + #[[2]])/2,
{{0, -1}, {1, 0}}.(#[[2]] - (#[[1]] + #[[2]])/2) + (#[[1]] + #[[2]])/2} &

As you can see this is pretty lengthy compare to the simplicity of my request. But I do not have enough Mathematica experience to shorten it. So can anyone help?

share|improve this question

4 Answers 4

up vote 10 down vote accepted

Something along the lines of Rotate[Line[pts], angle, Mean[pts]]:

g = Graphics[Line[{{1, 1}, {2, 2}}]];
rot = l : Line[pts_] :> Rotate[l, Pi/2, Mean[pts]];

Show[g, g /. rot]

enter image description here

I believe that Rotate and family are Graphics/Graphics3D directives which are only processed when they are rendered. If you need to access actual rotated values of the points, you can use RotationTransform instead.

share|improve this answer
data = RandomReal[1, {5, 2}]

Whole rotation

Graphics[{Line[data], {Red, Rotate[Line[data], Pi/2]}}]

enter image description here

Single segment rotation

Graphics[{Line[data], {Red, Rotate[Line[#], Pi/2]} & /@ Partition[data, 2, 1]}]

enter image description here

share|improve this answer
    
This does not appear to rotate line segments around their centers, as asked by the O.P. –  whuber Apr 26 '13 at 20:51
1  
@whuber added that too –  Vitaliy Kaurov Apr 26 '13 at 21:27
    
The third argument of Rotate (your Mean[]) isn't needed here b/c the rotation is made around the bounding box center by default, and that's the line center point –  belisarius Apr 26 '13 at 23:50
    
@belisarius I tried that - it did not look right. They were not rotations about segment centers. –  Vitaliy Kaurov Apr 27 '13 at 3:34
1  
@belisarius yep you are right. strange that PlotRange->All did not help - which i checked. Anyway I fixed it. Did not put PlotRange there though, - he can figure it out from the comments. –  Vitaliy Kaurov Apr 27 '13 at 19:16

Had Rotate[]/RotationTransform[] not been available, here's a possible alternative:

BlockRandom[SeedRandom[123, Method -> "MKL"]; (* for reproducibility *)
            segs = Arrow[RandomVariate[NormalDistribution[], {5, 2, 2}]]];

Graphics[{{Blue, segs},
          {Red, segs /. s_?MatrixQ :> With[{m = Mean[s]}, m + Cross[# - m] & /@ s]}}]

spin arrows a bit

share|improve this answer

Your own formula can be refactored in a more concise form:

f1 = With[{c = +##/2}, c + (# - c).{{0, -1}, {1, 0}} & /@ {##}] &;
  • +##/2 is a "trick" that here is equivalent to Mean[{#, #2}]
  • the function needs to be applied with @@@ rather than /@

A shorter function can be written using Cross, similar to what J. M. used:

f2 = {+##, # - #2}/2 &[+##, Cross[# - #2]] &;

Use of either function:

lines = RandomReal[{-5, 5}, {3, 2, 2}];

Graphics[{
  {Thick, Line /@ lines},
  {Red, Thick, Line /@ f2 @@@ lines}
}]

enter image description here

share|improve this answer

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.