Ramer-Douglas-Peucker line simplification: Difference between revisions
Content added Content deleted
(Added BASIC256) |
(Added various BASIC dialects (QBasic and QB64)) |
||
Line 1,517: | Line 1,517: | ||
<pre>LINESTRING (0 0, 2 -0.1, 3 5, 7 9, 9 9)</pre> |
<pre>LINESTRING (0 0, 2 -0.1, 3 5, 7 9, 9 9)</pre> |
||
=={{header| |
=={{header|QBasic}}== |
||
{{works with|QBasic|1.1}} |
|||
{{works with|QuickBasic|4.5}} |
|||
{{works with|QB64}} |
|||
<syntaxhighlight lang="qbasic">DECLARE SUB DRDP (ListaDePuntos() AS DOUBLE, ini AS INTEGER, fin AS INTEGER, epsilon AS DOUBLE) |
|||
DECLARE FUNCTION DistanciaPerpendicular! (tabla() AS DOUBLE, i AS INTEGER, ini AS INTEGER, fin AS INTEGER) |
|||
CONST True = -1 |
|||
DIM matriz(1 TO 10, 1 TO 3) AS DOUBLE |
|||
DATA 0,0,1,0.1,2,-0.1,3,5,4,6,5,7,6,8.1,7,9,8,9,9,9 |
|||
FOR i = LBOUND(matriz) TO UBOUND(matriz) |
|||
READ matriz(i, 1), matriz(i, 2) |
|||
NEXT i |
|||
CALL DRDP(matriz(), 1, 10, 1) |
|||
PRINT "Remaining points after simplifying:" |
|||
matriz(1, 3) = True: matriz(10, 3) = True |
|||
FOR i = LBOUND(matriz) TO UBOUND(matriz) |
|||
IF matriz(i, 3) THEN PRINT "("; matriz(i, 1); ", "; matriz(i, 2); ") "; |
|||
NEXT i |
|||
END |
|||
FUNCTION DistanciaPerpendicular (tabla() AS DOUBLE, i AS INTEGER, ini AS INTEGER, fin AS INTEGER) |
|||
DIM dx AS DOUBLE, dy AS DOUBLE, mag AS DOUBLE, pvx AS DOUBLE, pvy AS DOUBLE |
|||
DIM pvdot AS DOUBLE, dsx AS DOUBLE, dsy AS DOUBLE, ax AS DOUBLE, ay AS DOUBLE |
|||
dx = tabla(fin, 1) - tabla(ini, 1) |
|||
dy = tabla(fin, 2) - tabla(ini, 2) |
|||
'Normalise |
|||
mag = (dx ^ 2 + dy ^ 2) ^ .5 |
|||
IF mag > 0 THEN dx = dx / mag: dy = dy / mag |
|||
pvx = tabla(i, 1) - tabla(ini, 1) |
|||
pvy = tabla(i, 2) - tabla(ini, 2) |
|||
'Get dot product (project pv onto normalized direction) |
|||
pvdot = dx * pvx + dy * pvy |
|||
'Subtract this from pv |
|||
dsx = pvdot * dx |
|||
dsy = pvdot * dy |
|||
'Reste esto de pv |
|||
ax = pvx - dsx |
|||
ay = pvy - dsy |
|||
DistanciaPerpendicular = (ax ^ 2 + ay ^ 2) ^ .5 |
|||
END FUNCTION |
|||
SUB DRDP (ListaDePuntos() AS DOUBLE, ini AS INTEGER, fin AS INTEGER, epsilon AS DOUBLE) |
|||
DIM dmax AS DOUBLE, d AS DOUBLE |
|||
DIM indice AS INTEGER, i AS INTEGER |
|||
' Find the point with the maximum distance |
|||
IF UBOUND(ListaDePuntos) < 2 THEN PRINT "Not enough points to simplify": END |
|||
FOR i = ini + 1 TO fin |
|||
d = DistanciaPerpendicular(ListaDePuntos(), i, ini, fin) |
|||
IF d > dmax THEN indice = i: dmax = d |
|||
NEXT |
|||
' If max distance is greater than epsilon, recursively simplify |
|||
IF dmax > epsilon THEN |
|||
ListaDePuntos(indice, 3) = True |
|||
' Recursive call |
|||
CALL DRDP(ListaDePuntos(), ini, indice, epsilon) |
|||
CALL DRDP(ListaDePuntos(), indice, fin, epsilon) |
|||
END IF |
|||
END SUB</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Remaining points after simplifying: |
|||
( 0 , 0 ) ( 2 , -.1 ) ( 3 , 5 ) ( 7 , 9 ) ( 9 , 9 )</pre> |
|||
=={{header|QB64}}== |
|||
The [[#QBasic|QBasic]] solution works without any changes. |
|||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket">#lang racket |
<syntaxhighlight lang="racket">#lang racket |
||
(require math/flonum) |
(require math/flonum) |