package main // $GOSRC/book.go // (c) Christian Maurer v. 201026 - license see µU.go import ( "µU/scr" . "book/internal" ) func main() { s := scr.NewWH (0, 0, 1594, 1150); defer s.Fin() mode := scr.Walk var ex, ey, ez, fx, fy, fz, nx, ny, nz float64 ex, ey, ez = 22, -40, 2 fx, fz = 22, 2 // Mitte der Weichenverbindung nz = 1 s.Go (mode, Draw, ex, ey, ez, fx, fy, fz, nx, ny, nz) } package book // $GOSRC/book/internal/def.go // (c) Christian Maurer v. 191019 func Draw() { draw() } package book // $GOSRC/book/internal/book.go // (c) Christian Maurer v. 210104 // >>> Fig. 4.2 on p. 135 of "Nonsequential and Distributed Programming with Go" (Springer Nature 2021) import ( "math" "µU/col" "µU/gl" ) const ( pi_180 = math.Pi / 180 y0 = 0.; y1 = 3.50; dy = 1.435 x0 = 0. xw = 12. x1 = 31.5 xv = 0.8 xz = 4.75 xf = 2.5 xk = 0.8 xp = 0.6 xl = xw - 2 * xp xd = xv + xz + xf + xk + 2 * xp z0 = -0.15 z1 = z0 - 0.16 zz = 1.75 zf = 1.2 zk = 3. // 2.50 zp = 1.3 dz = 4.28 Breite = 3. db = (Breite - dy) / 2. r = 1.75 / 2. rr = 0.6 rp = 0.3 zs = 5. sb = 0.07 // Schienenbreite b2 = sb / 2. a0 = 22.5 vorne = -50. hinten = 350. seite = 200. ) var b0, b1 float64 func Erde() { gl.Colour (col.New3 ("Erde", 244, 164, 96)) gl.HorRectangle (vorne, -seite, -0.32, hinten, seite, true) } func Gleise (w float64) { x := vorne x2 := 14. x3 := x2 + 17.54 x5 := 4.0 x6 := x3 - x5 x7 := 0.7 gl.Colour (col.DarkGray()) gl.Cuboid (x, y1 + dy - b2, z0, x2, y1 + dy + b2, 0) // Gleis 2 hinten links gl.Cuboid (x, y1 - b2, z0, x2, y1 + b2, 0) // Gleis 2 vorne links gl.Cuboid (x2 + x5, y1 - b2, z0, 22.0 - x7, y1 + b2, 0) // Gleis 2 vorne Zwischenstück gl.Cuboid (x, y0 + dy - b2, z0, 23.6 - x7, y0 + dy + b2, 0) // Gleis 1 hinten Schiene links gl.Cuboid (23.6 + x7, y0 + dy - b2, z0, x6, y0 + dy + b2, 0) // Gleis 1 hinten Zwischenstück gl.Cuboid (x, y0 - b2, z0, x6, y0 + b2, 0) // Gleis 1 vorne links gl.Cuboid (x2 + x5, y1 + dy - b2, z0, 30.14, y1 + dy + b2, 0) // ! Gleis 2 hinten rechts gl.Cuboid (w, y1 + dy - b2, z0, hinten, y1 + dy + b2, 0) // ! Gleis 2 hinten ganz rechts gl.Cuboid (22.0 + x7, y1 - b2, z0, 30.14, y1 + b2, 0) // ! Gleis 2 vorne rechts gl.Cuboid (w, y1 - b2, z0, hinten, y1 + b2, 0) // ! Gleis 2 vorne ganz rechts gl.Cuboid (x3 - 0.20, y0 + dy - b2, z0, hinten, y0 + dy + b2, 0) // Gleis 1 hinten rechts gl.Cuboid (x3 - 0.20, y0 - b2, z0, hinten, y0 + b2, 0) // Gleis 1 vorne rechts // x6 + 2.60 R, da, a := (y1 / 2) / (1 - math.Cos (a0 * pi_180)), 0.5, -90. for { a1, a2 := (-a - 90) * pi_180, da / 2 * pi_180 a3 := a1 + a2 gl.Cuboid1 (x2 + R * math.Sin(a1) - b2 * math.Sin(a3), y1 - R + R * math.Cos(a1) + b2 * math.Cos(a3), z0, sb, 0.20, 0.15, a - da/2) gl.Cuboid1 (x2 + R * math.Sin(a1) - b2 * math.Sin(a3), y1+dy - R + R * math.Cos(a1) + b2 * math.Cos(a3), z0, sb, 0.20, 0.15, a - da/2) a = a - da if a <= -90 - a0 { break } } a = -180 - 90 - a0 for { a1, a2 := (-a - 90) * pi_180, da / 2 * pi_180 a3 := a1 + a2 gl.Cuboid1 (x3 + R * math.Sin(a1) - b2 * math.Sin(a3), y0 + R + R * math.Cos(a1) + b2 * math.Cos(a3), z0, sb, 0.20, 0.15, a - da / 2) gl.Cuboid1 (x3 + R * math.Sin(a1) - b2 * math.Sin(a3), y0+dy + R + R * math.Cos(a1) + b2 * math.Cos(a3), z0, sb, 0.20, 0.15, a - da / 2) a = a + da if a >= -180 - 90 { break } } c := col.New3 ("BlackBrown", 64, 42, 0) gl.Colour (c) for { // Schwellenbreite 2.60 if x > 22.8 - 4.80 && x < 22.8 + 4.80 { gl.Cuboid (x, y0 - 0.58, z1, x + 0.26, y1 + dy + 0.58, z0) // Schwellen im Weichenbereich } else { gl.Cuboid (x, y0 - 0.58, z1, x + 0.26, y0 + dy + 0.58, z0) if x <= 30.14 || x >= w { gl.Cuboid (x, y1 - 0.58, z1, x + 0.26, y1 + dy + 0.58, z0) } } x = x + 0.60 if x >= hinten { break } } } func LokfensterLinks (x, y float64) { gl.Colour (col.Siena()) a := 0.01 z, z1, z2 := 0.7 * dz, 0.35 * dz, 0.9 * dz yl, yr := y - db - a, y + dy + db + a x0 := x + xv + xz gl.VertRectangle (x0 + 1.25, yl, z, x0 + 1.85, yl, z2) gl.VertRectangle (x0 + 1.25, yr, z, x0 + 1.85, yr, z2) gl.VertRectangle (x0 + 2.35, yl, z1, x0 + 2.95, yl, z2) gl.VertRectangle (x0 + 2.35, yr, z1, x0 + 2.95, yr, z2) x0 += xp gl.VertRectangle (x0 - a, yl + 0.2, z, x0 - a, yl + 0.7, z2) gl.VertRectangle (x0 - a, yr - 0.7, z, x0 - a, yr - 0.2, z2) x0 += xf gl.VertRectangle (x0 + a, yl + 0.5, z, x0 + a, yr - 0.5, z2) } func linkeLok (x, y float64, oben, unten col.Colour) { x0, y0 := x, y b0, b1 = y - db, y + dy + db gl.Colour (oben) gl.HorCylinder (x, y + dy / 2 - 0.9, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.9, zp, rp, xp, 0) gl.Colour (col.Yellow()) gl.HorCylinder (x + 1.3, y + dy / 2 - 0.7, zp + 0.7, 0.2, 0.1, 0) gl.HorCylinder (x + 1.3, y + dy / 2 + 0.7, zp + 0.7, 0.2, 0.1, 0) gl.HorCylinder (x + 1.3, y + dy / 2, zp + 1.90, 0.2, 0.1, 0) x += xp gl.Colour (unten) gl.Cuboid (x, b0, 1.5 * rr, x + xv + xz, b1, zz) x += xv gl.Colour (oben) gl.HorCylinder (x, y + dy / 2, zz + r, r, xz, 0) gl.Colour (col.Gray9()) gl.Cylinder (x + 0.65, y + dy / 2, zz + 2 * r, 0.20, 0.65) gl.Cylinder (x + 2.70, y + dy / 2, zz + 2 * r, 0.27, 0.55) h0, dh := 0.7, 0.2 gl.Colour (col.Gray()) for i, x0, h, r0 := float64(0), x + 2.7, 2.8, 2.; i < 8; i++ { gl.Sphere (x0, y + dy / 2, zz + h, r0 / 10) h += h0 + i * dh; x0 += i * 0.5; r0++ } x += xz gl.Colour (unten) gl.Cuboid (x, b0, 1.5 * rr, x + xf, b1, zf) gl.Colour (oben) gl.Cuboid (x, b0, zf, x + xf, b1, zf + 3.20) x += xf gl.Colour (oben) gl.Cuboid (x, b0, 1.5 * rr, x + xk, b1, zk) x += xk gl.Colour (unten) gl.HorCylinder (x, y + dy / 2 - 0.9, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.9, zp, rp, xp, 0) x = x - xf - xz - xv - xk x += 2.4 b0 = b0 + 0.45 gl.Colour (oben) gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) x += 1.6 gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) x += 1.6 gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) LokfensterLinks (x0, y0) } func LokfensterRechts (x, y float64) { gl.Colour (col.Siena()) a := 0.01 z, z1, z2 := 0.7 * dz, 0.35 * dz, 0.9 * dz yl, yr := y - db - a, y + dy + db + a gl.VertRectangle (x + 1.7, yl, z1, x + 2.3, yl, z2) gl.VertRectangle (x + 1.7, yr, z1, x + 2.3, yr, z2) gl.VertRectangle (x + 2.8, yl, z, x + 3.5, yl, z2) gl.VertRectangle (x + 2.8, yr, z, x + 3.5, yr, z2) x0 := x + xp + xv x1 := x0 + xf gl.VertRectangle (x0 - a, yl + 0.5, z, x0 - a, yr - 0.5, z2) gl.VertRectangle (x1 + a, yl + 0.2, z, x1 + a, yl + 0.7, z2) gl.VertRectangle (x1 + a, yr - 0.7, z, x1 + a, yr - 0.2, z2) } func rechteLok (x, y float64, oben, unten col.Colour) { x0, y0 := x, y b0 = y - db b1 = y + dy + db gl.Colour (unten) gl.HorCylinder (x, y + dy / 2 - 0.90, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.90, zp, rp, xp, 0) x = x + xp gl.Colour (oben) gl.Cuboid (x, b0, 1.5 * rr, x + xk, b1, zk) x = x + xv gl.Colour (unten) gl.Cuboid (x, b0, 1.5 * rr, x + xf, b1, zf) gl.Colour (oben) gl.Cuboid (x, b0, zf, x + xf, b1, zf + 3.20) x = x + xf gl.Colour (unten) gl.Cuboid (x, b0, 1.5 * rr, x + xz + xv, b1, zz) gl.Colour (oben) gl.HorCylinder (x, y + dy / 2, zz + r, r, xz, 0) gl.Colour (oben) gl.Cylinder (x + xz - 0.65, y + dy / 2, zz + 2 * r, 0.20, 0.65) gl.Cylinder (x + xz - 2.70, y + dy / 2, zz + 2 * r, 0.27, 0.55) h, h0, dh := 2.8, 0.7, 0.03 gl.Colour (col.Gray()) for i, r0 := float64(0), 1.5; i < 5; i++ { gl.Sphere (x + xz - 2.70, y + dy / 2, zz + h, r0/20) h += h0 + i * dh; r0++ } gl.Colour (oben) gl.Cylinder (x + xz - 3.70, y + dy / 2, zz + 2 * r, 0.27, 0.55) x = x + xz + xk gl.Colour (oben) gl.HorCylinder (x, y + dy / 2 - 0.90, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.90, zp, rp, xp, 0) gl.Colour (col.Yellow()) gl.HorCylinder (x - 0.8, y + dy / 2 - 0.7, zp + 0.7, 0.2, 0.1, 0) gl.HorCylinder (x - 0.8, y + dy / 2 + 0.7, zp + 0.7, 0.2, 0.1, 0) gl.HorCylinder (x - 0.8, y + dy / 2, zp + 1.90, 0.2, 0.1, 0) x = x - xk - xz - xf - xv x = x + xk + xf + xz + xv - 2.4 - 2 * 1.6 b0 = b0 + 0.45 gl.Colour (oben) gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) x = x + 1.6 gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) x = x + 1.6 gl.HorCylinder (x, y, rr, 0.1, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) LokfensterRechts (x0, y0) } func Wagenfenster (x, y float64) { gl.Colour (col.BlackBlue()) a := 0.01 z, z1, z2 := 0.6 * dz, 0.9 * dz, 0.35 * dz f := xw / 10; f2 := f / 2; df := 0.1 dx := x + 0.5 xr := 0.2 xt := x + xp yl, yr := y - db - a, y + dy + db + a gl.VertRectangle (xt + xr, y - db - a, z2, xt + xr + f2, yl, z1) gl.VertRectangle (xt + xr, y + dy + db + a, z2, xt + xr + f2, yr, z1) for i := float64(1); i < 8; i++ { gl.VertRectangle (dx + i * f + df, yl, z, dx + (i + 1) * f, yl, z1) gl.VertRectangle (dx + i * f + df, yr, z, dx + (i + 1) * f, yr, z1) } gl.VertRectangle (xt + xl - xr - f2, yl, z2, xt + xl - xr, yl, z1) gl.VertRectangle (xt + xl - xr - f2, yr, z2, xt + xl - xr, yr, z1) } func Wagen (x, y float64) { x0, y0 := x, y gl.Colour (col.Gray9()) gl.HorCylinder (x, y + dy / 2 - 0.90, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.90, zp, rp, xp, 0) x += xp gl.Colour (col.VeryDarkGreen()) gl.Cuboid (x, y - db, 1.8 * rr, x + xl, y + dy + db, dz) gl.Colour (col.LightGray()) gl.HorRectangle (x, y - db, dz + 0.01, x + xl, y + dy + db, true) x += xl gl.Colour (col.Gray9()) gl.HorCylinder (x, y + dy / 2 - 0.90, zp, rp, xp, 0) gl.HorCylinder (x, y + dy / 2 + 0.90, zp, rp, xp, 0) x = x0 + xw / 6 b0 = y - db + 0.45 gl.HorCylinder (x, y, rr, 0.10, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) x += 4 * xw / 6 gl.HorCylinder (x, y, rr, 0.10, dy, 90) gl.HorCylinder (x, y - sb, rr, rr, 2 * sb, 90) gl.HorCylinder (x, y + dy - sb, rr, rr, 2 * sb, 90) Wagenfenster (x0, y0) } func SignalHalt (x, y float64) { const d = 0.10 gl.Colour (col.Gray()) gl.Cylinder (x, y, z1, d, zs - z1) gl.Colour (col.Red()) gl.Cuboid (x - d, y + d, zs, x + d, y - 2, zs + 6 * d) } func SignalFahrt (x, y float64) { const d = 0.10 gl.Colour (col.Gray()) gl.Cylinder (x, y, z1, d, zs - z1) gl.Colour (col.Green()) gl.Prism (0, 1.41, 1.41, x - d / 2, y - d, zs, x + d / 2, y - d, zs, x + d / 2, y - d, zs + 6 * d, x - d / 2, y - d, zs + 6 * d) } func draw() { gl.Clear() Erde() w := 130. Gleise (w) rechteLok (x0, y0, col.Gray9(), col.DarkRed()) for i := float64(1); i < 3; i++ { Wagen (x0 - i * xw, y0) } linkeLok (x1, y0, col.Gray9(), col.DarkRed()) rechteLok (w + 5, y1, col.DarkRed(), col.Gray9()) for i := float64(0); i < 4; i++ { Wagen (x1 + xd + i * xw, y0) } ys := (y1 - dy) / 2. SignalHalt (x0 + 11, y0 - ys) SignalFahrt (x1 + 3, y1 - ys) gl.InitLight (0, 50, -10, 15, 0.5, 0.5, 0.5, 255, 255, 255) gl.PosLight (0, 50, -10, 15) gl.Lamp (0) }