7
$\begingroup$

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?

$\endgroup$
11
$\begingroup$

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.

$\endgroup$
5
$\begingroup$
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

$\endgroup$
  • $\begingroup$ This does not appear to rotate line segments around their centers, as asked by the O.P. $\endgroup$ – whuber Apr 26 '13 at 20:51
  • 1
    $\begingroup$ @whuber added that too $\endgroup$ – Vitaliy Kaurov Apr 26 '13 at 21:27
  • $\begingroup$ 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 $\endgroup$ – Dr. belisarius Apr 26 '13 at 23:50
  • $\begingroup$ @belisarius I tried that - it did not look right. They were not rotations about segment centers. $\endgroup$ – Vitaliy Kaurov Apr 27 '13 at 3:34
  • 1
    $\begingroup$ @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. $\endgroup$ – Vitaliy Kaurov Apr 27 '13 at 19:16
2
$\begingroup$

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

$\endgroup$
2
$\begingroup$

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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