if i have 3 known points, and i know they are 3 of the 4 corners of a square, how do i calculate the 4th? these points are on a skewed square, where the square has been rotated in the x axis and then rotated in the z axis. It must be simple geometry, but i cant see it! any help or pointers to where i should look would be appreciated!
Are you working with a rectangle, a square (literally), or a cube?
Do some websearches on vector maths and/or matrix maths.
You're looking for a math formula that will mirror a point along a line (defined by 2 other points) if you're talking about a true square. Alternatively you could try looking for a math formula that will copy/translate a point by the distance/vector defined by the two other points - that would create a rectangle or a parallelogram - you would need to do a bit of calculation to make sure you're copying the right point in each case, though there's a 2/3 change you'll get it right at random
After that it's just a case of converting it into vba maths. Sorry I don't have time to go into greater detail, but I'd only be looking stuff up on the web anyway.
thanks guys, ive spent two days net reading, and have a solution, but not really the correct (math) one.
ive constructed a line from pt1 to pt2, then moved it to pt3. the end pt of this line now gives me the co-ordinates i need.
if ive read correctly i think the cross product of a vector is at right angles to the original vector. the vector is the difference between pt1 and pt2.
ill keep reading!
Here is one solution. Look at the attached picture to see the result. 4th point is cross point of two vectors. It's easy to calculate direction angle between first and third point of the input line and based on this angle and length of the side of the square you can calculate the 4th point. We will have 4 different cases depending on wich quadrant lies the vector between 1st and 3rd point.
Option Explicit Public Const PI = 3.14159265358979 Sub testche() Dim line As AcadLWPolyline '' input line (constructed by 3 points) Dim obj As AcadObject Dim var As Variant On Error Resume Next ThisDrawing.Utility.GetEntity obj, var, "Select line: " If (TypeOf obj Is AcadLWPolyline) Then Set line = obj line = modifyLine(line) End If End Sub '' this method returns closed polyline Private Function modifyLine(inputLine As AcadLWPolyline) As AcadLWPolyline Dim line As AcadLWPolyline: Set line = inputLine Dim pnt1 As Variant: pnt1 = line.Coordinate(0) '' first vertex Dim pnt2 As Variant: pnt2 = line.Coordinate(1) '' second vertex Dim pnt3 As Variant: pnt3 = line.Coordinate(2) '' third vertex Dim pnt4(0 To 1) As Double '' fourth vertex Dim s As Double: s = getDistance(pnt1(1), pnt1(0), pnt2(1), pnt2(0)) Dim r As Double: r = 50 '' this is always 45 degrees (50 gon)
Dim a1 As Double: a1 = getDirectionAngle(pnt1(1), pnt1(0), pnt3(1), pnt3(0)) Dim a2 As Double: a2 = getDirectionAngle(pnt1(1), pnt1(0), pnt2(1), pnt2(0)) '' we have four different cases according to rotation of the input line If a1 < 200 Then If a1 < a2 Then a1 = a1 - r Else a1 = a1 + r End If Else If a1 < a2 Then a1 = a1 - r Else a1 = a1 + r End If End If '' coordinates of the 4th vertex pnt4(1) = pnt1(1) + s * Math.Cos(a1 * PI / 200) pnt4(0) = pnt1(0) + s * Math.Sin(a1 * PI / 200) line.AddVertex 3, pnt4 line.Closed = True line.Update modifyLine = line End Function Private Function getDistance(ByVal x1 As Double, ByVal y1 As Double, ByVal x2 As Double, ByVal y2 As Double) getDistance = Math.Sqr(Math.Abs(x2 - x1) ^ 2 + Math.Abs(y2 - y1) ^ 2) End Function Private Function getDirectionAngle(ByVal x1 As Double, ByVal y1 As Double, ByVal x2 As Double, ByVal y2 As Double) As Double Dim alfa As Double If x2 - x1 > 0 And y2 - y1 > 0 Then alfa = Math.Atn(Abs(y2 - y1) / Abs(x2 - x1)) * 200 / PI ElseIf x2 - x1 < 0 And y2 - y1 > 0 Then alfa = Math.Atn(Abs(y2 - y1) / Abs(x2 - x1)) * 200 / PI alfa = 200 - alfa ElseIf x2 - x1 < 0 And y2 - y1 < 0 Then alfa = Math.Atn(Abs(y2 - y1) / Abs(x2 - x1)) * 200 / PI alfa = 200 + alfa ElseIf x2 - x1 > 0 And y2 - y1 < 0 Then alfa = Math.Atn(Abs(y2 - y1) / Abs(x2 - x1)) * 200 / PI alfa = 400 - alfa ElseIf x2 - x1 = 0 And y2 - y1 > 0 Then alfa = 100 ElseIf x2 - x1 < 0 And y2 - y1 = 0 Then alfa = 200 ElseIf x2 - x1 = 0 And y2 - y1 < 0 Then alfa = 300 ElseIf x2 - x1 > 0 And y2 - y1 = 0 Then alfa = 0 End If getDirectionAngle = alfa End Function