Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Centroid Question
#11
yeah I thought you @TerryRitchie were that far already???

Google: How to calculate the Centroid:
Quote:How do I compute the centroid in a polygon?
Write down the coordinates of each polygon vertex.
Count the vertices and denote their number by n .
Add all the x values from the vertices and divide the sum by n .
Add all the y values from the vertices and divide the sum by n .
That's it!

thats why I said compare that to your idea of mid(x, y) (xmax-xmin)/2, (ymax-ymin)/2
They might be kinda close, the same in certain cases like a circle but not always correct.
b = b + ...
Reply
#12
Then expanded to include calculation of the center of gravity - height of the triangle unknown. The calculation should be correct, but probably not for all shapes of triangles.
Polygon is too complicated for me now. Now I need a good glass of wine first.  Tongue

Code: (Select All)

'Berechnung des Inkreismittelpunktes und des Schwerpunkts eines Dreiecks - 14. Juli 2024
'https://www.biancahoegel.de/geometrie/ebene/inkreis.html
'Mathematik 2 Geometrie S.98ff, 106, 108

Option _Explicit

'ad, bd, cd Seiten eines Dreiecks, AF = Flaecheninhalt, s = Umfang
Dim As Double AF, ad, bd, cd, s, radius, dummy
Dim As Double xAchse, yAchse, hoeheDreieck

Locate 2, 3
Print "Berechnung des Inkreismittelpunktes und des Schwerpunkts eines Dreiecks"
Locate 3, 3
Print "======================================================================="

Locate 5, 3
Input "Laenge der Seite a in cm: ", ad
Locate 6, 3
Input "Laenge der Seite b in cm: ", bd
Locate 7, 3
Input "Laenge der Seite c in cm: ", cd

s = (ad + bd + cd) / 2
dummy = s * ((s - ad) * (s - bd) * (s - cd))
AF = Sqr(dummy)

'Der Radius ist von allen Seiten des Dreiecks gleich weit entfernt,
'und zeigt somit den Inkreismittelpunkt an.
radius = (2 * AF) / (ad + bd + cd)

Locate 9, 3
Print Using "Der Inkreismittelpunkt des gegebenen Dreiecks liegt bei ###.## cm."; radius

'Schwerpunkt des Dreiecks unbekanter Hoehe
'Erst die Hoehe berechnen  - s und dummy bleiben
hoeheDreieck = (2 / cd) * Sqr(dummy)

'X-Achse und Y-Achse berechnen
xAchse = (2 / 3) * ad
yAchse = (1 / 3) * hoeheDreieck

Locate 11, 3
Print "Der Schwerpunkt des Dreiecks liegt:"
Locate 12, 3
Print Using "Bei der X-Achse bei ###.## cm - bei Y-Achse bei ###.## cm"; xAchse, yAchse


'Bild anzeigen
_Clipboard$ = "Inkreis+SchwerpDreieck.jpg"
Shell "BildAnzeigen.exe"

End

[Image: Inkreis-Schwerpunkt-Dreieck.jpg]
Reply
#13
If you want something done right... don't wait for bplus to do it because he will post blunderful code many times before he gets this simple thing right
Code: (Select All)
Const RED~& = _RGB32(255, 0, 0)
Const GREEN~& = _RGB32(0, 255, 0)
Const GRAY~& = _RGB32(64, 64, 64)
Const Blue~& = _RGB32(0, 0, 255)
Type iPoint
    As Integer x, y
End Type
Dim Min As iPoint '    min x,y seen
Dim Max As iPoint '    max x,y seen
Dim Center As iPoint ' center point of random points
Dim Centroid As iPoint
Dim p As Integer
Dim tx, ty ' totals of x, y

_Title "Terry's Point (yellow) versus the Centroid Point in blue."
Screen _NewImage(640, 480, 32)
Randomize Timer
restart:
Min.x = 641 '          start min at max
Min.y = 481
Max.x = -1 'start max at min
Max.y = -1

Dim nRP As Integer: nRP = 3 + Int(Rnd * 9) ' Int(Rnd * 9' NUMBER OF RANDOM POINTS
ReDim rp(1 To nRP) As iPoint ' random point

tx = 0: ty = 0
For p = 1 To nRP '                             create random points
    rp(p).x = Rnd * 600 + 20 ' 20 pixel border  of no points
    rp(p).y = Rnd * 440 + 20
    tx = rp(p).x + tx
    ty = rp(p).y + ty
    If rp(p).x > Max.x Then Max.x = rp(p).x
    If rp(p).x < Min.x Then Min.x = rp(p).x ' get max/min x
    If rp(p).y > Max.y Then Max.y = rp(p).y
    If rp(p).y < Min.y Then Min.y = rp(p).y ' get max/min y
Next

Center.x = (Max.x + Min.x) / 2 ' get center x
Center.y = (Max.y + Min.y) / 2 ' get center y
Centroid.x = Int(tx / nRP)
Centroid.y = Int(ty / nRP)

For p = 1 To nRP '                                    draw points in red, lines to center in gray
    Line (rp(p).x, rp(p).y)-(Centroid.x, Centroid.y), GRAY
    Circle (rp(p).x, rp(p).y), 2, RED
    Paint (rp(p).x, rp(p).y), RED, RED
Next

Circle (Center.x, Center.y), 2, GREEN '                 draw green center point
Paint (Center.x, Center.y), GREEN, GREEN

Circle (Centroid.x, Centroid.y), 2, Blue '                 draw green center point
Paint (Centroid.x, Centroid.y), Blue, Blue

Print Min.x; Min.y, Max.x; Max.y, Center.x; Center.y, Centroid.x; Centroid.y '  display values
Locate 30, 1: Print "zzz... sleeping press any for another Centroid calc.";
Sleep
Cls
GoTo restart

EDIT: oh crap min and max was not calculating correctly, fixed
something is still off!

Fixed: dividing by number of points does not work with ubound of array that starts at 0 Tongue
Then had to reset everything like max and min to loop through many, many examples with different amounts of points. Tongue


Attached Files Image(s)
   
b = b + ...
Reply
#14
Math-wise, if you want something done right, just keep checking Mark's updates. If you want something done right away, do itself and live in misery.

Pete
Reply
#15
nice mod, bplus, check out my old centroid mod

Code: (Select All)
deflng a-z
const sw = 800
const sh = 600
dim shared pi as double
pi = 4*atn(1)
declare sub circlef(x, y, r, c)

n = 14
dim x(n), y(n)

for i=0 to n-1
    x(i) = 200*cos(2*pi*i/n)
    y(i) = 200*sin(2*pi*i/n)
next

'x(0) = 0: y(0) = -200
'x(1) = -30: y(1) = -30
'x(2) = -200: y(2) = 0
'x(3) = -30: y(3) = 30
'x(4) = 0: y(4) = 200
'x(5) = 30: y(5) = 30
'x(6) = 200: y(6) = 0
'x(7) = 30: y(7) = -30
x(n) = x(0)
y(n) = y(0)

for i=0 to n-1
    x(i) = 200*cos(2*pi*i/n)
    y(i) = 200*sin(2*pi*i/n)
next

'screenres sw, sh, 32
screen _newimage(sw, sh, 32)
redraw = -1
drag = 0
do
    'm = getmouse(mx, my, mw, mb)
    do
        mx = _mousex
        my = _mousey
        mb = -_mousebutton(1)
    loop while _mouseinput
   
    if drag then
        if mb = 1 then
            x(ii) = mx - sw/2
            y(ii) = sh/2 - my
        else
            drag = 0
        end if
    else
        dmin = 1e10
        for i=0 to n - 1
            dx = (mx - sw/2) - x(i)
            dy = (sh/2 - my) - y(i)
            d = (dx*dx + dy*dy)
            if d < dmin then
                dmin = d
                ii = i
            end if
        next

        if mb = 1 then
            omx = mx
            omy = my
            drag = -1
        end if
    end if

    a = 0
    cx = 0
    cy = 0
    for i=0 to n-1
        d = x(i)*y(i + 1) - x(i + 1)*y(i)
        cx = cx + (x(i) + y(i + 1))*d
        cy = cy + (y(i) + y(i + 1))*d
        a = a + d
    next
    cx = cx/(3*a)
    cy = cy/(3*a)

    redraw = -1

    if redraw then
        'screenlock
       
        line (0,0)-(sw,sh),_rgb(0,0,0),bf
        locate 1,1: ? m, mx, my, mw, mb

        x(n) = x(0)
        y(n) = y(0)
        x0 = sw/2 + x(0)
        y0 = sh/2 - y(0)
        for i=1 to n
            x1 = sw/2 + x(i)
            y1 = sh/2 - y(i)
            line (x0, y0)-(x1, y1)
            'line -(sw/2 + cx, sh/2 - cy)
            circlef x1, y1, 8, _rgb(255,255,255)
            x0 = x1
            y0 = y1
        next
        circlef sw/2 + x(ii), sh/2 - y(ii), 8, _rgb(255,0,0)

        circle (sw/2 + cx, sh/2 - cy), 10, _rgb(255,255,0)
        circlef sw/2 + cx, sh/2 - cy, 7, _rgb(255,255,0)

        'screenunlock
        'screensync

        redraw = 0

        _display
    end if
loop until _keyhit = 27
system


sub circlef(x, y, r, c)
    x0 = r
    y0 = 0
    e = -r

    do while y0 < x0
        if e <=0 then
            y0 = y0 + 1
            line (x - x0, y + y0)-(x + x0, y + y0), c, bf
            line (x - x0, y - y0)-(x + x0, y - y0), c, bf
            e = e + 2*y0
        else
            line (x - y0, y - x0)-(x + y0, y - x0), c, bf
            line (x - y0, y + x0)-(x + y0, y + x0), c, bf
            x0 = x0 - 1
            e = e - 2*x0
        end if
    loop
    line (x - r, y)-(x + r, y), c, bf
end sub
Reply
#16
Yeah @vince fun to play with...


Attached Files Image(s)
   
b = b + ...
Reply
#17
(07-14-2024, 06:55 PM)bplus Wrote: If you want something done right... don't wait for bplus to do it because he will post blunderful code many times before he gets this simple thing right

EDIT: oh crap min and max was not calculating correctly, fixed
something is still off!

Fixed: dividing by number of points does not work with ubound of array that starts at 0 Tongue
Then had to reset everything like max and min to loop through many, many examples with different amounts of points. Tongue
Is this supposed to be a polygon? You can also see it as a triangle.  Wink

[Image: Dreieck-Polygon.jpg]
Reply
#18
(07-15-2024, 01:02 PM)bplus Wrote: Yeah @vince fun to play with...

Great, now thanks to Mark we can find the center of Satan. I'll stick to how many licks it takes me to get to the center of a Tootsie Pop.

Pete Big Grin (Needed a laugh today). +1
Reply




Users browsing this thread: 2 Guest(s)