1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Math professors in the house?

Discussion in 'Tools programming' started by SdC, 8/4/07.

  1. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Hi all,
    My highschool math lessons seem to have made place for other stuff in my head...
    I'm programming a polygon manipulation tool, but cannot get around the following problem, and I hope some brilliant soul could give me some help with it:

    [​IMG]

    If I know the points (x1,y1), (x2,y2) and (x3,y3) as well as the distance between the parallel lines (w) how could I deduct the intersections of the parallel lines (x4,y4),(x5,y5)?
  2. Luis_Sá

    Luis_Sá Resource contributor

    Joined:
    16/9/04
    Messages:
    314
    Country:
    portugal
    Hello,

    Here is the code I use in SBuilder to draw one "wide line" NP points. For each point I have the X, Y and W (width at this point). Note that I start at point 2. The instruction FillPolygon(PTS) draws the polygon (filling it with a color) whose vertices are PTS(0) PTS(1) PTS(2) and PTS(3). I post here 2 pictures. The first one is the normal one. The second one is the one I get after deleting the FillPolygon(PTS) inside the "If Then ... End If". I hope you can figure out the points PTS(0) PTS(1) PTS(2) and PTS(3) by looking to the pictures.

    PX1 = X(1)
    PY1 = Y(1)
    PW1 = W(1)/2

    For K = 2 To NP

    PX0 = PX1
    PY0 = PY1
    PW0 = PW1

    PX1 = X(K)
    PY1 = Y(K)
    PW1 = W(K)/2

    UX = PX1 - PX0
    UY = PY1 - PY0
    U = UX * UX + UY * UY
    U = System.Math.Sqrt(U)

    UX = UX / U
    UY = UY / U
    DX = PW0 * UX
    DY = PW0 * UY

    PTS(0).X = PX0 - DY
    PTS(0).Y = PY0 + DX
    PTS(1).X = PX0 + DY
    PTS(1).Y = PY0 - DX

    If K > 2 Then
    FillPolygon(PTS)
    End If

    DX = PW1 * UX
    DY = PW1 * UY
    PTS(2).X = PX1 + DY
    PTS(2).Y = PY1 - DX
    PTS(3).X = PX1 - DY
    PTS(3).Y = PY1 + DX

    FillPolygon(PTS)

    Next K


    [​IMG]


    [​IMG]


    Regards,

    Luis
  3. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Hi Luis!
    Thanks very much, I will look at it today.

    -The purpose of this routine is to convert lines from an SBX file (!) and create ASM output to draw VTP1 (!) lines. VTP1 lines are my closest friend and my worst enemy at the same time for the last 4 years. This is my site: http://combatfs.homeip.net
    Rhumba and me almost continuously have discussions like this: http://www.fsdeveloper.com/forum/showthread.php?t=4182

    The tool I'm developing is cfs2autocoast. Until now, I was converting lines to ground2k project (LWM file) because ground2k3 v.4 is currently the only program to compile VTP1 lines, but the routine is too buggy and Christian lost the source files for it.....

    Maybe if I get this project working, you'd be interested in integrating it in sBuilder (a CFS2 checkbox in the BGL compilation form)? I know of about 6 active developers (we hang out at www.sim-outhouse.com) that would make good use of it!

    Right now, I'm programming in vb.net 2005, and I think you are using vb6?
    Maybe we can help each other (I'm very good at upgrading vb6 apps for .NET/ Vista).

    I'll let you know how I get on with the routine!
    Bye now,
    -Sander.
  4. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Unfortunately your algorithm is not going to work well for me; it would become too difficult to do the UV map and also roads/railways would become uneven.
    The result I need to get is something like:
    [​IMG]

    But the result I get is:
    [​IMG]

    from this code:
    Code:
    Public Sub CreatePolygons()
    
            Dim i As Integer
            Dim w, a As Double
            Dim Preva1X, Preva1Y, Preva2X, Preva2Y As Double
    
            ReDim SegmentPolys(NumberOfPoints - 1)
            For i = 1 To NumberOfPoints - 1
                If i = 1 Then
                    'first point parameters
                    If BeginThinner = True Then w = 8 Else w = getSegmentWidth(0)
                    'set the first point:
                    Preva1X = getPointX(0) + (PixDegreeX(w / 2) * Sin(90))
                    Preva1Y = getPointY(0) + (PixDegreeY(w / 2) * Sin(90))
                    Preva2X = getPointX(0) - (PixDegreeX(w / 2) * Sin(90))
                    Preva2Y = getPointY(0) - (PixDegreeY(w / 2) * Sin(90))
                    w = getSegmentWidth(i)
                    a = Gamma(i)
                ElseIf i <= NumberOfPoints - 2 Then
                    'middle points parameters
                    w = getSegmentWidth(i)
                    a = Gamma(i)
                ElseIf i = NumberOfPoints - 1 Then
                    'last point
                    If EndThinner = True Then w = 8 Else w = getSegmentWidth(i)
                    a = 180
    
                End If
    
                SegmentPolys(i - 1) = New LineSegment.RectanglePolygon
                ' MsgBox(a.ToString)
                With SegmentPolys(i - 1)
                    .b1X = Preva1X
                    .b1Y = Preva1Y
                    .b2X = Preva2X
                    .b2Y = Preva2Y
    [COLOR="Red"]                .a1X = getPointX(i) + (PixDegreeX(w / 2) * Sin(a / 2))
                    .a1Y = getPointY(i) + (PixDegreeY(w / 2) * Sin(a / 2))
                    .a2X = getPointX(i) - (PixDegreeX(w / 2) * Sin(a / 2))
                    .a2Y = getPointY(i) - (PixDegreeY(w / 2) * Sin(a / 2))[/COLOR]
                End With
    
                Preva1X = SegmentPolys(i - 1).a1X
                Preva1Y = SegmentPolys(i - 1).a1Y
                Preva2X = SegmentPolys(i - 1).a2X
                Preva2Y = SegmentPolys(i - 1).a2Y
            Next
        End Sub
    
    The lines in red indicate the problematic formula's
    Last edited: 9/4/07
  5. arno

    arno Administrator Staff Member FSDevConf team Resource contributor

    Joined:
    28/5/04
    Messages:
    21,300
    Country:
    netherlands
    Hi Sander,

    I should have some old code doing something similar here, but at the moment I can't really find it. I used it in my Bumpy tool to convert roads (lines) into polygons.
  6. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    It would be great if you could dig it up Arno! :D
  7. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Getting pretty close myself:
    [​IMG]
  8. Luis_Sá

    Luis_Sá Resource contributor

    Joined:
    16/9/04
    Messages:
    314
    Country:
    portugal
    Hello Sander,

    VTP1! To say the truth I never used them. About what you said:

    1) SBuilder was in fact programmed in VB6. Now I switched to VB2005 and I had to rewrite most of the graphics.

    2) There is no problem for me in adding the facility to compile for CFS. The only problem is that I "wrote SB for myself" and I have few comments and, may be, I am the only person that can read the source code. Even for the purpose of helping you with the geometry, I had to look several times to what I have writen to understand it. So, we can keep in touch regarding to adding such funcionality to SB206 (VB6!). I can send you relevant parts of the source code if you think it is useful.

    3) I am thinking in converting "lines with width" to polygons in SBuilder for FSX. The reason is that vectored lines with adjustable width are no longer supported. In my implementation (that I will start soon) I will have to check within the code the turns to the right and the turns to the left. When a new segment turns to the right I will use points 3 and 0 (see the drawing) on the left side and I have to solve what is upsetting you (eg to find a kind of intersection near points 0 and 1).

    So I will try to explain the algorithm in my previous post. Say that a line starts with points P1, followed by P2, P3 ...

    I start to get the vector P1_to_P2. This is vector U (coordinates UX and UY). Note that I normalize U so that it has a lenght of 1. Then I get a vector D with coordinates DX and DY. This vector is aligned with the segment P1 to P2 but the size is now equal to 1/2 of the width of the line.

    The part:

    PTS(0).X = PX0 - DY
    PTS(0).Y = PY0 + DX
    PTS(1).X = PX0 + DY
    PTS(1).Y = PY0 - DX

    is to find the points B and A (or PTS(0) and PTS(1)) as if I had created 2 vectors, DR and DL, from vector D.

    May be you now can fully understand the code (if you have not already done so!)

    Kind Regards,

    Luis

    [​IMG]
  9. Luis_Sá

    Luis_Sá Resource contributor

    Joined:
    16/9/04
    Messages:
    314
    Country:
    portugal
    Hi again

    Take notice that the points can not be very close or you will get something like the bottom line (widths of 5, 50 and 500, top to bottom)

    Regards, Luis

    [​IMG]
  10. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Hi Luis,
    1) Excellent news!
    2) No problem. I'll supply the assembly (dll) when I'm done, you can include with your project, and then you can copy the function you already have to "export SBX file" to send the filestream instead of to "filename" directly to the cf2autocoast.SBXInputfilestream, then call the routine cfs2autocoast.GenerateBGL and that's it! :) .NET rules! (it would be nice if you could please also allow your own LWM-mask save routine to create LWM1....saves us from having to de-compile-modify-recompile. This is something that would be too difficult for me to re-create)
    3) I'm going to bed now ;) I will look at the math again with a fresh mind another day! Thank you!
    Regards,
    -Sander.
  11. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
  12. rhumbaflappy

    rhumbaflappy Moderator Staff Member Resource contributor

    Joined:
    2/6/04
    Messages:
    2,502
    Country:
    us-wisconsin
    Hi Sander.

    Luis' original SBuilder used SCASM routines to make LWM and VTP2 polys and lines. SCASM never included the CFS2 Water ( LWM1 ) or VTP1... in fact the routines used were misnamed in SCASM, as I recall.

    SBuilderX was written in VB.NET 2.0, and doesn't make LWM or VTP of any variety.

    If the original Sbuilder was made to use BGLC, then it might be possible to include VTP1 and LWM1 code.

    Dick
  13. Luis_Sá

    Luis_Sá Resource contributor

    Joined:
    16/9/04
    Messages:
    314
    Country:
    portugal
    Hello,

    I saw your forum but could not register. To get (x4 y4) and (x5 y5) as
    in the picture of one of your readers, take this (non Pitagoras!)
    approach:

    1) Say the line is defined by center points P1 P2 P3 P4 ... When you start
    at point P1 and go to point P2 you have a 1/2 width to your left where you
    find point (x4 y4) and to your right where you find (x5 y5).

    2) I call D1 the unitary vector from P1 to P2; D2 the unitary vector from P2 to
    P3; D3 from P3 to P4 and so on ...

    3) I call DL1 the vector that has the size of 1/2 width of the line and that
    is obtained from D1 by rotating it 90 to the left.

    4) I call PL1 the point obtained by adding DL1 to P1 (point B in my
    hand writen figure). PL2 will be point 0 in the 3rd column of my figure.
    In general, point PLN (Point Left Nth) is the point that is 1/2 width
    to the left of the line at point PN

    5) By using a similar convention I name points PR1 PR2 PR3 ... the points
    that are on the right hand side and that are at a distance of 1/2 width from
    the center points P1 P2 P3 ...

    6) PL1 PL2 PL3 ... and PR1 PR2 PR3 can be easily obtained from my previous
    post.

    7) To obtain (x4 y4) you need to get the intersection between the lines

    PL1 + k1 D1 (where k1 is a scalar between -oo and +oo) and
    PL2 + k2 D2 (whre K2 is also any scalar).

    The intersecting point is determined by solving:

    PL1 + k1 D1 = PL2 + k2 D2

    Let me modify the names of (x4 y4) to PLL2 and (x5 y5) to PRR2 (2 because
    they are near P2). Using .X and .Y for the coordinates you have
    the equations

    PL1.X + k1 D1.X = PL2.X + k2 D2.X
    PL1.Y + k1 D1.Y = PL2.Y + k2 D2.Y

    If the lines really intersect and if they are not colinear there will
    be a unique solution for the real numbers k1 and k2. Once you get
    them you can either get your (x4, y4) as :

    x4 = PLL2.X = PL1.X + k1 D1.X
    y4 = PLL2.Y = PL1.Y + k1 D1.Y

    or as:

    x4 = PLL2.X = PL2.X + k2 D1.X
    y4 = PLL2.Y = PL2.Y + k2 D1.Y

    8) Point (x5 y5) is determined in an analogous way.

    Regards, Luis
  14. José

    José

    Joined:
    10/11/06
    Messages:
    490
    Country:
    brazil
    Only some math

    Hi,

    This is not programing sugestion, but another math approach for the problem.

    Knowing the points (x1,y1), (x2,y2) for Line1, one can write its slope, as

    m1 = (y2 - y1)/(x2 - x1)

    The same for Line2:

    m2 = (y3 - y2)/(x3 - x2)

    Those lines make an angle, whose bisector is the Line3 (not in your drawing)
    that contains the known intersection point (x2,y2) and its slope m3 could be
    find as a function from m1 and m2 slopes.

    The two searched points are over the Line3 (bisector), at a distance (d)
    from point (x2,y2), calculated by:

    d = (w/2)/sin(Teta/2)

    where Teta is the angle made by the lines 1 and 2, that could be known from
    their calculated slopes and w is the value given (distance between lines 1 and 2).

    As the solution for the distance is a second degree math expression, it returns
    the two searched points.

    I wait this could be implemented in programing easily.

    Regards,

    José
    Last edited: 10/4/07
  15. SdC

    SdC

    Joined:
    6/3/07
    Messages:
    35
    Country:
    netherlands
    Thank you all for the information and suggestions. I got it working (more or less) last night. The final algorithm is a "Frankenstein" from all suggested solutions :)

Share This Page