מציאת נקודה על פי מעלות זוית
-
הנה שיפצתי את הקוד, כעת הוא עובד מצויין אבל רק אם החלון מרובע אבל אם החלון מלבני הנקודה האדומה מתנהגת בצורה מוזרה במעלות 0, 90, 180 ו 270 נפגשת עם הקשת ובמעלות אחרות לא. מדוע?
Public Class Form1 ' Create start and sweep angles on ellipse. Dim startAngle As Single = 0.0F Dim sweepAngle As Single = 0.0F Function toRadians(ByVal angle As Single) As Single Return CSng(angle * (Math.PI / 180)) End Function Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove 'שינוי תחילת הקשת על פי הסמן 'startAngle = GetAngle(Me.ClientSize.Width \ 2, Me.ClientSize.Height \ 2, e.Location.X, e.Location.Y) 'שינוי אורך הקשת על פי הסמן sweepAngle = GetAngle(Me.ClientSize.Width \ 2, Me.ClientSize.Height \ 2, e.Location.X, e.Location.Y) - startAngle Me.Invalidate() End Sub Function GetAngle(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single) As Single Dim xDiff As Single = (x1 - x2) Dim yDiff As Single = (y1 - y2) Return (CSng(Math.Atan2(yDiff, xDiff)) * CSng(180 / Math.PI) + 180) End Function Private Function GetCoordinate(ByVal angle As Single) As Point Dim Radian As Single = toRadians(angle) Dim x As Single = (Me.ClientSize.Width \ 2) + CSng(Math.Cos(Radian) * (Me.ClientSize.Width \ 2)) Dim y As Single = (Me.ClientSize.Height \ 2) + CSng(Math.Sin(Radian) * (Me.ClientSize.Height \ 2)) Return New Point(x - 6, y - 6) End Function Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint ' Create pen. Dim blackPen As New Pen(Color.Black, 3) ' Create rectangle to bound ellipse. Dim rect As New Rectangle(0, 0, Me.ClientSize.Width, Me.ClientSize.Height) ' Draw arc to screen. e.Graphics.DrawArc(blackPen, rect, startAngle, sweepAngle) e.Graphics.FillEllipse(Brushes.Red, New Rectangle(GetCoordinate(startAngle + sweepAngle), New Size(12, 12))) End Sub Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.Height = Me.Width * 2 End Sub End Class
פורסם במקור בפורום CODE613 ב15/08/2013 19:03 (+03:00)
-
כל הנוסחה מתבססת על תכונות מרובע ועיגול, לא מלבן ואליפסה.
במקרה של מלבן ואליפסה תתייחס כאילו זה מרובע כאשר הצלע/קוטר שוה לצלע הקטן שבמלבן, ואת תוצאת הXY תמיר למלבן לפי היחס.
לדוגמא מלבן בגודל 20:10, אתה מתייחס כאילו הוא 10:10 וכאשר מתקבלת לך תוצאת XY כזאת: 5,7 אתה מכפיל את ה5 ביחס בין הצלעות (הקטן לחלק לגדול) במקרה זה 2.פורסם במקור בפורום CODE613 ב18/08/2013 11:14 (+03:00)
-
שיפצתי לפי דבריך את הפקודה GetCoordinate
וזה מה שיצא, אבל זה לא עובד.Private Function GetCoordinate(ByVal angle As Single) As Point Dim Radian As Single = toRadians(angle) Dim Dis As Integer Dim WidthIsLarge As Boolean If Me.ClientSize.Width > Me.ClientSize.Height Then Dis = Me.ClientSize.Height / 2 WidthIsLarge = True Else Dis = Me.ClientSize.Width / 2 WidthIsLarge = False End If Dim x As Single = (Me.ClientSize.Width / 2) + CSng(Math.Cos(Radian) * Dis) Dim y As Single = (Me.ClientSize.Height / 2) + CSng(Math.Sin(Radian) * Dis) If WidthIsLarge = True Then x = x * (Me.ClientSize.Height / Me.ClientSize.Width) Else y = y * (Me.ClientSize.Width / Me.ClientSize.Height) End If Return New Point(x - 6, y - 6) End Function
פורסם במקור בפורום CODE613 ב18/08/2013 13:14 (+03:00)
-
@דוד ל.ט.
כל הנוסחה מתבססת על תכונות מרובע ועיגול, לא מלבן ואליפסה.
במקרה של מלבן ואליפסה תתייחס כאילו זה מרובע כאשר הצלע/קוטר שוה לצלע הקטן שבמלבן, ואת תוצאת הXY תמיר למלבן לפי היחס.
לדוגמא מלבן בגודל 20:10, אתה מתייחס כאילו הוא 10:10 וכאשר מתקבלת לך תוצאת XY כזאת: 5,7 אתה מכפיל את ה5 ביחס בין הצלעות (הקטן לחלק לגדול) במקרה זה 2.זה בדיוק מה שהוא כתב.
התוצאה זה יחס והוא מכפיל את היחס באורך וברוחב.
כלומר אם זה 5,7 אז התוצאה ב cos וב sin זה 0.2 , 0 ואז ההמרה תהיה
0.2 * 5 + 5 = 7
0 * 10 * 10 = 10 .וזה יוצא בדיוק אותו חשבון.
כלומר החשבון הראשון הוא בסדר גמור.
מה אני רואה בתמונה שהעיגול ממשיך את המגמה של הקו כלומר הוא לא סוטה מהמגמה.
זה נראה שיש לו נתון אחר של מעלות.
פורסם במקור בפורום CODE613 ב18/08/2013 14:58 (+03:00)
-
בשבילך דוגמא בjs.
פורסם במקור בפורום CODE613 ב18/08/2013 22:27 (+03:00)
-
זה דוגמא יותר טובה.
תזיז את העכבר.
תשים לב מה ההבדל בין הדוגמא הראשונה לשניה.
זה התשובה לשאלה שלך.
פורסם במקור בפורום CODE613 ב18/08/2013 23:21 (+03:00)
-
זה דוגמא יותר טובה.
תזיז את העכבר.
תשים לב מה ההבדל בין הדוגמא הראשונה לשניה.
זה התשובה לשאלה שלך.
מרשים ביותר!
פורסם במקור בפורום CODE613 ב19/08/2013 11:02 (+03:00)
-
Return (CType(Math.Atan2(yDiff, xDiff), Single) * CType((180 / Math.PI), Single) + 180)
בשורה הזאת יש בעיה.
אין התיחסות לצורה מלבנית.
היחס צריך להיות כמו שכתבתי בדוגמא.
drew( Math.atan2( (e.clientY - 200) / 2 , e.clientX - 100 ));
שזה בעצם ההבדל בין שניהם.
ההבדל הוא שאם אתה עוקב עם העכבר צמוד אז בדוגמא הראשונה רואים שהעכבר עושה את אותו פיספוס כמו שיש לך בתוכנה.
בדוגמא השניה החשבתי את היחס ב atan2 בצורה שכתבתי את זה
(e.clientY - 200) / 2
אפשר לכתוב פשוט ככה
(e.clientY - 200) * (100/200)
ואז אתה מודד את הזוית בצורה יחסית.
מה שכן לא ברור לי למה הפונקציה שמציירת אצלך את הקשת מקבלת מעלות ולא ראדיאנים. כמו שמקובל.
יכול להיות שאם תעשה שני מדידות
אחד עם יחס ואחד בלי זה יפתור אצלך את הבעיה.פורסם במקור בפורום CODE613 ב19/08/2013 13:19 (+03:00)
-
תודה רבה רבה!!!
הנה הקוד הסופי:
אני רוצה לציין שהיתי מוכרח לעשות שתי פונקציות שממירות את מיקום העכבר למעלות וכמו שאמרת, אחת עבור הקשת ואחת עבור הכדור האדום, וזאת משום שכאשר הכנסתי לפונקציה את ההתיחסות לצורת מלבן אז הכדור האדום אכן היה תמיד צמוד לעכבר אבל הקשת לא!! ולכן לקשת השארתי את הפונקציה הישנה ולכדור האדום פונקציה עם התיחסות למלבן.
אני משער שהפונקציה שמציירת את הקשת מוסיפה את ההתיחסות למלבן מעצמה ולכן זה משבש אותה.Public Class Form1 ' Create start and sweep angles on ellipse. Dim startAngle As Single = 40.0F Dim sweepAngle As Single = 0.0F Dim RedEllipseAngle As Single Public Sub New() ' This call is required by the designer. InitializeComponent() ' Add any initialization after the InitializeComponent() call. Me.Height = Me.Width * 2 End Sub Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint ' Create pen. Dim blackPen As New Pen(Color.Black, 3) ' Create rectangle to bound ellipse. Dim rect As New Rectangle(0, 0, Me.ClientSize.Width, Me.ClientSize.Height) ' Draw arc to screen. e.Graphics.DrawArc(blackPen, rect, startAngle, sweepAngle) e.Graphics.FillEllipse(Brushes.Red, New Rectangle(GetCoordinate(RedEllipseAngle), New Size(12, 12))) End Sub Private Sub Form1_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove 'שינוי תחילת הקשת על פי הסמן 'startAngle = GetAngle(Me.ClientSize.Width/ 2, Me.ClientSize.Height / 2, e.Location.X, e.Location.Y) 'שינוי אורך הקשת על פי הסמן sweepAngle = GetAngle(Me.ClientSize.Width / 2, Me.ClientSize.Height / 2, e.Location.X, e.Location.Y) - startAngle RedEllipseAngle = GetAngle2(Me.ClientSize.Width / 2, Me.ClientSize.Height / 2, e.Location.X, e.Location.Y) Me.Invalidate() End Sub Function GetAngle(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single) As Single Dim xDiff As Single = (x1 - x2) Dim yDiff As Single = (y1 - y2) Return (CSng(Math.Atan2(yDiff, xDiff)) * (180 / Math.PI) + 180) End Function Function GetAngle2(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single) As Single Dim xDiff As Single = ((x1 - x2) * (Me.ClientSize.Height / Me.ClientSize.Width)) Dim yDiff As Single = (y1 - y2) Return (CSng(Math.Atan2(yDiff, xDiff)) * (180 / Math.PI) + 180) End Function Private Function GetCoordinate(ByVal angle As Single) As Point Dim Radian As Double = toRadians(angle) Dim x As Single = (Me.ClientSize.Width / 2) + CSng(Math.Cos(Radian) * (Me.ClientSize.Width / 2)) Dim y As Single = (Me.ClientSize.Height / 2) + CSng(Math.Sin(Radian) * (Me.ClientSize.Height / 2)) Return New Point(x - 6, y - 6) End Function Function toRadians(ByVal angle As Single) As Double Return angle * (Math.PI / 180) End Function End Class
פורסם במקור בפורום CODE613 ב19/08/2013 13:42 (+03:00)