代码之家  ›  专栏  ›  技术社区  ›  Todd Main

计算WPF或SVG图形的坐标点[闭合]

  •  2
  • Todd Main  · 技术社区  · 8 年前

    我正在寻找以下关于如何计算A、B和C的提示/建议 和/或 SVG 图解的这与 another question 我只是问,但不是用笔划 LineJoin Miter Path 具有 LineTo ArcTo

    我想弄清楚的是: arrow

    很抱歉,我对三角函数几乎一无所知。我确实试着去查cos,sin和tan,但都记不住。我到处看了看,找不到足够直截了当的东西来处理我正在寻找的帮助。

    • 我总是知道“笔划厚度”(箭头的两个斜率)。在这种情况下,0.28英寸。
    • ArcTo公司 从…起 A B
    • 这个 MoveTo

    1 回复  |  直到 8 年前
        1
  •  1
  •   Todd Main    8 年前

    近似结果,最好在程序中计算,以获得更高的精度。

    A = 0.0178, 1.4717
    B = 0.2622, 1.6083
    C = 0.84,   0.5739
    

    Close up of Circle

    左下圆的粗略特写

    r = 0.14 (0.28/2)
    w,h = 1.64
    

    圆的中心( D )位于 r, h-r . 箭头的尖端( T )是 w/2,0 . 自左切线( A T A. D ,我们可以确定角度 a1 (双方 T )以下方式:

    a1 = acos(r / H)
    

    H D T ,在这种情况下

    H = |D - T|
    H = sqrt(0,7² + 1,54²)
    H = 1,6916...
    

    所以 85.25273° . 以及从水平到 DT a2 ):

    a2 = atan(DTy / DTx)
    a2 = atan((1.54 - 0.0) / (0.84 - 0.14))
    a2 = atan(1.54 / 0.7)
    a2 = 65.56°
    

    所以我们的横轴(X)和 DA

    a = a1+a2
    a = 150.81273°
    

    现在我们知道了距离( r )还有角度( a )来自 A. B

    dx = cos(a) * r
    dy = sin(a) * r
    
    dx = 0.1222
    dy = 0.0683
    

    你现在要做的就是从中心加减( D )你有 B

    A = 0.0178, 1.4717
    B = 0.2622, 1.6083
    

    Determining C

    现在开始 C . 既然我们想要 AT BC 为了平行,我们可以使用角度 我们已经计算确定 不列颠哥伦比亚省 x 之间的差值X C , y b 不列颠哥伦比亚省

    b = a - 90°
    b = 60.81273°
    

    我们已经知道 C ( Cx )因为我们希望它在中心。

    Cx = w/2
    Cx = 0.84
    x = Cx - Bx
    x = 0.84 - 0.2622
    x = 0.5778
    

    .

    tan(b) = y/x
    y = tan(b) * x
    y = 1.79022 * 0.5778
    y = 1.0344
    
    Cy = By - y
    Cy = 1.6083 - 1.0344
    Cy = 0.5739
    

    把这些放在一起,你就会

    C = 0.84, 0.5739
    

    <SVG Width="84px" height="168px">
        <g transform="scale(100)">
            <Path d="M 0,0 L 0.84,0 L 0.84,1.68 L 0,1.68 Z" fill="#f6be98"/>
            <Path d="M 0.84,0 L 0.0178 1.4717 A 0.14,0.14 0 0 0 0.2622 1.6083 L 0.84 0.5739 Z" fill="#4472c4" />
        </g>
    </SVG>

    下面的编辑是托德·梅因的原创海报。以下是Manfred Radlwimmer的精彩代码的实现。它在VB中。NET并使用XML文字。它没有任何分号。如果是这样的话,在这个时代,允许在VB中注释代码,它就会有注释。它在原始帖子中创建了图片,并附加到此答案中,供其他人根据需要查看和使用。

        Private Sub Main()
            Dim diameter = 20
            Dim bb As New Size(120, 120)
            Dim pathData = RenderedArrowheadPath(diameter, bb)
            Dim svg As String = RenderedSVG(bb, pathData).ToString
            Console.WriteLine(svg)
            Console.ReadLine()
        End Sub
        Private Function RenderedSVG(bb As Size, pathData As String) As XElement
            Return <SVG width=<%= bb.Width.ToString & "px" %> height=<%= bb.Height.ToString & "px" %>>
                       <g>
                           <Path d=<%= $"M0,0 L{bb.Width},0 L{bb.Width},{bb.Height} L0,{bb.Height} Z" %> fill="#f6be98"/>
                           <Path d=<%= pathData %> fill="#4472c4"/>
                       </g>
                   </SVG>
        End Function
        Private Function RenderedArrowheadPath(diameter As Double, bb As Size) As String
    
            Dim radius = diameter / 2
            Dim Distance = New Point(radius, bb.Height - radius)
            Dim Tip = bb.Width / 2
            Dim DT = New Point(bb.Height - radius, (bb.Width / 2) - radius)
            Dim Hypotenuse = Math.Sqrt(DT.X ^ 2 + DT.Y ^ 2)
            Dim angle1 = Math.Acos(radius / Hypotenuse)
            Dim angle2 = Math.Atan(DT.X / DT.Y)
            Dim angle = angle1 + angle2
            Dim dx = Math.Cos(angle) * radius
            Dim dy = Math.Sin(angle) * radius
    
            Dim PointA = New Point(Distance.X + dx, Distance.Y - dy)
            Dim PointB = New Point(Distance.X - dx, Distance.Y + dy)
    
    
            Dim b = angle - (90 / (180 / Math.PI)) 
            Dim Cx = bb.Width / 2
            Dim Bx = PointB.X
            Dim X = Cx - Bx
            Dim Y = Math.Tan(b) * X
            Dim Cy = PointB.Y - Y
            Dim PointC = New Point(Cx, Cy)
    
    
            Dim PointBInv = New Point(bb.Width - (Distance.X - dx), Distance.Y + dy)
            Dim PointAInv = New Point(bb.Width - (Distance.X + dx), Distance.Y - dy)
    
            Return $"M{Tip},0 L{PointA.X},{PointA.Y} A{radius},{radius} 0 0 0 {PointB.X},{PointB.Y} L{PointC.X},{PointC.Y} L{PointBInv.X},{PointBInv.Y} A{radius},{radius} 0 0 0 {PointAInv.X},{PointAInv.Y}  Z"
        End Function
    

    <SVG width="120px" height="120px">
      <g>
        <Path d="M0,0 L120,0 L120,120 L0,120 Z" fill="#f6be98" />
        <Path d="M60,0 L1.27003148173183,105.122741582605 A10,10 0 0 0 18.7299685182682,114.877258417395 L60,41.0066440783012 L101.270031481732,114.877258417395 A10,10 0 0 0 118.729968518268,105.122741582605  Z" fill="#4472c4" />
      </g>
    </SVG>