Entry 3211
why can't I just leave this field empty?
Submitted by bz
on Feb. 15, 2010 at 10:27 a.m.
Language: Erlang. Code size: 2.9 KB.
-module(snowflake). -author(baltazar). -compile(export_all). -define(RELATIVE_PATH(Step), [{Step, 0}, {0, -Step}, {Step, 0}, {0, Step}, {0, Step}, {Step, 0}, {0, -Step}, {Step, 0}]). -define(ABSOLUTE_ANGLES, [-90, 0, 90, 90, 0, -90, 0, 0]). -define(WINDOW_WIDTH, 900). -define(WINDOW_HEIGHT, 900). init() -> S = gs:start(), Win = gs:create(window, S, [{width, ?WINDOW_WIDTH}, {height, ?WINDOW_HEIGHT}, {map, true}]), Canvas = gs:canvas(Win, [{x, 0}, {y, 0}, {width, ?WINDOW_WIDTH}, {height, ?WINDOW_HEIGHT}]), draw_snowflake(Canvas, {200, 200}, 500, 1), loop(), halt(0). degree_to_radian(Degree) -> (Degree * math:pi()) / 180. draw_snowflake(Canvas, {X, Y}, Size, Level) -> gs:rectangle(Canvas, [{fg, red}, {coords, [{X, Y}, {X + Size, Y + Size}]}]), draw_init(Canvas, {X, Y}, Size, 0, Level), draw_init(Canvas, {X + Size, Y}, Size, 90, Level), draw_init(Canvas, {X + Size, Y + Size}, Size, 180, Level), draw_init(Canvas, {X, Y + Size}, Size, 270, Level). draw_init(Canvas, {X, Y}, Size, Angle, 0) -> % draw resulting curve draw_gen(Canvas, {X, Y}, Size, Angle); draw_init(Canvas, {X, Y}, Size, Angle, Level) -> Step = Size / 4, % prepare absolute coords for each corner Coords = make_absolute_coords({X, Y}, rotate_coords(?RELATIVE_PATH(Step), Angle, {0, 0})), % mix absolute coord for each corner and corresponding angle CoordsAngles = lists:zip(Coords, [0 | ?ABSOLUTE_ANGLES]), % draw init figure at each corner according to angle Apply = fun({{Xi, Yi}, CornerAngle}) -> draw_init(Canvas, {Xi, Yi}, Step, Angle + CornerAngle, Level - 1) end, % remove last coord and apply draw_init to the resulting list lists:foreach(Apply, lists:reverse(tl(lists:reverse(CoordsAngles)))). make_absolute_coords({X, Y}, RelCoords) -> make_absolute_coords({X, Y}, RelCoords, [{X, Y}]). make_absolute_coords({_X, _Y}, [], Coords) -> lists:reverse(Coords); make_absolute_coords({X, Y}, [{RelX, RelY} | Other], Coords) -> NewX = X + RelX, NewY = Y + RelY, make_absolute_coords({NewX, NewY}, Other, [{NewX, NewY} | Coords]). %% rotates the point around X0, Y0 rotate_point({X, Y}, Angle, {X0, Y0}) -> X1 = X0 + (X - X0) * math:cos(Angle) - (Y - Y0) * math:sin(Angle), Y1 = Y0 + (X - X0) * math:sin(Angle) + (Y - Y0) * math:cos(Angle), {X1, Y1}. rotate_coords([], _DegreeAngle, {_X0, _Y0}) -> []; rotate_coords(Coords, DegreeAngle, {X0, Y0}) -> RadAngle = degree_to_radian(DegreeAngle), Rotate = fun({X, Y}) -> rotate_point({X, Y}, RadAngle, {X0, Y0}) end, lists:map(Rotate, Coords). draw_gen(Canvas, {X, Y}, Size, Angle) -> Step = Size / 4, Coords = make_absolute_coords({X, Y}, rotate_coords(?RELATIVE_PATH(Step), Angle, {0, 0})), gs:line(Canvas, [{coords, Coords}]). loop() -> receive _Other -> loop() end.
This snippet took 0.03 seconds to highlight.
Back to the Entry List or Home.