Hier werden die Unterschiede zwischen zwei Versionen gezeigt.
Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
ss20:neg_utility [2020/08/26 20:43] srather angelegt |
ss20:neg_utility [2020/09/11 14:28] (aktuell) srather [draw] |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | |||
+ | |||
+ | [[nichteuklidische_geometrie|← Back to project page]] | ||
+ | |||
====== Sourcecode ====== | ====== Sourcecode ====== | ||
- | Download sourcecode from Git repository: | + | Download the release version here:\\ |
+ | {{:ss20:neg-world-engine.zip}} | ||
- | [[https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git|https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git]] | + | Or download the newest version from the Git repository:\\ |
+ | [[https://gitlab.tubit.tu-berlin.de/srather/NEG-World-Engine.git]] | ||
- | **[[neg_sourcecode#sourcecode|Sourcecode]]:** | + | ==== Folder Structure: ==== |
- | * **[[neg_sourcecode|Root]]:** [[neg_sourcecode#readme|README]], [[neg_sourcecode#main|main]] | + | |
+ | **[[neg_sourcecode|Root]]:** [[neg_sourcecode#readme|README]], [[neg_sourcecode#main|main]] | ||
* **[[neg_datatypes|Datatypes]]:** [[neg_datatypes#vector|Vector]], [[neg_datatypes#matrix|Matrix]] | * **[[neg_datatypes|Datatypes]]:** [[neg_datatypes#vector|Vector]], [[neg_datatypes#matrix|Matrix]] | ||
Zeile 14: | Zeile 21: | ||
* **[[neg_utility|Utility]]:** [[neg_utility#colors|colors]], [[neg_utility#generate|generate]], [[neg_utility#draw|draw]] | * **[[neg_utility|Utility]]:** [[neg_utility#colors|colors]], [[neg_utility#generate|generate]], [[neg_utility#draw|draw]] | ||
+ | |||
+ | ===== Utility ===== | ||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | ==== colors ==== | ||
+ | <file python colors.py> | ||
+ | WHITE = (0xff, 0xff, 0xff) | ||
+ | LIGHT_GRAY = (0xc0, 0xc0, 0xc0) | ||
+ | GRAY = (0x80, 0x80, 0x80) | ||
+ | DARK_GRAY = (0x40, 0x40, 0x40) | ||
+ | BLACK = (0x00, 0x00, 0x00) | ||
+ | |||
+ | LIGHT_RED = (0xff, 0x40, 0x40) | ||
+ | LIGHT_ORANGE = (0xff, 0xa0, 0x40) | ||
+ | LIGHT_YELLOW = (0xff, 0xff, 0x40) | ||
+ | LIGHT_GREEN = (0x40, 0xff, 0x40) | ||
+ | LIGHT_CYAN = (0x40, 0xff, 0xff) | ||
+ | LIGHT_BLUE = (0x40, 0x40, 0xff) | ||
+ | LIGHT_PURPLE = (0xa0, 0x40, 0xff) | ||
+ | LIGHT_MAGENTA = (0xff, 0x40, 0xff) | ||
+ | |||
+ | BRIGHT_RED = (0xff, 0x00, 0x00) | ||
+ | BRIGHT_ORANGE = (0xff, 0x80, 0x00) | ||
+ | BRIGHT_YELLOW = (0xff, 0xff, 0x00) | ||
+ | BRIGHT_GREEN = (0x00, 0xff, 0x00) | ||
+ | BRIGHT_CYAN = (0x00, 0xff, 0xff) | ||
+ | BRIGHT_BLUE = (0x00, 0x00, 0xff) | ||
+ | BRIGHT_PURPLE = (0x80, 0x00, 0xff) | ||
+ | BRIGHT_MAGENTA = (0xff, 0x00, 0xff) | ||
+ | |||
+ | RED = (0xc0, 0x00, 0x00) | ||
+ | ORANGE = (0xc0, 0x60, 0x00) | ||
+ | YELLOW = (0xc0, 0xc0, 0x00) | ||
+ | GREEN = (0x00, 0xc0, 0x00) | ||
+ | CYAN = (0x00, 0xc0, 0xc0) | ||
+ | BLUE = (0x00, 0x00, 0xc0) | ||
+ | PURPLE = (0x60, 0x00, 0xc0) | ||
+ | MAGENTA = (0xc0, 0x00, 0xc0) | ||
+ | |||
+ | DARK_RED = (0x80, 0x00, 0x00) | ||
+ | DARK_ORANGE = (0x80, 0x40, 0x00) | ||
+ | DARK_YELLOW = (0x80, 0x80, 0x00) | ||
+ | DARK_GREEN = (0x00, 0x80, 0x00) | ||
+ | DARK_CYAN = (0x00, 0x80, 0x80) | ||
+ | DARK_BLUE = (0x00, 0x00, 0x80) | ||
+ | DARK_PURPLE = (0x40, 0x00, 0x80) | ||
+ | DARK_MAGENTA = (0x80, 0x00, 0x80) | ||
+ | |||
+ | </file> | ||
+ | |||
+ | [[#top|↑ Back to top]] | ||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | ==== generate ==== | ||
+ | <file python generate.py> | ||
+ | import math | ||
+ | from polygon import * | ||
+ | from matrix import * | ||
+ | |||
+ | |||
+ | def polygon(edges, center, radius, phase=0, M=((1,0),(0,1)), color=(0,0,0)): | ||
+ | """ | ||
+ | Return a regular polygon. | ||
+ | |||
+ | edges (int) -- number of sides | ||
+ | center (Vector) -- position of center | ||
+ | radius (float) -- radius to vertex | ||
+ | phase (float) -- rotates polygon 'phase' vertics | ||
+ | M (Matrix) -- distortion matrix | ||
+ | """ | ||
+ | |||
+ | poly = Polygon(color=color) | ||
+ | for n in range(edges): | ||
+ | x = radius * math.sin((n + phase) * math.tau / edges) | ||
+ | y = radius * math.cos((n + phase) * math.tau / edges) | ||
+ | poly.append(Vector(*center) + Matrix(*M).prod(Vector(x, y))) | ||
+ | |||
+ | return poly | ||
+ | |||
+ | |||
+ | def star(edges, center, radius, ratio=0.5, phase=0, M=Matrix((1,0),(0,1)), color=(0,0,0)): | ||
+ | """ | ||
+ | Return a regular star polygon. | ||
+ | |||
+ | edges (int) -- number of convex vertices | ||
+ | center (Vector) -- position of center | ||
+ | radius (float) -- radius to vertex | ||
+ | ratio (float) -- radius ratio to inner vertices | ||
+ | phase (float) -- rotates polygon 'phase' vertics | ||
+ | M (Matrix) -- distortion matrix | ||
+ | """ | ||
+ | |||
+ | poly = Polygon(color=color) | ||
+ | for n in range(edges): | ||
+ | x = radius * math.sin((n + phase) * math.tau / edges) | ||
+ | y = radius * math.cos((n + phase) * math.tau / edges) | ||
+ | poly.append(Vector(*center) + M.prod(Vector(x, y))) | ||
+ | |||
+ | x = ratio * radius * math.sin((n + 0.5 + phase) * math.tau / edges) | ||
+ | y = ratio * radius * math.cos((n + 0.5 + phase) * math.tau / edges) | ||
+ | poly.append(Vector(*center) + M.prod(Vector(x, y))) | ||
+ | |||
+ | return poly | ||
+ | |||
+ | |||
+ | def border(polygon): | ||
+ | """ | ||
+ | Turn a polygon into a border. | ||
+ | (split it into its sides) | ||
+ | """ | ||
+ | |||
+ | bor = [] | ||
+ | for i, _ in enumerate(polygon): | ||
+ | bor.append(Polygon(polygon[i-1], polygon[i])) | ||
+ | return bor | ||
+ | |||
+ | |||
+ | def door(start, end, part): | ||
+ | """ | ||
+ | Turn a wall into a door. | ||
+ | (make a hole in the middle with relative size 'part') | ||
+ | """ | ||
+ | |||
+ | return (Polygon(start, start+(1-part)/2*(end-start)), Polygon(end+(1-part)/2*(start-end), end)) | ||
+ | |||
+ | </file> | ||
+ | |||
+ | [[#top|↑ Back to top]] | ||
+ | |||
+ | ---- | ||
+ | |||
+ | |||
+ | ==== draw ==== | ||
+ | <file python draw.py> | ||
+ | import pygame.gfxdraw | ||
+ | import colors | ||
+ | from drawable import * | ||
+ | from portal import * | ||
+ | |||
+ | |||
+ | def player(screen, offset, size): | ||
+ | """ | ||
+ | Draw the player as a white circle in the middle of the screen. | ||
+ | """ | ||
+ | |||
+ | rect = Vector(*screen.get_rect()[2:]) | ||
+ | pygame.gfxdraw.aacircle(screen, *round(rect / 2), size // 2, colors.WHITE) | ||
+ | pygame.gfxdraw.filled_circle(screen, *round(rect / 2), size // 2, colors.WHITE) | ||
+ | |||
+ | |||
+ | def world(screen, wrld, offset, depth): | ||
+ | """ | ||
+ | Draw all objects in 'wrld' in the right order with their shadows | ||
+ | and portal worlds to the maximum recursion-'depth'. | ||
+ | """ | ||
+ | |||
+ | # put all objects in a tuple with their distance to be sortable | ||
+ | dists = [] | ||
+ | for object in wrld: | ||
+ | dists.append((object.dist_to(offset), object)) | ||
+ | |||
+ | # draw the furtheset object first | ||
+ | for object in reversed(sorted(dists)): | ||
+ | if isinstance(object[1], drawable): | ||
+ | # draw order: shadow, portal world, object | ||
+ | object[1].draw_shadow(screen, offset, offset) | ||
+ | if depth > 0 and type(object[1]) is Portal: | ||
+ | world(screen, object[1].portal_world(wrld, offset), offset, depth - 1) | ||
+ | object[1].draw(screen, offset) | ||
+ | else: | ||
+ | raise TypeError(f"draw_world() expected drawable objects, but '{object.__class__.__name__}' found") | ||
+ | |||
+ | |||
+ | def debug(screen, y, info, color): | ||
+ | """ | ||
+ | Draw debug information 'info' to the top right corner. | ||
+ | 'y' is the textline and 'color' the color. | ||
+ | """ | ||
+ | |||
+ | # binary representation of some chars | ||
+ | chars = { | ||
+ | '': [0b10101010, 0b01010101, 0b10101010, 0b01010101, 0b10101010, 0b01010101], | ||
+ | '0': [0b00111110, 0b01000101, 0b01001001, 0b01010001, 0b00111110, 0b00000000], | ||
+ | '1': [0b01000000, 0b01000000, 0b01111111, 0b01000010, 0b01000000, 0b00000000], | ||
+ | '2': [0b01000110, 0b01001001, 0b01001001, 0b01010001, 0b01100010, 0b00000000], | ||
+ | '3': [0b00110110, 0b01001001, 0b01001001, 0b01000001, 0b00100010, 0b00000000], | ||
+ | '4': [0b01111111, 0b00010001, 0b00010010, 0b00010100, 0b00011000, 0b00000000], | ||
+ | '5': [0b00111001, 0b01000101, 0b01000101, 0b01000101, 0b00100111, 0b00000000], | ||
+ | '6': [0b00110000, 0b01001001, 0b01001001, 0b01001010, 0b00111100, 0b00000000], | ||
+ | '7': [0b00000111, 0b00001001, 0b01110001, 0b00000001, 0b00000011, 0b00000000], | ||
+ | '8': [0b00110110, 0b01001001, 0b01001001, 0b01001001, 0b00110110, 0b00000000], | ||
+ | '9': [0b00011110, 0b00101001, 0b01001001, 0b01001001, 0b00000110, 0b00000000], | ||
+ | '.': [0b01100000, 0b00000000], | ||
+ | ',': [0b11100000, 0b00000000], | ||
+ | '+': [0b00001000, 0b00001000, 0b00111110, 0b00001000, 0b00001000, 0b00000000], | ||
+ | '-': [0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00001000, 0b00000000], | ||
+ | ' ': [0b00000000, 0b00000000, 0b00000000], | ||
+ | 'F': [0b00000001, 0b00001001, 0b00001001, 0b00001001, 0b01111111, 0b00000000], | ||
+ | 'P': [0b00000110, 0b00001001, 0b00001001, 0b00001001, 0b01111111, 0b00000000], | ||
+ | 'S': [0b00110001, 0b01001001, 0b01001001, 0b01001001, 0b01000110, 0b00000000], | ||
+ | 'X': [0b01100011, 0b00010100, 0b00001000, 0b00010100, 0b01100011, 0b00000000], | ||
+ | 'Y': [0b00000011, 0b00000100, 0b01111000, 0b00000100, 0b00000011, 0b00000000], | ||
+ | } | ||
+ | |||
+ | pos = screen.get_rect()[2] - 4 | ||
+ | for char in reversed(str(info)): | ||
+ | for line in chars.get(char, chars.get(char.upper(), chars[''])): | ||
+ | for i in range(8): | ||
+ | if line >> i & 0b1: | ||
+ | pygame.gfxdraw.pixel(screen, pos, i+3 + 10*y, color) | ||
+ | pos -= 1 | ||
+ | |||
+ | </file> | ||
+ | |||
+ | [[#top|↑ Back to top]] | ||