DMUG-Archiv 2011

Frühere   Chronologischer Index   Spätere
Vorherige   Thematischer Index   Nächste

Re: Aufgabe::multizentrische Linie

Moin,

nimmt man sich ein paar Pinnwandnadeln, Stift, Faden, ... und eine
geeignete Unterlage, zb ein dickes Mousepad (bevorzugterweise das der
Angetrauten und nicht sein eigenes), dann kann man das ganze manuell
studieren.

Wenn ich das hier richtig sehe, dann ist diese "verallgemeinerte
Ellipsenkonstruktion" gar nicht so verallgemeinert wie es sich das
vielleicht wuenscht: Waehrend man um einen Pin nur einen Kreis hinkriegt
und der Faden logischer weise nur an einem Pin anliegt; und man bei 2
Pins eine Ellipse bekommt und der Faden immer durch die 2 Pins gefuehrt
wird, bleibt diese 2-Pin-Fuehrung bei mehr als 2 Pins erhalten. 

Lokal, auf kleinen Abschnitten wird der Faden durch 2 Pins gefuehrt,
genauso als waehren es nur 2 Pins. Allerdings sind es nicht immer die
gleichen 2 Pins, waehrend man den Stift bewegt.

Weiterhin faellt einem auf, dass die meisten Punkte egal sind. Nur die
Punkte, die die konvexe Huelle beschreiben sind ausschlaggebend. Alle
anderen kann man getrost ignorieren.

Haben wir also eine Startsituation, in der der Faden um alle Pins liegt
und der Stift den Faden straff spannt, ergibt sich daraus ein moeglicher
Startpunkt der auf der veralg. Ellipse liegt. Solange nun die aktuelle
Pin-Stift-Pin Kombination nicht wechselt wahrend man den Stift fuehrt,
wird die Linie durch eine ganz normale Ellipse beschrieben und kann
entsprechend auch mathematisch sehr einfach konstruiert werden. 

Sobald man weiter zeichnet und der Faden sich von einem Pin loest und
nun an einem anderen anliegt, ergibt sich eine neue 2 Pin-Kombi und
dementsprechend ein neuer Ellipsenabschnitt.

Man kann also Udo's Bild aus stueckweise definierten Ellipsen
konstruieren, deren Brennpunkte immer jeweils 2 Punkte der konvexen
Huelle sind.

Fuer unterschiedliche Fadenlaengen ergeben sich unterschiedliche
Ellipsen mit unterschiedlichen Kombinationen von Brennpunkten. Das kann
man sich durch eine Zeichnung schnell klar machen. Der Wechsel von einer
Ellipse zur naechsten finded immer auf einer der gedachten
Verlaengerungen der Kanten der konv. Huelle statt.

Ok, ich muss in der Mail schon scrollen, deshalb mal zum Punkt. Will man
mit ContourPlot Udo's Zeichnung dublizieren, dann braucht man eine
Funktion f[x,y,hull], die fuer einen Punkt {x,y}:

- testet, ob er auch ausserhalb der konvexen Huelle liegt
- testet welche beiden Punkten aus der konv. Huelle den momentanen
Ellipsenabschnitt definieren
- die Laenge von {x,y} zu den beiden Punkten plus die Laenge des Teils
der konv. Huelle, wo der Faden anliegt berechnet.

Das ergibt mit Udos Bild


(************************ Start ****************************)
<< ComputationalGeometry`

path = "multizentrischerKreis.jpg";

img = ImagePad[
   Binarize[
    ColorNegate[
     ColorConvert[Import[path], "Grayscale"]], 
    0.2], -30];
pts = Rescale@
   ComponentMeasurements[
     MorphologicalComponents[img], {"Area", "Centroid"}, 
     5 < #1 < 15 &][[All, 2, 2]];
hull = pts[[ConvexHull[pts, AllPoints -> False]]]

(************************** End *******************************)

Und dann der Aufruf zu ContourPlot, wobei generalizedEllipseN am Ende
der Mail steht

(************************ Start ****************************)
ContourPlot[
 generalizedEllipseN[x, y, hull], {x, -0.5, 1.5}, {y, -0.5, 1.5}, 
 Contours -> 
  With[{circumference = 
     Total[Norm[Subtract[##]] & @@@ Partition[hull, 2, 1, {1, 1}]]}, 
   Table[circumference + dc, {dc, 0, 2, 0.3}]], 
 Epilog -> {Darker[Gray], EdgeForm[Thick], Polygon[hull], White, 
   PointSize[0.015], Point /@ pts}, MaxRecursion -> 3, 
 ColorFunction -> ColorData["AuroraColors"]]

(************************** End *******************************)

Wer bis hier hin dabei geblieben ist, wird die Optionen 
CompilationTarget -> "C", RuntimeAttributes -> {Listable},
RuntimeOptions -> "Speed", Parallelization -> True im Compileaufruf
unten bemerkt haben. Es kann gut sein, dass bei denen, die keinen
C-Compiler installiert haben, der Compile-Aufruf fehlschlaegt. Dann
sollten die Optionen weggelassen werden. Bei allen, bei denen das aber
funktioniert und die mehrere Kerne im Rechner haben, kann man noch
folgendes Manipulate probieren und dabei n=512 beliebig hoch waehlen. 
Bevor man startet sollte man die Augen auf den System-Monitor
(Taskmanager) richten und die Prozessorlast betrachten.
Die meiste Zeit geht natuerlich fuers Manipulate drauf, aber bei n=2048
und einem Semikolon ganz am Schluss habe ich hier 5 Sekunden Volllast,
auf allen 8 CPUs.

(************************ Start ****************************)
With[{n = 512}, 
 With[{img = 
    ImageAdjust@
     Image[Reverse@
       generalizedEllipse[
        Sequence @@ 
         Transpose[
          Table[{x, y}, {x, -0.5, 1.5, 2.0/(n - 1)}, {y, -0.5, 1.5, 
            2.0/(n - 1)}], {3, 2, 1}], hull]]}, 
  Manipulate[
   ColorCombine[{Binarize[img], Binarize[img, t]}], {t, 0.6, 1}]]]
(**************************End*******************************)

Cheers
Patrick


(************************ Start ****************************)
generalizedEllipse = 
  Compile[{{px, _Real}, {py, _Real}, {poly, _Real, 2}},
   Module[{
     areas = Table[
       p[[1, 1]] p[[2, 2]] + p[[2, 1]] py + px p[[1, 2]] - 
        p[[2, 1]] p[[1, 2]] - px p[[2, 2]] - p[[1, 1]] py, {p, 
        Partition[Append[poly, First[poly]], 2, 1]}
       ],
     sign = 0.0,
     i = 0,
     insidePolyQ = 0,
     refAngle = 0.0,
     angles = {0.0},
     n = Length[poly],
     maxAngleDiff = 0.0,
     ida = 1,
     idb = 1,
     
     int1 = {1},
     int2 = {1},
     meanDistance1 = 0.0,
     meanDistance2 = 0.0,
     farHalfPoly = {0.0}
     
     },
    
    (* First check whether we are inside the polygon 
    and can skip the rest *)
    sign = Sign[areas[[1]]];
    For[i = 2, i <= Length[areas], i++,
     If[Sign[areas[[i]]] != sign, insidePolyQ = 1; Break[]];
     ];
    If[insidePolyQ === 0, Return[0.0]];
    
    (* Now we need to find the two points of the convex hull wich 
    are the current anchors for our string in the construction 
    of the current ellipse-segment *)
    
    refAngle = ArcTan[px - poly[[1, 1]], py - poly[[1, 2]] ];
    angles = 
     Table[Mod[ArcTan[p[[1]] - px, p[[2]] - py] - refAngle, 2 Pi], {p,
        poly}];
    Table[With[{mad = Abs[angles[[i]] - angles[[j]]]},
      If[mad > maxAngleDiff,
       {ida, idb} = {j, i};
       maxAngleDiff = mad;
       ]], {j, 1, i}, {i, 1, n}];
    int1 = 
     With[{nn = Mod[idb - ida, n]}, 
      Table[Mod[i, n] + 1, {i, ida - 1, ida + nn - 1}]];
    int2 = 
     With[{nn = Mod[ida - idb, n]}, 
      Table[Mod[i, n] + 1, {i, idb - 1, idb + nn - 1}]];
    
    (* Finally, the length of the band at point {px,
    py} is the length 
    of the two strings in from the anchor points to {px,py} 
    plus the circumference of the polygon-part where the
    string is currently attached *)
    
    meanDistance1 = Mean[Table[Norm[{px, py} - p], {p, poly[[int1]]}]];
    meanDistance2 = Mean[Table[Norm[{px, py} - p], {p, poly[[int2]]}]];
    Norm[{px, py} - poly[[ida]]] + Norm[{px, py} - poly[[idb]] ] + 
     Total[Table[Norm[l[[1]] - l[[2]]],
       {l, Partition[If[meanDistance1 > meanDistance2,
          poly[[int1]],
          poly[[int2]]
          ], 2, 1]}]]
    
    ], CompilationTarget -> "C", RuntimeAttributes -> {Listable}, 
   RuntimeOptions -> "Speed", Parallelization -> True
   ];
generalizedEllipseN[x_?NumericQ, y_?NumericQ, hull_] := 
 generalizedEllipse[x, y, hull]
(************************** End *******************************)



On Sun, 2011-12-25 at 22:38 +0100, Udo und Susanne Krause wrote:
> Liebe Freundinnen und Freunde der Zweiterfeiertagsbeschäftigung,
> 
> Sei P = {p1, p2, p3, ..., pN} eine Punktmenge in der Ebene, p1 = {p11,  
> p12}.
> Sei weiterhin B ein nichtdehnbares geschlossenes Band der Länge l.
> Man beschreibe die Linie in der Ebene, die ein Stift S zeichnet,
> wenn S und P innerhalb des Bandes sind und das Band gespannt ist.
> [Verallgemeinerte Ellipsenkonstruktion]
> 
> Frohe Weihnachten!
> Udo.




Antworten:
Verweise:
Frühere   Chronologischer Index   Spätere
Vorherige   Thematischer Index   Nächste

DMUG DMUG-Archiv, http://www.mathematica.ch/archiv.html