Android Question Draw Canvas Lines (Angles) with Angle Numbers Each End

Azhar

Active Member
Licensed User
Longtime User
Hi All,

My app draws two lines (shaded rectangles) to represent two Airport Runways exactly to the angles that the user entered.
I just need to place the runway markers at each end to represent the angle each runway is pointing to.
I start off with drawing a shaded long and thin rectangle and their respective angles are configured through the app (so each long/thin rectangle is rotated)
My problem now is knowing how to place text markers at each end and preferably rotate and align the text runway markers along the axis of their respective runway.
Can anyone give me an idea of how to locate the ends of each runway?

part of drawing the runways:
    'setup canvas for the visualise runway/wind
    Dim cvs As Canvas
    cvs.Initialize(pnlVisualise)
    Dim rwy1 As Rect
    Dim rwy2 As Rect
    Dim rwy1Angle, rwy2Angle As Int
   
    rwy1Angle = common.Val(lblRWY1L.Text) * 10
    rwy2Angle = common.Val(lblRWY2L.Text) * 10

    rwy1.Initialize(200dip,100dip,220dip,350dip)
    cvs.DrawRectRotated(rwy1,Colors.Gray,True,5,rwy1Angle)
   
    rwy2.Initialize(200dip,100dip,220dip,350dip)
    cvs.DrawRectRotated(rwy2,Colors.DarkGray,True,5,rwy2Angle)
    Activity.Invalidate
   
End Sub
 

emexes

Expert
Licensed User
Something like this, maybe:
B4X:
Dim RunwayMiddleX As Int = (100 + 220) / 2
Dim RunwayMiddleY As Int = (200 + 350) / 2

Dim RunwayRadius As Int = (220 - 100 + 350 - 200) / 2 / 2
Dim LabelRadius As Int = RunwayRadius + 30    'eg labels 30 pixels past end of runway

Dim RunwayAngleDegrees = RunwayNumber * 10
Dim RunwayAngleRadians = RunwayAngleDegrees / 180 * 3.14159

Dim LabelX As Int = RunwayMiddleX + Sin(RunwayAngleRadians) * LabelRadius - half of label width?
Dim LabelY As Int = RunwayMiddleY + Cos(RunwayAngleRadians) * LabelRadius - half of label height?

edit:
1/ might have to add 180 degrees to runway angle to get label at the correct (incoming) end
2/ will leave it to you to rotate the labels; trick might be to put them on a panel and then rotate the panel

epiphany:
put the runway and its runway number labels onto a panel, and then rotate the panel - the runway numbers will rotate with the runway - magic!

yikes:
you don't even need a canvas, can all be done with Designer widgets
 
Last edited:
Upvote 0

emexes

Expert
Licensed User




B4X:
Private Label1 As Label
Private Label2 As Label
    
Private Pane1 As B4XView
    
Dim Timer1 As Timer
Dim RunwayAngle As Int

Timer1.Initialize("Timer1", 100)
Timer1.Enabled = True

Sub Timer1_Tick
    
    RunwayAngle = RunwayAngle + 1
    If RunwayAngle >= 360 Then
        RunwayAngle = RunwayAngle - 360
    End If
    
    Dim RunwayNumber As Int = RunwayAngle / 10

    Label2.Text = NumberFormat(RunwayNumber, 2, 0)
    Label1.Text = NumberFormat((RunwayNumber + 18) Mod 36, 2, 0)
    
    Pane1.Rotation = RunwayAngle
    
End Sub
 
Upvote 0

Azhar

Active Member
Licensed User
Longtime User
This is absolutely fantastic Emexes.
I really can't thank you enough for your expertise.
I'll give it a whirl now.

Azhar
 
Upvote 0

emexes

Expert
Licensed User
This is absolutely fantastic
Yeah, I was pretty chuffed with how well it turned out too. ?

Later thoughts were:
1/ make the runways gray or black(er) like yours, to match color of concrete or asphalt
2/ make runway numbers to be white on a black panel, like real runway numbers
3/ rotate top runway number 180 degrees to face incoming landings
4/ maybe even move the numbers onto the runway (but perhaps they'll then be too small)
5/ use the same panel-rotation trick to point a windsock or weathervane in the wind direction
6/ use Pane3.Visible = False to hide second runway

 
Last edited:
Upvote 0

Azhar

Active Member
Licensed User
Longtime User
I know this is a silly question but how do I initialize Pane1?

EDIT> Duh It's okay. Sussed it out now. This is great
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
how do I initialize Pane1?
Pane1 should be initialized automatically by LoadLayout.

I did it in B4J but I know that B4A has the same ability to rotate panels, just using slightly different words (eg Pane vs Panel).

This is great
Yeah, my eyes nearly fell out when @klaus showed me panel rotations.
 
Last edited:
Upvote 0

Azhar

Active Member
Licensed User
Longtime User
I'll take a look at those samples, but this is what I have so far...



The user enters the runway co-ordinates on the main runway first and I basically shaded that runway darker grey.
The little wind arrow was basically a fontawesome icon in a label as B4XView so that I could rotate it as per the panels (Runways).
What I might do is fill the runway panels with a generic runway .jpeg or something and see how that goes. That'll give a realistic image for sure.
Cool hey?
Thanks so much
 
Upvote 0

emexes

Expert
Licensed User
Looks great. Perhaps highlight the suggested runway a bit more, to minimize thinking time. Although maybe that's just me, not being a pilot.

 
Upvote 0

Azhar

Active Member
Licensed User
Longtime User
Looks great. Perhaps highlight the suggested runway a bit more, to minimize thinking time. Although maybe that's just me, not being a pilot.

View attachment 96917
Yeah you're right because the more time you spend looking down at your phone, the greater chances are that your plane is in a very peculiar attitude when you look back up!
 
Upvote 0

emexes

Expert
Licensed User
Lol it'd be fairly simple to animate that arrow too. Let's say to move ArrowLabel up your unrotated runway, from y = 285 at the bottom to y = 93 at the top, then you'd set up a say 50 ms timer ArrowTimer to call:
B4X:
Sub ArrowTimer_Tick

    Dim ArrowSpeed = -7    'how many pixels to move arrow each 50 ms

    ArrowLabel.Y = ( (ArrowLabel.Y - 93 + ArrowSpeed) Mod (285 - 93 + 1) ) + 93

    'or perhaps the simpler
    'Dim Y As Int = ArrowLabel.Y + ArrowSpeed
    'If Y < 93 Then
    '    ArrowLabel.Y = 285
    'ElseIf Y > 285 Then
    '    ArrowLabel.Y = 93
    'Else
    '    ArrowLabel.Y = Y
    'End If

End Sub
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Speaking of gurus... back when I was calculating areas on a sphere, this guy gave the absolute best explanation of it out of all that I found. Talk about an unexpected diamond in the rough.

 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…