Spirograph (Hypozykloide) (Schleifen)
Auf einer kleinen Kreisscheibe mit Radius r wird ein beliebiger Punkt p (im Abstand a < r vom Rand) gewählt. Aus einer Ebene wird eine zweite größere Kreisscheibe mit Radius R (R > r) ausgeschnitten.
Nun wird die kleine Kreisscheibe innerhalb des großen Kreises abgerollt und der Ort des Punktes p dabei beobachtet. Das entstehende Bild heißt Hypozykloide.
Die Bewegung des Punktes p kann mit dem Zeichengerät "Spirograph" einfach nachvollzogen werden: Siehe Wikipedia Spirograp(Spielzeug), Wolframalpha: Spirograph und Wikipedia: Zykloide.
Sind r und R nun ganzzahlige Werte (Anzahl Zähne beim Spirographen), so läßt sich die Anzahl der entstehenden Zacken oder Bogen einfach berechnen: Entwickeln Sie nun eine Formel (oder suchen Sie diese auf den obigen Webseiten), welche die Anzahl der entstehenden Zacken bei gegebenen Radien r und R in der Zeichnung berechnet.
Schreiben danach Sie ein Programm, bei dem r und R als ganzzahlige Werte entegegen genommen werden, und als Ausgabe steht die Anzahl der Zacken oder Bogen.
0 Kommentare
7 Lösung(en)
package ch.programmieraufgaben.iteration.spirograph;
/**
* @author philipp gressly freimann @ santis-training.ch
* @version 1.0 vom 17. März 2014
*/
import java.util.Scanner;
public class Spirograph {
public static void main(String[] args) {
new Spirograph().top();
}
void top() {
// Radien einlesen:
int R = leseInt("Innenradius R (groß )");
int r = leseInt("Außenradius r (klein)");
// ggT rechnen:
int g1 = R, ggt = r, g2 = g1 % ggt;
while(g2 > 0) {
g1 = ggt;
ggt = g2;
g2 = g1 % ggt;
}
// Ausgabe:
System.out.println("Es gibt " + (R / ggt) + " «Zacken».");
}
// Hilfsfunktion zum Einlesen (in den meisten Sprachen standardmäßig vorhanden).
Scanner sc = new Scanner(System.in);
int leseInt(String frage) {
System.out.println("Bitte " + frage + " eingeben: ");
return sc.nextInt();
}
} // end of class Spirograph
Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)
<!DOCTYPE html>
<html>
<head>
<title>Hypozykloide</title>
</head>
<body>
<form action="Hypozykloide.php" method="POST">
Aussenradius: <input type="text" name="ar"> <br>
Innenradius: <input type="text" name="ir"> <br>
<input type="Submit" value="Absenden">
</form>
<?php
function ggt($zahl1, $zahl2)
{
if($zahl1 == $zahl2)return $zahl1;
if($zahl1 < $zahl2)
$i = $zahl1;
else
$i = $zahl2;
while($i >= 1)
{
if($zahl1 % $i == 0 && $zahl2 % $i == 0)return $i;
$i--;
}
}
$R = $_POST["ar"];
$r = $_POST["ir"];
if($R != "" && $r != "")
echo "Hypozykloid besitzt ".(floor($R / ggt($R, $r)))." Zacken.<br>";
?>
</body>
</html>
Lösung von: Christian :) (Hochschule Merseburg)
# light
open System
let rec ggt a b =
match b with
|0 -> a
|_ -> ggt b (a % b)
let input t =
printfn "%s eingeben: " t
System.Console.ReadLine
let conv (input : string) : int =
try
System.Int32.Parse(input)
with
:? System.FormatException ->
printfn "'%s' ist kein Zahl!" input;
0
let a = input "R" |> conv
let b = input "r" |> conv
printfn "Es gibt %d Zacken" (a / ggt a b)
Lösung von: Vural Acar ()
import turtle
def zumStartGehen():
turtle.up()
turtle.left(180)
turtle.forward(100)
turtle.left(90)
turtle.forward(200)
turtle.left(90)
turtle.down()
def zeichne(aussen, innen):
turtle.reset()
zumStartGehen()
winkel = 360. / (aussen / innen)
winkelSumme = 0
while abs((winkelSumme % 360) - 360) > 0.2 :
turtle.forward(200)
turtle.left(winkel)
winkelSumme += winkel
if int(winkelSumme) % 360 == 0:
break
aussen = float(eval(input('Anzahl der äußeren Zähne eingeben: ')))
innen = float(eval(input('Anzahl der inneren Zähne eingeben: ')))
zeichne(aussen, innen)
Lösung von: Martin Schimmels (Wilhelm-Schickard-Schule Tübingen)
function getLoops(inner, outer) {
function gcd(a, b) {
if (!b) return a;
return gcd(b, a % b);
}
return Math.floor(inner / gcd(inner, outer));
}
// eingabemaske
document.write(
'<input type="number" id="outer" onchange="compute()" value="60">' +
'Anzahl Zähne außen (r)<br>' +
'<input type="number" id="inner" onchange="compute()" value="96">' +
'Anzahl Zähne innen (R)' +
'<h2 id="title"></h2>' +
'<canvas id="spiro" width="500" height="500"></canvas>'
);
function compute() {
var inner = document.getElementById("inner").value,
outer = document.getElementById("outer").value,
spiro = document.getElementById("spiro"),
ctx = spiro.getContext("2d"),
loops = getLoops(outer, inner);
document.getElementById("title").innerText = loops + " Bögen:";
/* visualisierung im canvas */
// löschen und zum startpunkt
ctx.clearRect(0, 0, spiro.width, spiro.height);
ctx.moveTo(spiro.width / 2 + inner + outer, spiro.height / 2);
ctx.beginPath();
// segmente von 0 bis 2?
for (var t = 0; t <= 2 * Math.PI; t +=0.01) {
var x = spiro.width / 2 + inner * Math.cos(t) + outer * Math.cos(t * loops);
var y = spiro.height / 2 + inner * Math.sin(t) + outer * Math.sin(t * loops);
ctx.lineTo(y, x);
}
// strich ziehen
ctx.stroke();
} // lissalanda@gmx.at
Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)
// C++ 20 | VS-2022
#include <iostream>
#include <functional>
#include <vector>
int main() {
const std::vector<std::tuple<size_t, size_t>>v{ {60, 96}, {56, 96}, {30, 105}, {5, 15}, {3, 7} };
std::function <size_t(size_t, size_t)> ggt{ [&](auto a, auto b) { return (b == 0) ? a : ggt(b, a % b); } };
for (const auto& [r, R] : v)
std::cout << "r= " << r << ", R= " << r << " -> " << R / ggt(R, r) << "\n";
}
Lösung von: Jens Kelm (@JKooP)
// NET 6.x | C# 10.x | VS-2022
var lst = new List<(uint r, uint R)> { (60, 96), (56, 96), (30, 105), (5, 15), (3, 7) };
uint ggt(uint a, uint b) => (b == 0) ? a : ggt(b, a % b);
lst.ForEach(x => Console.WriteLine($"r={x.r}, R={x.R} -> {x.R / ggt(x.R, x.r)}"));
Lösung von: Jens Kelm (@JKooP)
Verifikation/Checksumme:
r = 60, R = 96 --> Zacken = 8
r = 56, R = 96 --> Zacken = 12
r = 30, R = 105 --> Zacken = 7
r = 5, R = 15 --> Zacken = 3
r = 3, R = 7 --> Zacken = 7
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung:
Meta
Zeit: | 0.5 |
Schwierigkeit: | Mittel |
Webcode: | cvyy-k8xe |
Autor: | Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch) |