diff --git a/functional-core/app-init.sml b/functional-core/app-init.sml index 8038b46..647ef75 100644 --- a/functional-core/app-init.sml +++ b/functional-core/app-init.sml @@ -1,44 +1,51 @@ -structure AppInit = +signature APP_INIT = +sig + val fromWidthAndHeight : int * int -> AppType.app_type +end + +structure AppInit :> APP_INIT = struct open AppType - local - fun init (windowWidth, windowHeight, wStart, wFinish, hStart, hFinish) = + fun helpFromWidthAndHeight + (windowWidth, windowHeight, wStart, wFinish, hStart, hFinish) = + let + val xClickPoints = ClickPoints.generate (wStart, wFinish) + val yClickPoints = ClickPoints.generate (hStart, hFinish) + val graphLines = + GraphLines.generate + (windowWidth, windowHeight, xClickPoints, yClickPoints) + in + { triangles = [] + , triangleStage = NO_TRIANGLE + , windowWidth = windowWidth + , windowHeight = windowHeight + , xClickPoints = xClickPoints + , yClickPoints = yClickPoints + , graphLines = graphLines + } + end + + fun fromWidthAndHeight (windowWidth, windowHeight) = + if windowWidth = windowHeight then + helpFromWidthAndHeight + (windowWidth, windowHeight, 0, windowWidth, 0, windowHeight) + else if windowWidth > windowHeight then let - val xClickPoints = ClickPoints.generate (wStart, wFinish) - val yClickPoints = ClickPoints.generate (hStart, hFinish) - val graphLines = - GraphLines.generate - (windowWidth, windowHeight, xClickPoints, yClickPoints) + val difference = windowWidth - windowHeight + val wStart = difference div 2 + val wFinish = wStart + windowHeight in - { triangles = [] - , triangleStage = NO_TRIANGLE - , windowWidth = windowWidth - , windowHeight = windowHeight - , xClickPoints = xClickPoints - , yClickPoints = yClickPoints - , graphLines = graphLines - } + helpFromWidthAndHeight + (windowWidth, windowHeight, wStart, wFinish, 0, windowHeight) + end + else + let + val difference = windowHeight - windowWidth + val hStart = difference div 2 + val hFinish = hStart + windowWidth + in + helpFromWidthAndHeight + (windowWidth, windowHeight, 0, windowWidth, hStart, hFinish) end - in - fun fromWidthAndHeight (windowWidth, windowHeight) = - if windowWidth = windowHeight then - init (windowWidth, windowHeight, 0, windowWidth, 0, windowHeight) - else if windowWidth > windowHeight then - let - val difference = windowWidth - windowHeight - val wStart = difference div 2 - val wFinish = wStart + windowHeight - in - init (windowWidth, windowHeight, wStart, wFinish, 0, windowHeight) - end - else - let - val difference = windowHeight - windowWidth - val hStart = difference div 2 - val hFinish = hStart + windowWidth - in - init (windowWidth, windowHeight, 0, windowWidth, hStart, hFinish) - end - end end diff --git a/functional-core/app-with.sml b/functional-core/app-with.sml index eea1e84..11706c6 100644 --- a/functional-core/app-with.sml +++ b/functional-core/app-with.sml @@ -1,4 +1,20 @@ -structure AppWith = +signature APP_WITH = +sig + val windowResize: AppType.app_type * int * int -> AppType.app_type + val triangleStage: AppType.app_type * AppType.triangle_stage + -> AppType.app_type + val newTriangle: + AppType.app_type + * Real32.real + * Real32.real + * Real32.real + * Real32.real + * Real32.real + * Real32.real + -> AppType.app_type +end + +structure AppWith :> APP_WITH = struct open AppType @@ -49,61 +65,55 @@ struct } end - local - fun make - ( app: app_type - , windowWidth - , windowHeight - , wStart - , wFinish - , hStart - , hFinish - ) : app_type = + fun helpWindowResize + (app: app_type, windowWidth, windowHeight, wStart, wFinish, hStart, hFinish) : + app_type = + let + val + { xClickPoints = _ + , yClickPoints = _ + , windowWidth = _ + , windowHeight = _ + , graphLines = _ + , triangles + , triangleStage + } = app + val xClickPoints = ClickPoints.generate (wStart, wFinish) + val yClickPoints = ClickPoints.generate (hStart, hFinish) + val graphLines = + GraphLines.generate + (windowWidth, windowHeight, xClickPoints, yClickPoints) + in + { xClickPoints = xClickPoints + , yClickPoints = yClickPoints + , graphLines = graphLines + , triangles = triangles + , triangleStage = triangleStage + , windowWidth = windowWidth + , windowHeight = windowHeight + } + end + + fun windowResize (app: app_type, windowWidth, windowHeight) = + if windowWidth = windowHeight then + helpWindowResize + (app, windowWidth, windowHeight, 0, windowWidth, 0, windowHeight) + else if windowWidth > windowHeight then let - val - { xClickPoints = _ - , yClickPoints = _ - , windowWidth = _ - , windowHeight = _ - , graphLines = _ - , triangles - , triangleStage - } = app - val xClickPoints = ClickPoints.generate (wStart, wFinish) - val yClickPoints = ClickPoints.generate (hStart, hFinish) - val graphLines = - GraphLines.generate - (windowWidth, windowHeight, xClickPoints, yClickPoints) + val difference = windowWidth - windowHeight + val wStart = difference div 2 + val wFinish = wStart + windowHeight in - { xClickPoints = xClickPoints - , yClickPoints = yClickPoints - , graphLines = graphLines - , triangles = triangles - , triangleStage = triangleStage - , windowWidth = windowWidth - , windowHeight = windowHeight - } + helpWindowResize + (app, windowWidth, windowHeight, wStart, wFinish, 0, windowHeight) + end + else + let + val difference = windowHeight - windowWidth + val hStart = difference div 2 + val hFinish = hStart + windowWidth + in + helpWindowResize + (app, windowWidth, windowHeight, 0, windowWidth, hStart, hFinish) end - in - fun windowResize (app: app_type, windowWidth, windowHeight) = - if windowWidth = windowHeight then - make (app, windowWidth, windowHeight, 0, windowWidth, 0, windowHeight) - else if windowWidth > windowHeight then - let - val difference = windowWidth - windowHeight - val wStart = difference div 2 - val wFinish = wStart + windowHeight - in - make - (app, windowWidth, windowHeight, wStart, wFinish, 0, windowHeight) - end - else - let - val difference = windowHeight - windowWidth - val hStart = difference div 2 - val hFinish = hStart + windowWidth - in - make (app, windowWidth, windowHeight, 0, windowWidth, hStart, hFinish) - end - end end diff --git a/functional-core/click-points.sml b/functional-core/click-points.sml index 0de553c..c697604 100644 --- a/functional-core/click-points.sml +++ b/functional-core/click-points.sml @@ -1,4 +1,20 @@ -structure ClickPoints = +signature CLICK_POINTS = +sig + val generate: int * int -> Real32.real vector + val getClickPosition: + Real32.real + * Real32.real + * Real32.real + * Real32.real + * Real32.real + * Real32.real vector + * Real32.real vector + * int + * int + -> Real32.real vector * Real32.real * Real32.real +end + +structure ClickPoints :> CLICK_POINTS = struct fun generate (start, finish) = let @@ -9,127 +25,188 @@ struct Vector.tabulate (41, fn idx => (Real32.fromInt idx * increment) + start) end - local - (* - * Range to detect from clickable position. - * For example, if we have a clickable position at (x, y) = (500, 500), - * with a range of 15, we can detect clicks targeting this position - * from top left at (485, 485) to bottom right at (515, 515). - * *) - val range = 15.0 + (* + * Range to detect from clickable position. + * For example, if we have a clickable position at (x, y) = (500, 500), + * with a range of 15, we can detect clicks targeting this position + * from top left at (485, 485) to bottom right at (515, 515). + * *) + val range = 15.0 - fun getVerticalClickPos - ( yClickPoints - , idx - , horizontalPos - , mouseX - , mouseY - , r - , g - , b - , windowWidth - , windowHeight - ) = - if idx = Vector.length yClickPoints then - (#[], 0.0, 0.0) - else - let - val curVerticalPos = Vector.sub (yClickPoints, idx) - in - if - mouseY < curVerticalPos - range - orelse mouseY > curVerticalPos + range - then - getVerticalClickPos - ( yClickPoints - , idx + 1 - , horizontalPos - , mouseX - , mouseY - , r - , g - , b - , windowWidth - , windowHeight - ) - else - let - (* calculate normalised device coordinates *) - val halfWidth = Real32.fromInt (windowWidth div 2) - val halfHeight = Real32.fromInt (windowHeight div 2) - val hpos = horizontalPos - halfWidth - val vpos = ~(curVerticalPos - halfHeight) + fun getVerticalClickPos + ( yClickPoints + , idx + , horizontalPos + , mouseX + , mouseY + , r + , g + , b + , windowWidth + , windowHeight + ) = + if idx = Vector.length yClickPoints then + (#[], 0.0, 0.0) + else + let + val curVerticalPos = Vector.sub (yClickPoints, idx) + in + if + mouseY < curVerticalPos - range orelse mouseY > curVerticalPos + range + then + getVerticalClickPos + ( yClickPoints + , idx + 1 + , horizontalPos + , mouseX + , mouseY + , r + , g + , b + , windowWidth + , windowHeight + ) + else + let + (* calculate normalised device coordinates *) + val halfWidth = Real32.fromInt (windowWidth div 2) + val halfHeight = Real32.fromInt (windowHeight div 2) + val hpos = horizontalPos - halfWidth + val vpos = ~(curVerticalPos - halfHeight) - (* coordinates to form small box around clicked area *) - val left = (hpos - 5.0) / halfWidth - val right = (hpos + 5.0) / halfWidth - val bottom = (vpos - 5.0) / halfHeight - val top = (vpos + 5.0) / halfHeight + (* coordinates to form small box around clicked area *) + val left = (hpos - 5.0) / halfWidth + val right = (hpos + 5.0) / halfWidth + val bottom = (vpos - 5.0) / halfHeight + val top = (vpos + 5.0) / halfHeight - (* normalised device coordinates of drawVec should be relative - * to actual windowWidth and windowHeight, - * even if not a square, to display cursor position... *) - val drawVec = Ndc.ltrbToVertex (left, top, right, bottom, r, g, b) - in - (* - * ...however, normalised device coordinate of hpos and vpos - * should be relative to the vertical centre - * (if height is greater than width) - * or horizontal centre - * (if width is greater than height). - * - * So, for example, a 900x1000 resolution - * will have clickable points from 50...950, - * in increments of 50. - * Because we always want to show canvas as a square - * with an aspect ratio of 1:1. - * For displaying the click position on the screen, drawVec - * which uses actual windowWidth and windowHeight, is fine. - * However, we want to attach the meaning "start" to 50 - * and "end" to 950, - * so the hpos and vpos stored in the app's triangle list - * subtracts the offset 50 if needed, - * allowing us to treat the coordinates as a 900x900 square. - * - * We may not actually want to render a square to the screen - * if the screen's aspect ratio is not 1:1, - * but it's the responsibility of the rendering code - * which turns triangles into OpenGL vectors - * to do that. - * *) - if windowWidth = windowHeight then - let - val hpos = hpos / halfWidth - val vpos = vpos / halfHeight - in - (drawVec, hpos, vpos) - end - else if windowWidth > windowHeight then - let - val difference = windowWidth - windowHeight - val offset = Real32.fromInt (difference div 2) - val hpos = hpos / (halfWidth - offset) - val vpos = vpos / halfHeight - in - (drawVec, hpos, vpos) - end - else - (* windowHeight > windowWidth *) - let - val difference = windowHeight - windowWidth - val offset = Real32.fromInt (difference div 2) - val hpos = hpos / halfWidth - val vpos = vpos / (halfHeight - offset) - in - (drawVec, hpos, vpos) - end - end - end + (* normalised device coordinates of drawVec should be relative + * to actual windowWidth and windowHeight, + * even if not a square, to display cursor position... *) + val drawVec = Ndc.ltrbToVertex (left, top, right, bottom, r, g, b) + in + (* + * ...however, normalised device coordinate of hpos and vpos + * should be relative to the vertical centre + * (if height is greater than width) + * or horizontal centre + * (if width is greater than height). + * + * So, for example, a 900x1000 resolution + * will have clickable points from 50...950, + * in increments of 50. + * Because we always want to show canvas as a square + * with an aspect ratio of 1:1. + * For displaying the click position on the screen, drawVec + * which uses actual windowWidth and windowHeight, is fine. + * However, we want to attach the meaning "start" to 50 + * and "end" to 950, + * so the hpos and vpos stored in the app's triangle list + * subtracts the offset 50 if needed, + * allowing us to treat the coordinates as a 900x900 square. + * + * We may not actually want to render a square to the screen + * if the screen's aspect ratio is not 1:1, + * but it's the responsibility of the rendering code + * which turns triangles into OpenGL vectors + * to do that. + * *) + if windowWidth = windowHeight then + let + val hpos = hpos / halfWidth + val vpos = vpos / halfHeight + in + (drawVec, hpos, vpos) + end + else if windowWidth > windowHeight then + let + val difference = windowWidth - windowHeight + val offset = Real32.fromInt (difference div 2) + val hpos = hpos / (halfWidth - offset) + val vpos = vpos / halfHeight + in + (drawVec, hpos, vpos) + end + else + (* windowHeight > windowWidth *) + let + val difference = windowHeight - windowWidth + val offset = Real32.fromInt (difference div 2) + val hpos = hpos / halfWidth + val vpos = vpos / (halfHeight - offset) + in + (drawVec, hpos, vpos) + end + end + end - fun getHorizontalClickPos + fun getHorizontalClickPos + ( xClickPoints + , yClickPoints + , idx + , mouseX + , mouseY + , r + , g + , b + , windowWidth + , windowHeight + ) = + if idx = Vector.length xClickPoints then + (#[], 0.0, 0.0) + else + let + val curPos = Vector.sub (xClickPoints, idx) + in + if mouseX < curPos - range orelse mouseX > curPos + range then + getHorizontalClickPos + ( xClickPoints + , yClickPoints + , idx + 1 + , mouseX + , mouseY + , r + , g + , b + , windowWidth + , windowHeight + ) + else + getVerticalClickPos + ( yClickPoints + , 0 + , curPos + , mouseX + , mouseY + , r + , g + , b + , windowWidth + , windowHeight + ) + end + + (* + * This function returns a vector containing the position data of the + * clicked square. + * If a square wasn't found at the clicked position, + * an empty vector is returned. + *) + fun getClickPosition + ( mouseX + , mouseY + , r + , g + , b + , xClickPoints + , yClickPoints + , windowWidth + , windowHeight + ) = + getHorizontalClickPos ( xClickPoints , yClickPoints - , idx + , 0 , mouseX , mouseY , r @@ -137,69 +214,5 @@ struct , b , windowWidth , windowHeight - ) = - if idx = Vector.length xClickPoints then - (#[], 0.0, 0.0) - else - let - val curPos = Vector.sub (xClickPoints, idx) - in - if mouseX < curPos - range orelse mouseX > curPos + range then - getHorizontalClickPos - ( xClickPoints - , yClickPoints - , idx + 1 - , mouseX - , mouseY - , r - , g - , b - , windowWidth - , windowHeight - ) - else - getVerticalClickPos - ( yClickPoints - , 0 - , curPos - , mouseX - , mouseY - , r - , g - , b - , windowWidth - , windowHeight - ) - end - in - (* - * This function returns a vector containing the position data of the - * clicked square. - * If a square wasn't found at the clicked position, - * an empty vector is returned. - *) - fun getClickPosition - ( mouseX - , mouseY - , r - , g - , b - , xClickPoints - , yClickPoints - , windowWidth - , windowHeight - ) = - getHorizontalClickPos - ( xClickPoints - , yClickPoints - , 0 - , mouseX - , mouseY - , r - , g - , b - , windowWidth - , windowHeight - ) - end + ) end diff --git a/functional-core/graph-lines.sml b/functional-core/graph-lines.sml index 07897b6..510a63b 100644 --- a/functional-core/graph-lines.sml +++ b/functional-core/graph-lines.sml @@ -1,176 +1,183 @@ -structure GraphLines = +signature GRAPH_LINES = +sig + val generate: int * int * Real32.real vector * Real32.real vector + -> Real32.real vector +end + +structure GraphLines :> GRAPH_LINES = struct - local - (* This function only produces the desired result - * when the window is a square and has the aspect ratio 1:1. - * This is because the function assumes it can use - * the same position coordinates both horizontally and vertically. - * *) - fun helpGenGraphLinesSquare (pos: Real32.real, limit, acc) = - if pos >= limit then - Vector.concat acc - else - let - val pos2 = pos + 0.05 - val vec = - #[ (* x = _.1 *) - pos - 0.002, ~1.0 - , pos + 0.002, ~1.0 - , pos + 0.002, 1.0 + (* + * This function only produces the desired result + * when the window is a square and has the aspect ratio 1:1. + * This is because the function assumes it can use + * the same position coordinates both horizontally and vertically. + *) + fun helpGenGraphLinesSquare (pos: Real32.real, limit, acc) = + if pos >= limit then + Vector.concat acc + else + let + val pos2 = pos + 0.05 + val vec = + #[ (* x = _.1 *) + pos - 0.002, ~1.0 + , pos + 0.002, ~1.0 + , pos + 0.002, 1.0 - , pos + 0.002, 1.0 - , pos - 0.002, 1.0 - , pos - 0.002, ~1.0 - (* y = _.1 *) - , ~1.0, pos - 0.002 - , ~1.0, pos + 0.002 - , 1.0, pos + 0.002 + , pos + 0.002, 1.0 + , pos - 0.002, 1.0 + , pos - 0.002, ~1.0 - , 1.0, pos + 0.002 - , 1.0, pos - 0.002 - , ~1.0, pos - 0.002 + (* y = _.1 *) + , ~1.0, pos - 0.002 + , ~1.0, pos + 0.002 + , 1.0, pos + 0.002 + + , 1.0, pos + 0.002 + , 1.0, pos - 0.002 + , ~1.0, pos - 0.002 (* x = _.05 *) - , pos2 - 0.001, ~1.0 - , pos2 + 0.001, ~1.0 - , pos2 + 0.001, 1.0 + , pos2 - 0.001, ~1.0 + , pos2 + 0.001, ~1.0 + , pos2 + 0.001, 1.0 - , pos2 + 0.001, 1.0 - , pos2 - 0.001, 1.0 - , pos2 - 0.001, ~1.0 + , pos2 + 0.001, 1.0 + , pos2 - 0.001, 1.0 + , pos2 - 0.001, ~1.0 - (* y = _.05 *) - , ~1.0, pos2 - 0.001 - , ~1.0, pos2 + 0.001 - , 1.0, pos2 + 0.001 + (* y = _.05 *) + , ~1.0, pos2 - 0.001 + , ~1.0, pos2 + 0.001 + , 1.0, pos2 + 0.001 - , 1.0, pos2 + 0.001 - , 1.0, pos2 - 0.001 - , ~1.0, pos2 - 0.001 + , 1.0, pos2 + 0.001 + , 1.0, pos2 - 0.001 + , ~1.0, pos2 - 0.001 + ] + val acc = vec :: acc + val nextPos = pos + 0.1 + in + helpGenGraphLinesSquare (nextPos, limit, acc) + end + + fun helpGenGraphLinesHorizontal + (pos, xClickPoints, acc, halfWidth, yMin, yMax) = + if pos = Vector.length xClickPoints then + acc + else + let + val curX = Vector.sub (xClickPoints, pos) + val ndc = (curX - halfWidth) / halfWidth + val vec = + if (pos + 1) mod 2 = 0 then + (* if even (thin lines) *) + #[ + ndc - 0.001, yMin + , ndc + 0.001, yMin + , ndc + 0.001, yMax + + , ndc + 0.001, yMax + , ndc - 0.001, yMax + , ndc - 0.001, yMin ] - val acc = vec :: acc - val nextPos = pos + 0.1 - in - helpGenGraphLinesSquare (nextPos, limit, acc) - end + else + (* if odd (thick lines) *) + #[ + ndc - 0.002, yMin + , ndc + 0.002, yMin + , ndc + 0.002, yMax - fun helpGenGraphLinesHorizontal (pos, xClickPoints, acc, halfWidth, yMin, yMax) = - if pos = Vector.length xClickPoints then - acc - else - let - val curX = Vector.sub (xClickPoints, pos) - val ndc = (curX - halfWidth) / halfWidth - val vec = - if (pos + 1) mod 2 = 0 then - (* if even (thin lines) *) - #[ - ndc - 0.001, yMin - , ndc + 0.001, yMin - , ndc + 0.001, yMax + , ndc + 0.002, yMax + , ndc - 0.002, yMax + , ndc - 0.002, yMin + ] + val acc = vec :: acc + in + helpGenGraphLinesHorizontal + (pos + 1, xClickPoints, acc, halfWidth, yMin, yMax) + end - , ndc + 0.001, yMax - , ndc - 0.001, yMax - , ndc - 0.001, yMin - ] - else - (* if odd (thick lines) *) - #[ - ndc - 0.002, yMin - , ndc + 0.002, yMin - , ndc + 0.002, yMax + fun helpGenGraphLinesVertical (pos, yClickPoints, acc, halfHeight, xMin, xMax) = + if pos = Vector.length yClickPoints then + acc + else + let + val curY = Vector.sub (yClickPoints, pos) + val ndc = (curY - halfHeight) / halfHeight + val vec = + if (pos + 1) mod 2 = 0 then + (* if even (thin lines) *) + #[ + xMin, ndc - 0.001 + , xMin, ndc + 0.001 + , xMax, ndc + 0.001 - , ndc + 0.002, yMax - , ndc - 0.002, yMax - , ndc - 0.002, yMin - ] - val acc = vec:: acc - in - helpGenGraphLinesHorizontal - (pos + 1, xClickPoints, acc, halfWidth, yMin, yMax) - end + , xMax, ndc + 0.001 + , xMax, ndc - 0.001 + , xMin, ndc - 0.001 + ] + else + (* if odd (thick lines) *) + #[ + xMin, ndc - 0.002 + , xMin, ndc + 0.002 + , xMax, ndc + 0.002 - fun helpGenGraphLinesVertical (pos, yClickPoints, acc, halfHeight, xMin, xMax) = - if pos = Vector.length yClickPoints then - acc - else - let - val curY = Vector.sub (yClickPoints, pos) - val ndc = (curY - halfHeight) / halfHeight - val vec = - if (pos + 1) mod 2 = 0 then - (* if even (thin lines) *) - #[ - xMin, ndc - 0.001 - , xMin, ndc + 0.001 - , xMax, ndc + 0.001 + , xMax, ndc + 0.002 + , xMax, ndc - 0.002 + , xMin, ndc - 0.002 + ] + val acc = vec :: acc + in + helpGenGraphLinesVertical + (pos + 1, yClickPoints, acc, halfHeight, xMin, xMax) + end - , xMax, ndc + 0.001 - , xMax, ndc - 0.001 - , xMin, ndc - 0.001 - ] - else - (* if odd (thick lines) *) - #[ - xMin, ndc - 0.002 - , xMin, ndc + 0.002 - , xMax, ndc + 0.002 + fun generate (windowWidth, windowHeight, xClickPoints, yClickPoints) = + if windowWidth = windowHeight then + helpGenGraphLinesSquare (~1.0, 1.0, []) + else if windowWidth > windowHeight then + let + val difference = windowWidth - windowHeight + val offset = difference div 2 - , xMax, ndc + 0.002 - , xMax, ndc - 0.002 - , xMin, ndc - 0.002 - ] - val acc = vec:: acc - in - helpGenGraphLinesVertical - (pos + 1, yClickPoints, acc, halfHeight, xMin, xMax) - end - in - fun generate (windowWidth, windowHeight, xClickPoints, yClickPoints) = - if windowWidth = windowHeight then - helpGenGraphLinesSquare (~1.0, 1.0, []) - else if windowWidth > windowHeight then - let - val difference = windowWidth - windowHeight - val offset = difference div 2 + val halfWidth = Real32.fromInt (windowWidth div 2) + val halfHeight = Real32.fromInt (windowHeight div 2) - val halfWidth = Real32.fromInt (windowWidth div 2) - val halfHeight = Real32.fromInt (windowHeight div 2) + val start = offset - (windowWidth div 2) + val start = Real32.fromInt start / halfWidth - val start = offset - (windowWidth div 2) - val start = Real32.fromInt start / halfWidth + val finish = (windowWidth - offset) - (windowWidth div 2) + val finish = Real32.fromInt finish / halfWidth - val finish = (windowWidth - offset) - (windowWidth div 2) - val finish = Real32.fromInt finish / halfWidth + val lines = helpGenGraphLinesHorizontal + (0, xClickPoints, [], halfWidth, ~1.0, 1.0) + val lines = helpGenGraphLinesVertical + (0, yClickPoints, lines, halfHeight, start, finish) + in + Vector.concat lines + end + else + (* windowWidth < windowHeight *) + let + val difference = windowHeight - windowWidth + val offset = difference div 2 - val lines = helpGenGraphLinesHorizontal - (0, xClickPoints, [], halfWidth, ~1.0, 1.0) - val lines = helpGenGraphLinesVertical - (0, yClickPoints, lines, halfHeight, start, finish) - in - Vector.concat lines - end - else - (* windowWidth < windowHeight *) - let - val difference = windowHeight - windowWidth - val offset = difference div 2 + val halfWidth = Real32.fromInt (windowWidth div 2) + val halfHeight = Real32.fromInt (windowHeight div 2) - val halfWidth = Real32.fromInt (windowWidth div 2) - val halfHeight = Real32.fromInt (windowHeight div 2) + val start = offset - (windowHeight div 2) + val start = Real32.fromInt start / halfHeight - val start = offset - (windowHeight div 2) - val start = Real32.fromInt start / halfHeight + val finish = (windowHeight - offset) - (windowHeight div 2) + val finish = Real32.fromInt finish / halfHeight - val finish = (windowHeight - offset) - (windowHeight div 2) - val finish = Real32.fromInt finish / halfHeight - - val lines = helpGenGraphLinesHorizontal - (0, xClickPoints, [], halfWidth, start, finish) - val lines = helpGenGraphLinesVertical - (0, yClickPoints, lines, halfHeight, ~1.0, 1.0) - in - Vector.concat lines - end - end + val lines = helpGenGraphLinesHorizontal + (0, xClickPoints, [], halfWidth, start, finish) + val lines = helpGenGraphLinesVertical + (0, yClickPoints, lines, halfHeight, ~1.0, 1.0) + in + Vector.concat lines + end end diff --git a/functional-core/triangles.sml b/functional-core/triangles.sml index 3ebe93e..cddb82b 100644 --- a/functional-core/triangles.sml +++ b/functional-core/triangles.sml @@ -1,46 +1,48 @@ -structure Triangles = +signature TRIANGLES = +sig + val toVector: AppType.app_type -> Real32.real vector +end + +structure Triangles :> TRIANGLES = struct open AppType - local - fun helpToVector - (lst, acc, windowWidth, windowHeight, halfWidth, halfHeight) = - case lst of - {x1, y1, x2, y2, x3, y3} :: tl => - let - val x1 = Ndc.centreAlignX (x1, windowWidth, windowHeight, halfWidth) - val x2 = Ndc.centreAlignX (x2, windowWidth, windowHeight, halfWidth) - val x3 = Ndc.centreAlignX (x3, windowWidth, windowHeight, halfWidth) + fun helpToVector (lst, acc, windowWidth, windowHeight, halfWidth, halfHeight) = + case lst of + {x1, y1, x2, y2, x3, y3} :: tl => + let + val x1 = Ndc.centreAlignX (x1, windowWidth, windowHeight, halfWidth) + val x2 = Ndc.centreAlignX (x2, windowWidth, windowHeight, halfWidth) + val x3 = Ndc.centreAlignX (x3, windowWidth, windowHeight, halfWidth) - val y1 = Ndc.centreAlignY (y1, windowWidth, windowHeight, halfHeight) - val y2 = Ndc.centreAlignY (y2, windowWidth, windowHeight, halfHeight) - val y3 = Ndc.centreAlignY (y3, windowWidth, windowHeight, halfHeight) + val y1 = Ndc.centreAlignY (y1, windowWidth, windowHeight, halfHeight) + val y2 = Ndc.centreAlignY (y2, windowWidth, windowHeight, halfHeight) + val y3 = Ndc.centreAlignY (y3, windowWidth, windowHeight, halfHeight) - val vec = - #[ x1 / halfWidth - , y1 / halfHeight - , x2 / halfWidth - , y2 / halfHeight - , x3 / halfWidth - , y3 / halfHeight - ] - val acc = vec :: acc - in - helpToVector - (tl, acc, windowWidth, windowHeight, halfWidth, halfHeight) - end - | [] => acc - in - fun toVector (app: app_type) = - let - val windowWidth = #windowWidth app - val windowHeight = #windowHeight app - val halfWidth = Real32.fromInt (windowWidth div 2) - val halfHeight = Real32.fromInt (windowHeight div 2) - val lst = helpToVector - (#triangles app, [], windowWidth, windowHeight, halfWidth, halfHeight) - in - Vector.concat lst - end - end + val vec = + #[ x1 / halfWidth + , y1 / halfHeight + , x2 / halfWidth + , y2 / halfHeight + , x3 / halfWidth + , y3 / halfHeight + ] + val acc = vec :: acc + in + helpToVector + (tl, acc, windowWidth, windowHeight, halfWidth, halfHeight) + end + | [] => acc + + fun toVector (app: app_type) = + let + val windowWidth = #windowWidth app + val windowHeight = #windowHeight app + val halfWidth = Real32.fromInt (windowWidth div 2) + val halfHeight = Real32.fromInt (windowHeight div 2) + val lst = helpToVector + (#triangles app, [], windowWidth, windowHeight, halfWidth, halfHeight) + in + Vector.concat lst + end end