|
(49g 50g) Shoelace algorithm +- HP Forums (http://www.hpmuseum.org/forum) +-- Forum: HP Software Libraries (/forum-10.html) +--- Forum: General Software Library (/forum-13.html) +--- Thread: (49g 50g) Shoelace algorithm (/thread-11259.html) |
(49g 50g) Shoelace algorithm - John Keith - 08-23-2018 09:20 AM EDIT: These programs have been largely obsoleted by Thomas Klemm's programs in post numbers 5 and 11 respectively. I am leaving them here for illustrative purposes only. Inspired by Thomas Klemm's elegant RPL implementation of the shoelace method for calculating the area of a polygon, I am listing my version here. Though it is longer and not nearly as elegant, it is over 2.5 times faster. My program differs in that it takes a list of coordinates of the form { X1 Y1 X2 Y2...Xn Yn } instead of a list of two-element vectors. Code: The following extended version calculates the area and centroid (aka barycenter) of a polygon. The results are returned as a list of the form { Area X Y }. Code: Both programs will return exact integer or rational results if the input coordinates are exact and the program is run in exact mode. If this is not desirable, the integer(s) in the last lines of the programs can be changed to reals, and the EVALs in the last line of the second program can be eliminated. This will make the programs run slightly faster. RE: ( HP49/50) Shoelace algorithm - Thomas Klemm - 08-23-2018 10:56 PM Alternatively we can use \(A=\frac{1}{2}\sum_{i=1}^{n}x_{i}(y_{i+1}-y_{i-1})\) where \(y_{n+1}=y_{1}\) and \(y_{0}=y_{n}\). (xs ys -- area) Code: « DUP TAIL OVER HEAD + SWAPThe coordinates of the polygon have to be entered as two separate lists xs and ys. There might be better ways to rotate the elements of ys left and right. Kind regards Thomas RE: ( HP49/50) Shoelace algorithm - Thomas Klemm - 08-24-2018 08:51 PM (08-24-2018 09:08 AM)John Keith Wrote: If you have any suggestions for improving the rest of my area-and-centroid program I'm all ears. I used these formulas found in Centroid: \(C_{\mathrm {x} }={\frac {1}{6A}}\sum _{i=0}^{n-1}(x_{i}+x_{i+1})(x_{i}\ y_{i+1}-x_{i+1}\ y_{i})\) \(C_{\mathrm {y} }={\frac {1}{6A}}\sum _{i=0}^{n-1}(y_{i}+y_{i+1})(x_{i}\ y_{i+1}-x_{i+1}\ y_{i})\) where \(x_{n}=x_{0}\) and \(y_{n}=y_{0}\). (xs ys -- x y area) Code: « DUP TAIL OVER HEAD + ROTExample For the cat from this video: xs: { 4 0 -2 -6 -1 5 } ys: { 4 1 5 0 -4 -2 } The result is: 3: -.169696969697 2: .030303030303 1: 55 Cheers Thomas RE: (49g 50g) Shoelace algorithm - John Keith - 08-26-2018 08:47 AM The only improvement I can see for Thomas's area-and-centroid program using ListExt commands is to simply replace TAIL OVER HEAD + with LRLLD so that the first two lines become DUP LRLLD ROT DUP LRLLD. This saves about 10ms for the Cat and reduces the size from 194 to 172.5 bytes, at the cost of HP48g compatibility. Congratulations again to Thomas for a fine example of RPL programming! I can't think of a way to make a non-intersecting polygon with a large number of points other than points spread evenly around a circle, or tediously typing hundreds of points in. Based on experience I would guess that the speed ratios we have seen would hold pretty well for larger polygons. EDIT: I created a random (improper, multiply intersecting) polygon of 500 points, and a polygon made from 500 points evenly spread around a circle. For both polygons, my program from the first post takes about 42 seconds, and Thomas's program from post #11 takes about 18 seconds. The version using LRLLD is only about 100 milliseconds faster. John RE: University of Houston math contests - telemachos - 07-12-2019 11:41 AM I think this makes the best use of the HP-50g's capabilities: Input: { [–6.94 –1.2] [–5.16 3.84] [3.4 2.18] [2.46 –6.72] } Program (56.5 bytes): << DUP HEAD + << CROSS >> DOSUBS ΣLIST ABS 2 / >> Output: 67.473 RE: (49g 50g) Shoelace algorithm - John Keith - 08-24-2019 08:19 AM At Albert Chan's request, I am posting an HP-48G / HP 50 program for the perimeter of a polygon. Stack diagram is the same as for Thomas's programs for polygon area and centroid: xs ys -> p Code: |