Something went wrong. Try again.
Graphics calculator made with elm tedius.tngl.sh/zero
elm math graphics
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193module Draw exposing (..)
import List exposing (repeat)import Parse exposing (Point(..), Vector(..))import Svg exposing (..)import Svg.Attributes exposing (class, cx, cy, fill, height, id, markerEnd, markerHeight, markerWidth, orient, r, refX, refY, stroke, strokeWidth, viewBox, width, x1, x2, y1, y2)
type alias ZeroSvg = { size : { width : Float, height : Float } , center : { x : Float, y : Float } , scale : Float }
-- Centro del SVG
centerX : ZeroSvg -> FloatcenterX svg = svg.size.width / 2 + svg.center.x
centerY : ZeroSvg -> FloatcenterY svg = svg.size.height / 2 + svg.center.y
-- Convierte coordenadas del sistema matemático al sistema SVG-- En el sistema matemático: (0,0) está en el centro, Y crece hacia arriba-- En el sistema SVG: (0,0) está en la esquina superior izquierda, Y crece hacia abajo
transformX : ZeroSvg -> Float -> FloattransformX svg x = centerX svg + x * svg.scale
transformY : ZeroSvg -> Float -> FloattransformY svg y = centerY svg - (y * svg.scale)
transformCoordinates : ZeroSvg -> Float -> Float -> ( Float, Float )transformCoordinates svg x y = ( transformX svg x , transformY svg y )
axis : ZeroSvg -> Svg aaxis svg = g [ class "axis" ] [ -- Eje X line [ x1 "0", y1 (String.fromFloat (centerY svg)), x2 (String.fromFloat svg.size.width), y2 (String.fromFloat (centerY svg)), class "x-axis" ] [] , -- Eje Y line [ x1 (String.fromFloat (centerX svg)), y1 "0", x2 (String.fromFloat (centerX svg)), y2 (String.fromFloat svg.size.height), class "y-axis" ] [] ]
grid : ZeroSvg -> Float -> List (Svg a)grid svg gridScale = let toSvgX : Float -> String toSvgX x = String.fromFloat (transformX svg x)
toSvgY : Float -> String toSvgY y = String.fromFloat (transformY svg y) in List.indexedMap (\i -> \_ -> line [ x1 (String.fromFloat 0), y1 (toSvgY (toFloat i * gridScale)), x2 (String.fromFloat svg.size.width), y2 (toSvgY (toFloat i * gridScale)) ] []) (repeat (round (svg.size.height / 2)) 0) ++ List.indexedMap (\i -> \_ -> line [ x1 (String.fromFloat 0), y1 (toSvgY (toFloat i * -gridScale)), x2 (String.fromFloat svg.size.width), y2 (toSvgY (toFloat i * -gridScale)) ] []) (repeat (round (svg.size.height / 2)) 0) ++ List.indexedMap (\i -> \_ -> line [ y1 (String.fromFloat 0), x1 (toSvgX (toFloat i * gridScale)), y2 (String.fromFloat svg.size.height), x2 (toSvgX (toFloat i * gridScale)) ] []) (repeat (round (svg.size.width / 2)) 0) ++ List.indexedMap (\i -> \_ -> line [ y1 (String.fromFloat 0), x1 (toSvgX (toFloat i * -gridScale)), y2 (String.fromFloat svg.size.height), x2 (toSvgX (toFloat i * -gridScale)) ] []) (repeat (round (svg.size.width / 2)) 0)
gridSpacing : Float -> FloatgridSpacing scale = let targetPixelSpacing = 50
worldSpacing = targetPixelSpacing / scale
power = logBase 10 worldSpacing |> round |> toFloat in 10 ^ power
mainGrid : ZeroSvg -> Svg amainGrid svg = let spacing = gridSpacing svg.scale in g [ class "main-grid" ] (grid svg (spacing * 5))
secundGrid : ZeroSvg -> Svg asecundGrid svg = let spacing = gridSpacing svg.scale in if spacing * svg.scale > 10 then g [ class "secund-grid" ] (grid svg spacing)
else g [] []
arrowMarker : Svg aarrowMarker = defs [] [ marker [ id "arrowhead" , markerWidth "10" , markerHeight "7" , refX "9" , refY "3.5" , orient "auto" ] [ polygon [ Svg.Attributes.points "0 0, 10 3.5, 0 7" , fill "blue" , stroke "blue" , strokeWidth "0" ] [] ] ]
pointToSvg : ZeroSvg -> Point -> Svg apointToSvg svg (Point point) = let ( svgX, svgY ) = transformCoordinates svg point.x point.y in circle [ r "4" , cx (String.fromFloat svgX) , cy (String.fromFloat svgY) , stroke "red" , strokeWidth "2" , fill "red" ] []
vectorToSvg : ZeroSvg -> Vector -> Svg avectorToSvg svg (Vector vector) = let ( svgX, svgY ) = transformCoordinates svg vector.x vector.y in line [ x1 (String.fromFloat (centerX svg)) , y1 (String.fromFloat (centerY svg)) , x2 (String.fromFloat svgX) , y2 (String.fromFloat svgY) , stroke "blue" , strokeWidth "2" , markerEnd "url(#arrowhead)" ] []
mainSvg : ZeroSvg -> List Point -> List Vector -> Svg amainSvg zeroSvg points vectors = svg [ id "graph" , width (String.fromFloat zeroSvg.size.width) , height (String.fromFloat zeroSvg.size.height) , viewBox ("0 0 " ++ String.fromFloat zeroSvg.size.width ++ " " ++ String.fromFloat zeroSvg.size.height) ] [ arrowMarker , secundGrid zeroSvg , mainGrid zeroSvg , axis zeroSvg , g [ class "points" ] (List.map (pointToSvg zeroSvg) points) , g [ class "vectors" ] (List.map (vectorToSvg zeroSvg) vectors) ]