根据中心点创建钟针坐标

问题描述 投票:0回答:4

我正在尝试根据中心点创建钟针坐标(我已经有了中心点)。这是我到目前为止的代码:

我的 VB.NET 表单上有:

http://i58.tinypic.com/3ehwl.png

Private Sub CreateClockPoints(ByVal centerPt As VISIPoint)
        Dim vPtD As New VISIPoint

        If rbn1.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y + Util.convertVal(1.5, 1, 2), centerPt.Z)
        ElseIf rbn2.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn3.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn4.Checked Then
            vPtD.Put(centerPt.X + Util.convertVal(1.5, 1, 2), centerPt.Y, centerPt.Z)
        ElseIf rbn5.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn6.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn7.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y - Util.convertVal(1.5, 1, 2), centerPt.Z)
        ElseIf rbn8.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn9.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn10.Checked Then
            vPtD.Put(centerPt.X - Util.convertVal(1.5, 1, 2), centerPt.Y, centerPt.Z)
        ElseIf rbn11.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        ElseIf rbn12.Checked Then
            vPtD.Put(centerPt.X, centerPt.Y, centerPt.Z)
        End If

    End Sub

中心到时钟点的距离必须为1.5。

如你所见,我已经算出了 1、4、7 和 10。我不确定 2、3、5、6、8、9、11 和 12 的公式是什么。如果您需要任何其他信息,请告诉我,谢谢。

c# vb.net
4个回答
2
投票

这看起来像是一项家庭作业,所以我会剧透一些答案,而且我不会给你实际的代码。

假设您已经学过三角学并知道单位圆的公式。

您想要的偏移 x 和 y 的公式可以根据钟针的角度(我们称之为

theta
)来确定。 因为一圈有12小时,而且一圈是360度,
theta = hours * 360 / 12
。 然后你可以得到:

x = 1.5 * sin (θ)

y = -1.5 * cos(θ)


0
投票

正常的时钟应该是上面有12个,下面有6个。

要获取像素的坐标,您可以使用旋转矩阵将矢量从 0° 旋转到 359°

!这不是真正的 vb.net 代码!

function rotate(ByVal p as Point2D,ByVal angle as Single) as Point2D
    Single X = p.X * cos(angle) - p.Y * sin(angle)
    Single Y = p.X * sin(angle) + p.Y * cos(angle)
    return new Point2D(X,Y)
end function

请注意,旋转矩阵将逆时针旋转,因此您应该取反角度。您应该在角度(以度为单位)和您的时间之间创建某种映射

这可以通过将时间除以 12 并乘以 360° 来完成

function getAngleForTime(ByVal time as Integer) as Single
    Dim scale = time / 12
    return scale * 360
end function

此功能使 12:00 变为 360° 和 3:00 变为 90°

现在您可以旋转长度为 1.5 的向量:

Dim time as Integer = 4
Dim angle as Single = getAngleForTime(time)
Dim p as new Point2D(1.5,0)
Dim p_r as Point2D = rotate(p, -angle) 'use negative angle here !

现在你有了一个旋转的向量。要获得点的最终坐标,您必须将中心点的坐标添加到向量中:

Dim final_point as Point2D
final_point.X = p_r.X + center_point.X
final_point.Y = p_r.Y + center_point.Y

我希望这对您有帮助。我没有视觉工作室来测试这段代码。请根据您的示例调整此代码。抱歉我的英语不好。


0
投票

您将需要使用一些基本的三角函数来确定 X、Y 坐标。 鉴于有 12 个时钟点,您可以使用此函数确定时钟上任意点的 X、Y 坐标。 请注意,这将返回标准笛卡尔平面的 X,Y 坐标。 您必须转换为 .Net 坐标系才能绘图。

'Returns the X,Y coordinate of a point on a clock given a center point and radius.  
'Clock point 0 = 12:00, 1 = 1:00, etc.
Private Function getClockPoint(center As PointF, radius As Double, clockPoint As Integer) As PointF
    Dim angle As Double = clockPoint * (2.0 * Math.PI) / 12.0

    Dim x As Single = center.X + CSng(radius * Math.Sin(angle))
    Dim y As Single = center.Y + CSng(radius * Math.Cos(angle))

    Return New PointF(x, y)
End Function

0
投票

这是我绘制时针、分针和秒针的 C# 代码,它扩展了其他一些答案,我希望它有用。 注意我使用 SixLabors.ImageSharp 作为图形,您可能需要更新 Pen 和 DrawLine 线。 在我的程序中,它每秒循环一次。

// Create the Pens
Pen penHour = new SolidPen(new SolidBrush(Color.White), 4);
Pen penMinute = new SolidPen(new SolidBrush(Color.White), 4);
Pen penSecond = new SolidPen(new SolidBrush(Color.Red), 2);
                
// The centre point
PointF centre = new PointF(100, 200);

// The hand lengths
const double hourlength = 60;
const double minutelength = 80;
const double secondlength= 83;
                        
//.
//.
//.

// Date time to show
DateTime now = DateTime.Now;

// Get the Angles
double thetaHour = (((now.Hour%12) + (now.Minute/60.0)) * 360.0) / 12.0;
double thetaMinute = ((now.Minute + now.Second/60.0) * 360.0) / 60.0;
double thetaSecond = (now.Second * 360.0) / 60.0;

// Convert to Radians
thetaHour    = Math.PI * thetaHour / 180.0;
thetaMinute    = Math.PI * thetaMinute / 180.0;
thetaSecond    = Math.PI * thetaSecond / 180.0;
        
// Calculate end points
PointF hour = new PointF((float)(centre.X + hourlength * Math.Sin(thetaHour)),
            (float)(centre.Y - hourlength * Math.Cos(thetaHour)));

PointF minute = new PointF((float)(centre.X + minutelength * Math.Sin(thetaMinute)),
            (float)(centre.Y - minutelength * Math.Cos(thetaMinute)));

PointF second = new PointF((float)(centre.X + secondlength * Math.Sin(thetaSecond)),
            (float)(centre.Y - secondlength * Math.Cos(thetaSecond)));
                        
// Draw the lines using your Graphics library and pens created
imageContext.DrawLine(penHour, [centre, hour]); // Note this uses SixLabors.ImageSharp
imageContext.DrawLine(penMinute, [centre, minute]); 
imageContext.DrawLine(penSecond, [centre, second]); 
© www.soinside.com 2019 - 2024. All rights reserved.