Point of two intersecting lines at 90 degree Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
mast4rwang
Posts: 141
Joined: 19 Jul 2017, 09:59

Point of two intersecting lines at 90 degree

Post by mast4rwang » 18 Sep 2017, 06:42

Hello guys, I am trying to write a script which asks to input A(x;y) and B(x1;y1) and it displays the end result, which is coordinates of c(a;b). I can get lengths of lines so easily because they make right triangles, but when it comes to coordinates I am lost on what to do :oops:
Could someone help me out?

This is an illustration:
Spoiler

teadrinker
Posts: 4295
Joined: 29 Mar 2015, 09:41
Contact:

Re: Point of two intersecting lines at 90 degree  Topic is solved

Post by teadrinker » 18 Sep 2017, 17:59

Hi, mast4rwang. It's just school mathematics. :)

We have the line passing through two points (x1, y1) and (x2, y2), and point B(x3, y3)

The general equation of line with two points is
(y1 - y2)*X + (x2 - x1)*Y + (x1*y2 - x2*y1) = 0
In our case x2 and y2 are equal 0, therefore
y1*X - x1*Y = 0

If x1 equal 0, then the intersection point x = 0, y = y3.
If y1 equal 0, then x = x3, y = 0.

Else
Y = (y1/x1)*X
y1/x1 is the line's slop, hence the perpendicular's slop is -x1/y1
Then the perpendicular's equation is
Y - y3 = -x1/y1(X - x3)

Now to get the intersection point we need to solve the set of equations:
Y - y3 = -x1/y1(X - x3)
Y = (y1/x1)*X

(y1/x1)*X - y3 = -x1/y1(X - x3)
-(y1**2/x1**2)*X + y1/x1*y3 = X - x3
X + (y1**2/x1**2)*X = y1/x1*y3 + x3

X = (y1/x1*y3 + x3)/(y1**2/x1**2 + 1)
Y = (y1/x1)*X

Code: Select all

coords := GetIntersection( {x: -2, y: 2}, {x: 1, y: 3} )

MsgBox, % "X = " . coords.x . A_Tab . "Y = " . coords.y

GetIntersection(point1, point2)  {
   if (point1.x = 0)
      Return {x: 0, y: point2.y}
   
   if (point1.y = 0)
      Return {x: point2.x, y: 0}
   
   X := (point1.y/point1.x * point2.y + point2.x)/( (point1.y**2)/(point1.x**2) + 1 )
   Y := point1.y/point1.x * X
   
   Return {x: X, y: Y}
}

mast4rwang
Posts: 141
Joined: 19 Jul 2017, 09:59

Re: Point of two intersecting lines at 90 degree

Post by mast4rwang » 19 Sep 2017, 11:10

Cheers, teadrinker!

BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Point of two intersecting lines at 90 degree

Post by BoBo » 19 Sep 2017, 12:17

:o :o :o No doubt about that: "It's tea time!" :thumbup:


mast4rwang
Posts: 141
Joined: 19 Jul 2017, 09:59

Re: Point of two intersecting lines at 90 degree

Post by mast4rwang » 19 Sep 2017, 14:11

Well, one thing is certain: Teadrinker, you got a new fan 8-)

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 29 Nov 2021, 21:47

@teadrinker

How would I check if these two lines intersect and if so, where?

Code: Select all

Line1 := { X1: 100 , Y1: 100 , X2: 300 , Y2: 80 }
Line2 := { X1: 250 , Y1: 50 , X2: 500 , Y2: 350  }


User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 29 Nov 2021, 23:11

I got it sorted out thanks.

Code: Select all

LineIntercept( p0 , p1 , p2 , p3 ){
	A1 := p1.Y - p0.Y
	B1 := p0.X - p1.X
	C1 := A1 * p0.X + B1 * p0.Y
	A2 := p3.Y - p2.Y 
	B2 := p2.X - p3.X
	C2 := A2 * p2.X + B2 * p2.Y
	Denominator := A1 * B2 - A2 * B1 
	return { X: ( B2 * C1 - B1 * C2 ) / Denominator , Y: ( A1 * C2 - A2 * C1 ) / Denominator  }
}

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines

Post by Hellbent » 01 Dec 2021, 10:38

The function I posted only shows if two lines could intersect and not if they actually do.
This example shows how to only show when they actually intersect.
Temp (1).gif
Temp (1).gif (261.14 KiB) Viewed 2113 times

Code: Select all

;********************************************************************************************************************************************************************************************
#Include, <My Altered GDIP LIB> ;GDIP.AHK
;********************************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
CoordMode, Mouse, Screen
Gdip_Startup()

Main := {}
Main.TargetLine := { Start: New HB_Vector( Random( 100 , 500 ) , Random( 50 , 450 ) ) , End: New HB_Vector( Random( 500 , 900 ) , Random( 50 , 450 ) ) }
Main.CutLine1 := { Start: New HB_Vector() , End: New HB_Vector() }
Main.CutLine2 := { Start: New HB_Vector() , End: New HB_Vector() }
Main.CuttingLine := { Start: New HB_Vector() , End: New HB_Vector() }
Main.CutVector := { Top: New HB_Vector() , Bottom: New HB_Vector() }
Main.Intercept := New HB_Vector()
Main.CuttingFrames := 200
Main.LoopIndex := 0
Main.Gui1 := New PopUpWindow( { X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: " -DPIScale +AlwaysOnTop " , AutoShow: 1 } )
Main.Pen1 := Gdip_CreatePen( "0xFF000000" , 3 )
Main.Pen2 := Gdip_CreatePen( "0xFF0066FF" , 3 )
Main.Pen3 := Gdip_CreatePen( "0xFF0000FF" , 3 )
Main.Pen4 := Gdip_CreatePen( "0xFFFF0000" , 3 )
Main.Brush1 := Gdip_BrushCreateSolid( "0xFF000000" )
Main.Brush2 := Gdip_BrushCreateSolid( "0xFFFF0000" )
Draw( Main )
return

GuiContextMenu:
*ESC::ExitApp

Numpad3::PopUpWindow.Helper()

+LButton::
	MouseGetPos, x, y 
	Main.CuttingLine.Start := New HB_Vector( x , y )
	While( GetKeyState( "LButton" , "P" ) ){
		MouseGetPos,x, y
		Main.CuttingLine.End := New HB_Vector( x , y )
		Draw( Main , 2 )
	}
	Main.Intercept := LineIntercept( Main.TargetLine , Main.CuttingLine )
	if( !( Main.Intercept.X < min( Main.TargetLine.Start.X , Main.TargetLine.End.X ) || Main.Intercept.X > max( Main.TargetLine.Start.X , Main.TargetLine.End.X ) || Main.Intercept.X < min( Main.CuttingLine.Start.X , Main.CuttingLine.End.X ) || Main.Intercept.X > max( Main.CuttingLine.Start.X , Main.CuttingLine.End.X ) ) ) {
		Main.CutVector.Top := New HB_Vector( Main.TargetLine.Start.X , Main.TargetLine.Start.Y )
		Main.CutVector.Top.Sub( Main.Intercept )
		Main.CutVector.Top.SetMag( Main.CutVector.Top.Mag() / Main.CuttingFrames )
		Main.CutVector.Bottom := New HB_Vector( Main.TargetLine.End.X , Main.TargetLine.End.Y )
		Main.CutVector.Bottom.Sub( Main.Intercept )
		Main.CutVector.Bottom.SetMag( Main.CutVector.Bottom.Mag() / Main.CuttingFrames )
		Main.CutLine1 := { Start: New HB_Vector( Main.TargetLine.Start.X , Main.TargetLine.Start.Y ) , End: New HB_Vector( Main.Intercept.X , Main.Intercept.Y ) }
		Main.CutLine2 := { Start: New HB_Vector( Main.TargetLine.End.X , Main.TargetLine.End.Y ) , End: New HB_Vector( Main.Intercept.X , Main.Intercept.Y ) }
		Draw( Main , 3 )
		Loop, % Main.CuttingFrames	{
			Main.CutLine1.End.Add( Main.CutVector.Top )
			Main.CutLine2.End.Add( Main.CutVector.Bottom )
			Draw( Main , 3 )
		}
		Main.TargetLine := { Start: New HB_Vector( Random( 100 , 500 ) , Random( 50 , 450 ) ) , End: New HB_Vector( Random( 500 , 900 ) , Random( 50 , 450 ) ) }
	}
	Draw( Main )
	return

LineIntercept( Line1 , Line2 ){
	A1 := Line1.End.Y - Line1.Start.Y
	B1 := Line1.Start.X - Line1.End.X
	C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
	A2 := Line2.End.Y - Line2.Start.Y
	B2 := Line2.Start.X - Line2.End.X
	C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
	Denominator := A1 * B2 - A2 * B1 
	return New HB_Vector( ( ( B2 * C1 - B1 * C2 ) / Denominator )  ,  ( ( A1 * C2 - A2 * C1 ) / Denominator ) )
}
	
Draw( Main , value := 1){
	Main.Gui1.ClearWindow()
	if( Value = 1 || Value = 2 ){
		Gdip_DrawLine( Main.Gui1.G , Main.Pen1 ,  Main.TargetLine.Start.X , Main.TargetLine.Start.Y , Main.TargetLine.End.X , Main.TargetLine.End.Y )
		if( Value = 2 ){
			Gdip_DrawLine( Main.Gui1.G , Main.Pen2 ,  Main.CuttingLine.Start.X , Main.CuttingLine.Start.Y , Main.CuttingLine.End.X , Main.CuttingLine.End.Y )
			Gdip_FillEllipse( Main.Gui1.G , Main.Brush1 , Main.CuttingLine.End.X - 5 , Main.CuttingLine.End.Y - 5 , 10 , 10 )
		}
	}else if( Value = 3 ){
		Gdip_DrawLine( Main.Gui1.G , Main.Pen4 ,  Main.CutLine1.Start.X , Main.CutLine1.Start.Y , Main.CutLine1.End.X , Main.CutLine1.End.Y )
		Gdip_DrawLine( Main.Gui1.G , Main.Pen4 ,  Main.CutLine2.Start.X , Main.CutLine2.Start.Y , Main.CutLine2.End.X , Main.CutLine2.End.Y )
		Gdip_DrawLine( Main.Gui1.G , Main.Pen2 ,  Main.CuttingLine.Start.X , Main.CuttingLine.Start.Y , Main.CuttingLine.End.X , Main.CuttingLine.End.Y )
		Gdip_FillEllipse( Main.Gui1.G , Main.Brush2 , Main.Intercept.X - 5 , Main.Intercept.Y - 5 , 10 , 10 )
	}
	Main.Gui1.UpdateWindow()
}	

Random( Min, Max ){
	Random, Out, Min, Max
	return out	
}

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2
;Date Written: Oct 28th, 2021
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	AddTrigger( obj ){
		local k , v , cc , bd
		
		This.Controls[ ++This.Index ] := { 	X:		10
										,	Y:		10
										,	W:		10
										,	H:		10	}
		for k, v in obj
			This.Controls[ This.Index ][ k ] := obj[ k ] 
		cc := This.Controls[ This.Index ]
		Gui, % This.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
		This.Handles[ hwnd ] := This.Index
		This.Controls[ This.Index ].Hwnd := hwnd
		return hwnd
		
	}
	DrawTriggers( color := "0xFFFF0000" , AutoUpdate := 0 ){
		local brush , cc 
		Brush := Gdip_BrushCreateSolid( color ) 
		Gdip_SetSmoothingMode( This.G , 3 )
		loop, % This.Controls.Length()	{
			cc := This.Controls[ A_Index ]
			Gdip_FillRectangle( This.G , Brush , cc.x , cc.y , cc.w , cc.h )
		
		}
		Gdip_DeleteBrush( Brush )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
	_OnClose( wParam ){
		if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
			Try{
				Gui, % PopUpWindow.HelperHwnd ":Destroy"
				SoundBeep, 555
			}
		}
	}
	CreateCachedBitmap( pBitmap , Dispose := 0 ){
		local pCachedBitmap
		if( This.CachedBitmap )
			This.DisposeCachedbitmap()
		DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
		This.CachedBitmap := pCachedBitmap
		if( Dispose )
			Gdip_DisposeImage( pBitmap )
	}
	DrawCachedBitmap( AutoUpdate := 0 ){
		DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DisposeCachedbitmap(){
		DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
	}
	Helper(){
		local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
		Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
		PopUpWindow.HelperHwnd := hwnd
		Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
		PopUpWindow.EditHwnd := hwnd
		loop, % MethodList.Length()	
			Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
		Gui, Show,,
		OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
	}
	_HelperClip(){
		local ClipList 
		
		GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
		
		ClipList := 		{ 	__New: 					" := New PopUpWindow( { X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
							,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
							,	ShowWindow:				".ShowWindow( Title := """" )"
							,	HideWindow:				".HideWindow()"
							,	UpdateWindow:			".UpdateWindow()"
							,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
							,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 )"
							,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
							,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
							,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" , BoundClass: """" , BoundMethod: """" } )"	
							,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
							,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
							,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
							,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
							
		clipboard := Out ClipList[ A_GuiControl ]
		
	}
}
;****************************************************************
Class HB_Vector	{
	__New(x:=0,y:=0){
		This.X:=x
		This.Y:=y
	}
	Add(Other_HB_Vector){
		This.X+=Other_HB_Vector.X
		This.Y+=Other_HB_Vector.Y
	}
	Sub(Other_HB_Vector){
		This.X-=Other_HB_Vector.X
		This.Y-=Other_HB_Vector.Y
	}
	mag(){
		return Sqrt(This.X*This.X + This.Y*This.Y)
	}
	magsq(){
		return This.Mag()**2
	}	
	setMag(in1){
		m:=This.Mag()
		This.X := This.X * in1/m
		This.Y := This.Y * in1/m
		return This
	}
	mult(in1,in2:="",in3:="",in4:="",in5:=""){
		if(IsObject(in1)&&in2=""){
			This.X*=In1.X 
			This.Y*=In1.Y 
		}else if(!IsObject(In1)&&In2=""){
			This.X*=In1
			This.Y*=In1
		}else if(!IsObject(In1)&&IsObject(In2)){
			This.X*=In1*In2.X
			This.Y*=In1*In2.Y
		}else if(IsObject(In1)&&IsObject(In2)){
			This.X*=In1.X*In2.X
			This.Y*=In1.Y*In2.Y
		}	
	}
	div(in1,in2:="",in3:="",in4:="",in5:=""){
		if(IsObject(in1)&&in2=""){
			This.X/=In1.X 
			This.Y/=In1.Y 
		}else if(!IsObject(In1)&&In2=""){
			This.X/=In1
			This.Y/=In1
		}else if(!IsObject(In1)&&IsObject(In2)){
			This.X/=In1/In2.X
			This.Y/=In1/In2.Y
		}else if(IsObject(In1)&&IsObject(In2)){
			This.X/=In1.X/In2.X
			This.Y/=In1.Y/In2.Y
		}	
	}
	dist(in1){
		return Sqrt(((This.X-In1.X)**2) + ((This.Y-In1.Y)**2))
	}
	dot(in1){
		return (This.X*in1.X)+(This.Y*In1.Y)
	}
	cross(in1){
		return This.X*In1.Y-This.Y*In1.X
	}
	Norm(){
		m:=This.Mag()
		This.X/=m
		This.Y/=m
	}
}


User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 01 Dec 2021, 15:17

I turned my code into a mini game.

Press ctrl+LButton to shoot.
Reload the script to start over.
Temp (1).gif
Temp (1).gif (284.47 KiB) Viewed 2067 times

Code: Select all

;********************************************************************************************************************************************************************************************
#Include, <My Altered GDIP LIB> ;GDIP.AHK
;********************************************************************************************************************************************************************************************
#SingleInstance, Force
SetBatchlines, -1
CoordMode, Mouse, Screen
Gdip_Startup()

Main := {}
Main.Gui1 := New PopUpWindow( { X: A_ScreenWidth / 2 - 400  , Y: A_ScreenHeight - 500 , W: 800 , H: 400 , Options: " -DPIScale +AlwaysOnTop " , AutoShow: 1 } )
Main.Pen1 := Gdip_CreatePen( "0xFF000000" , 3 )
Main.Pen2 := Gdip_CreatePen( "0xFF0066FF" , 3 )
Main.Pen3 := Gdip_CreatePen( "0xFF0000FF" , 3 )
Main.Pen4 := Gdip_CreatePen( "0xFFFF0000" , 3 )
Main.Brush1 := Gdip_BrushCreateSolid( "0xFFff0000" )
Main.Brush2 := Gdip_BrushCreateSolid( "0xFF0000FF" )

Main.Gui2 := New PopUpWindow( { X: A_ScreenWidth / 2 - 400  , Y: A_ScreenHeight - 500 , W: 800 , H: 400 , Options: " -DPIScale +AlwaysOnTop " , AutoShow: 1 } )

Main.Gui2.DrawBitmap( HB_BITMAP_MAKER() , { X: 0 , Y: Main.Gui2.H / 3 * 2 , W: Main.Gui2.W , H: Main.Gui2.H / 3 } , dispose := 1 )
Main.Gui2.UpdateWindow()
Bob := New Missile( Main )

Score := 0
Health := 10
Lasers := []
SetTimer, GameLoop, 30
return

GuiContextMenu:
*ESC::ExitApp

Numpad3::PopUpWindow.Helper()

GameLoop:
	Main.Gui1.ClearWindow()
	
	Bob.Update(Main)
	
	Loop, % Lasers.Length()	{
		Lasers[ Lasers.Length() - A_Index + 1 ].Update( Main )
		if ( Lasers[ Lasers.Length() - A_Index + 1 ].CheckWalls() )
			Lasers.RemoveAt( Lasers.Length() - A_Index + 1 )
		else
			Lasers[ Lasers.Length() - A_Index + 1 ].Draw( Main )
		if( Lasers[ Lasers.Length() - A_Index + 1 ].CheckHit( Bob ) ){
			Bob := New Missile( Main )
			Hit := New HB_Vector( Lasers[ Lasers.Length() - A_Index + 1 ].Hit.X , Lasers[ Lasers.Length() - A_Index + 1 ].Hit.Y )
			Lasers.RemoveAt( Lasers.Length() - A_Index + 1 )
			cc := 1 , rad := 10 , ++Score
		}
	}
	if( cc && ++cc < 20 ){
		Gdip_FillEllipse( Main.Gui1.G , Main.Brush1 , Hit.X - rad , Hit.Y - rad , rad * 2 , rad * 2 )
		rad += 5
	}
	( cc > 20 && ! cc := 0)
	if( --Bob.Life = 0 ){
		Bob := New Missile( Main )
		Health--
	}
	Gdip_TextToGraphics( Main.Gui1.G , "Score: " Score , "s26 Bold c" Main.Brush2 " x0 y0" , "Segoe ui" , 322 , 22 )
	Gdip_TextToGraphics( Main.Gui1.G , "Health: " Health , "s26 Bold c" Main.Brush1 " x0 y45" , "Segoe ui" , 322 , 22 )
	if( Health <= 0 ){
		SetTimer, GameLoop, off
		Gdip_TextToGraphics( Main.Gui1.G , "Game Over!" , "s44 Bold Center vCenter c" Main.Brush1 " x0 y0" , "Segoe ui" , 800 , 400 )
	}
	Main.Gui1.UpdateWindow()
	return

^LButton::
	CoordMode, Mouse, Client
	Gui, % Main.Gui1.Hwnd ":Show", 
	if( Lasers.Length() > 0 )
		return
	MouseGetPos, x, y 
	Lasers.Push( New Laser( Main , Tog := !Tog , x , y ) )
	return

Class Laser	{
	static Walls := [ { Start: New HB_Vector( 0 , 400 ) , End: New HB_Vector( 0 , 0 ) } , { Start: New HB_Vector( 0 , 0 ) , End: New HB_Vector( 800 , 0 ) } , { Start: New HB_Vector( 800 , 0 ) , End: New HB_Vector( 800 , 400 ) } ]
	__New( Main , Station , x , y ){
		This._SetDefaults( Station , x , y )
		This.Draw( Main )
	}
	_SetDefaults( Station , x , y ){
		This.Length := 50
		This.Color := "0xFF00ff00"
		This.Life := 30
		This.StartPosition := New HB_Vector( ( ( Station = 1 ) ? ( 50 ) : ( 750 ) ) , 400 )
		This.TargetPosition := New HB_Vector( x , y )
		This.Vector := New HB_Vector( x , y )
		This.Vector.Sub( This.StartPosition )
		This.Vector.Norm()
		This.Vector.SetMag( 30 )
		This.BackVector := New HB_Vector( This.TargetPosition.X , This.TargetPosition.Y )
		This.BackVector.Sub( This.StartPosition )
		This.BackVector.SetMag( -This.Length )
		This.Back := New HB_Vector( This.StartPosition.X , This.StartPosition.Y )
		This.Back.Add( This.BackVector )	
	}
	LineIntercept( Line1 , Line2 ){
		A1 := Line1.End.Y - Line1.Start.Y
		B1 := Line1.Start.X - Line1.End.X
		C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
		A2 := Line2.End.Y - Line2.Start.Y
		B2 := Line2.Start.X - Line2.End.X
		C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
		Denominator := A1 * B2 - A2 * B1 
		return New HB_Vector( ( ( B2 * C1 - B1 * C2 ) / Denominator )  ,  ( ( A1 * C2 - A2 * C1 ) / Denominator ) )
	}
	CheckHit( obj ){
		inter := This.LineIntercept( { Start: This.StartPosition , End: This.Back } , { Start: obj.StartPosition , End: obj.Back } )
		if( !( inter.X < min( This.StartPosition.X , This.Back.X ) || inter.X > max( This.StartPosition.X , This.Back.X ) || inter.X < min( obj.StartPosition.X , obj.Back.X ) || inter.X > max( obj.StartPosition.X , obj.Back.X ) ) ) {
				This.Hit := inter
				return 1
			}else
				return 0
	}
	CheckWalls(){
		if( This.StartPosition.X < 0 || This.StartPosition.X > 800 || This.StartPosition.Y < - This.Length )
			return 1
		else 
			return 0
	}
	Update(){
		This.StartPosition.Add( This.Vector )
		This.Back.Add( This.Vector )
	}
	Draw( Main ){
		Gdip_DrawLine( Main.Gui1.G , Main.Pen3 ,  This.StartPosition.X , This.StartPosition.Y , This.Back.X , This.Back.Y )
	}
}

class Missile {
	__New( Main ){
		This._SetDefaults()
		This.Draw( Main )
	}
	_SetDefaults(){
		This.Length := 90
		This.Color := "0xFFFF0000"
		This.Life := Random( 75 , 150 )
		This.StartPosition := New HB_Vector( Random( 0 , 800 ) , 0 )
		This.TargetPosition := New HB_Vector( Random( 0 , 800 ) , 400 )
		This.Vector := New HB_Vector( This.TargetPosition.X , This.TargetPosition.Y )
		This.Vector.Sub( This.StartPosition )
		This.Vector.SetMag( This.Vector.Mag() / This.Life )
		This.BackVector := New HB_Vector( This.TargetPosition.X , This.TargetPosition.Y )
		This.BackVector.Sub( This.StartPosition )
		This.BackVector.SetMag( -This.Length )
		This.Back := New HB_Vector( This.StartPosition.X , This.StartPosition.Y )
		This.Back.Add( This.BackVector )
		
	}
	Update( main ){
		This.StartPosition.Add( This.Vector )
		This.Back.Add( This.Vector )
		This.Draw( Main )
	}
	Draw( Main ){
		Gdip_DrawLine( Main.Gui1.G , Main.Pen4 ,  This.StartPosition.X , This.StartPosition.Y , This.Back.X , This.Back.Y )
	}
}



HB_BITMAP_MAKER(){
	;Bitmap Created Using: HB Bitmap Maker
	pBitmap := Gdip_CreateBitmap( 800 , 200 ) , G := Gdip_GraphicsFromImage( pBitmap ) , Gdip_SetSmoothingMode( G , 2 )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , 0 , 60 , 80 , 150 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF222222" ) , Gdip_FillRectangle( G , Brush , 40 , 20 , 80 , 200 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF222222" ) , Gdip_FillRectangle( G , Brush , 190 , 140 , 200 , 200 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF222222" ) , Gdip_FillRectangle( G , Brush , 460 , 50 , 100 , 160 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF222222" ) , Gdip_FillRectangle( G , Brush , 660 , 110 , 100 , 100 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , 110 , 130 , 40 , 100 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , 230 , 80 , 80 , 120 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , 530 , 110 , 80 , 90 ) , Gdip_DeleteBrush( Brush )
	Brush := Gdip_BrushCreateSolid( "0xFF333333" ) , Gdip_FillRectangle( G , Brush , 720 , 30 , 80 , 180 ) , Gdip_DeleteBrush( Brush )
	Gdip_DeleteGraphics( G )
	return pBitmap
}

Random( Min, Max ){
	Random, Out, Min, Max
	return out	
}

;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
;####################################################################################################################################################################################
class PopUpWindow	{
;PopUpWindow v2
;Date Written: Oct 28th, 2021
;Written By: Hellbent aka CivReborn
;SpcThanks: teadrinker , malcev 
	static Index := 0 , Windows := [] , Handles := [] , EditHwnd , HelperHwnd
	__New( obj := "" ){
		This._SetDefaults()
		This.UpdateSettings( obj )
		This._CreateWindow()
		This._CreateWindowGraphics()
		if( This.AutoShow )
			This.ShowWindow( This.Title )
	}
	_SetDefaults(){
		This.X := 10
		This.Y := 10
		This.W := 10
		This.H := 10
		This.Smoothing := 2
		This.Options := " -DPIScale +AlwaysOnTop "
		This.AutoShow := 0
		This.GdipStartUp := 0
		This.Title := ""
		
		This.Controls := []
		This.Handles := []
		This.Index := 0 
	}
	AddTrigger( obj ){
		local k , v , cc , bd
		
		This.Controls[ ++This.Index ] := { 	X:		10
										,	Y:		10
										,	W:		10
										,	H:		10	}
		for k, v in obj
			This.Controls[ This.Index ][ k ] := obj[ k ] 
		cc := This.Controls[ This.Index ]
		Gui, % This.Hwnd ":Add", Text, % "x" cc.X " y" cc.Y " w" cc.W " h" cc.H " hwndhwnd"
		This.Handles[ hwnd ] := This.Index
		This.Controls[ This.Index ].Hwnd := hwnd
		return hwnd
		
	}
	DrawTriggers( color := "0xFFFF0000" , AutoUpdate := 0 ){
		local brush , cc 
		Brush := Gdip_BrushCreateSolid( color ) 
		Gdip_SetSmoothingMode( This.G , 3 )
		loop, % This.Controls.Length()	{
			cc := This.Controls[ A_Index ]
			Gdip_FillRectangle( This.G , Brush , cc.x , cc.y , cc.w , cc.h )
		
		}
		Gdip_DeleteBrush( Brush )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	UpdateSettings( obj := "" , UpdateGraphics := 0 ){
		local k , v
		if( IsObject( obj ) )
			for k, v in obj
				This[ k ] := obj[ k ]
		( This.X = "Center" ) ? ( This.X := ( A_ScreenWidth - This.W ) / 2 ) 	
		( This.Y = "Center" ) ? ( This.Y := ( A_ScreenHeight - This.H ) / 2 ) 	
		if( UpdateGraphics ){
			This._DestroyWindowsGraphics()
			This._CreateWindowGraphics()
		}
	}
	_CreateWindow(){
		local hwnd
		Gui , New, % " +LastFound +E0x80000 hwndhwnd -Caption  " This.Options
		PopUpWindow.Index++
		This.Index := PopUpWindow.Index
		PopUpWindow.Windows[ PopUpWindow.Index ] := This
		This.Hwnd := hwnd
		PopUpWindow.Handles[ hwnd ] := PopUpWindow.Index
		if( This.GdipStartUp && !PopUpWindow.pToken )
			PopUpWindow.pToken := GDIP_STARTUP()
	}
	_DestroyWindowsGraphics(){
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
	}
	_CreateWindowGraphics(){
		This.hbm := CreateDIBSection( This.W , This.H )
		This.hdc := CreateCompatibleDC()
		This.obm := SelectObject( This.hdc , This.hbm )
		This.G := Gdip_GraphicsFromHDC( This.hdc )
		Gdip_SetSmoothingMode( This.G , This.Smoothing )
	}
	ShowWindow( Title := "" ){
		Gui , % This.Hwnd ":Show", % "x" This.X " y" This.Y " w" This.W " h" This.H " NA", % Title
	}
	HideWindow(){
		Gui , % This.Hwnd ":Hide",
	}
	UpdateWindow(){
		UpdateLayeredWindow( This.hwnd , This.hdc , This.X , This.Y , This.W , This.H )
	}
	ClearWindow( AutoUpdate := 0 ){
		Gdip_GraphicsClear( This.G )
		if( Autoupdate )
			This.UpdateWindow()
	}
	DrawBitmap( pBitmap , obj , dispose := 1 , AutoUpdate := 0 ){
		Gdip_DrawImage( This.G , pBitmap , obj.X , obj.Y , obj.W , obj.H )
		if( dispose )
			Gdip_DisposeImage( pBitmap )
		if( Autoupdate )
			This.UpdateWindow()
	}
	PaintBackground( color := "0xFF000000" , AutoUpdate := 0 ){
		if( isObject( color ) ){
			Brush := Gdip_BrushCreateSolid( ( color.HasKey( "Color" ) ) ? ( color.Color ) : ( "0xFF000000" ) ) 
			if( color.Haskey( "Round" ) )
				Gdip_FillRoundedRectangle( This.G , Brush , color.X , color.Y , color.W , color.H , color.Round )
			else
				Gdip_FillRectangle( This.G , Brush , color.X , color.Y , color.W , color.H ) 
		}else{
			Brush := Gdip_BrushCreateSolid( color ) 
			Gdip_FillRectangle( This.G , Brush , -1 , -1 , This.W + 2 , This.H + 2 ) 
		}
		Gdip_DeleteBrush( Brush )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DeleteWindow( GDIPShutdown := 0 ){
		Gui, % This.Hwnd ":Destroy"
		SelectObject( This.hdc , This.obm )
		DeleteObject( This.hbm )
		DeleteDC( This.hdc )
		Gdip_DeleteGraphics( This.G )
		hwnd := This.Hwnd
		for k, v in PopUpWindow.Windows[ Hwnd ]
			This[k] := ""
		PopUpWindow.Windows[ Hwnd ] := ""
		if( GDIPShutdown ){
			Gdip_Shutdown( PopUpWindow.pToken )
			PopUpWindow.pToken := ""
		}
	}
	_OnClose( wParam ){
		if( wParam = 0xF060 ){	;SC_CLOSE ;[ clicking on the gui close button ]
			Try{
				Gui, % PopUpWindow.HelperHwnd ":Destroy"
				SoundBeep, 555
			}
		}
	}
	CreateCachedBitmap( pBitmap , Dispose := 0 ){
		local pCachedBitmap
		if( This.CachedBitmap )
			This.DisposeCachedbitmap()
		DllCall( "gdiplus\GdipCreateCachedBitmap" , "Ptr" , pBitmap , "Ptr" , this.G , "PtrP" , pCachedBitmap )
		This.CachedBitmap := pCachedBitmap
		if( Dispose )
			Gdip_DisposeImage( pBitmap )
	}
	DrawCachedBitmap( AutoUpdate := 0 ){
		DllCall( "gdiplus\GdipDrawCachedBitmap" , "Ptr" , this.G , "Ptr" , This.CachedBitmap , "Int" , 0 , "Int" , 0 )
		if( AutoUpdate )
			This.UpdateWindow()
	}
	DisposeCachedbitmap(){
		DllCall( "gdiplus\GdipDeleteCachedBitmap" , "Ptr" , This.CachedBitmap )
	}
	Helper(){
		local hwnd , MethodList := ["__New","UpdateSettings","ShowWindow","HideWindow","UpdateWindow","ClearWindow","DrawBitmap","PaintBackground","DeleteWindow" , "AddTrigger" , "DrawTriggers", "CreateCachedBitmap" , "DrawCachedBitmap" , "DisposeCachedbitmap" ]
		Gui, New, +AlwaysOnTop +ToolWindow +HwndHwnd
		PopUpWindow.HelperHwnd := hwnd
		Gui, Add, Edit, xm ym w250 r1 Center hwndhwnd, Gui1
		PopUpWindow.EditHwnd := hwnd
		loop, % MethodList.Length()	
			Gui, Add, Button, xm y+1 w250 r1 gPopUpWindow._HelperClip, % MethodList[ A_Index ]
		Gui, Show,,
		OnMessage( 0x112 , This._OnClose.Bind( hwnd ) )
	}
	_HelperClip(){
		local ClipList 
		
		GuiControlGet, out, % PopUpWindow.HelperHwnd ":", % PopUpWindow.EditHwnd	
		
		ClipList := 		{ 	__New: 					" := New PopUpWindow( { X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: "" -DPIScale +AlwaysOnTop "" } )"
							,	UpdateSettings:			".UpdateSettings( { X: """" , Y: """" , W: """" , H: """" } , UpdateGraphics := 0 )"
							,	ShowWindow:				".ShowWindow( Title := """" )"
							,	HideWindow:				".HideWindow()"
							,	UpdateWindow:			".UpdateWindow()"
							,	ClearWindow:			".ClearWindow( AutoUpdate := 0 )"
							,	DrawBitmap:				".DrawBitmap( pBitmap := """" , { X: 0 , Y: 0 , W: " Out ".W , H: " Out ".H } , dispose := 1 )"
							,	PaintBackground:		".PaintBackground( color := ""0xFF000000"" )  "  ";{ Color: ""0xFF000000"" , X: 2 , Y: 2 , W: " Out ".W - 4 , H: " Out ".H - 4 , Round: 10 }"
							,	DeleteWindow:			".DeleteWindow( GDIPShutdown := 0 )"
							,	AddTrigger:				".AddTrigger( { X: """" , Y: """" , W: """" , H: """" , Value: """" , Label: """" , BoundClass: """" , BoundMethod: """" } )"	
							,	DrawTriggers:			".DrawTriggers( color := ""0xFFFF0000"" , AutoUpdate := 0 )"	
							,	CreateCachedBitmap:		".CreateCachedBitmap( pBitmap , Dispose := 0 )"	
							,	DrawCachedBitmap: 		".DrawCachedBitmap( AutoUpdate := 0 )"	
							,	DisposeCachedbitmap:	".DisposeCachedbitmap()"	}
							
		clipboard := Out ClipList[ A_GuiControl ]
		
	}
}
;****************************************************************
Class HB_Vector	{
	__New(x:=0,y:=0){
		This.X:=x
		This.Y:=y
	}
	Add(Other_HB_Vector){
		This.X+=Other_HB_Vector.X
		This.Y+=Other_HB_Vector.Y
	}
	Sub(Other_HB_Vector){
		This.X-=Other_HB_Vector.X
		This.Y-=Other_HB_Vector.Y
	}
	mag(){
		return Sqrt(This.X*This.X + This.Y*This.Y)
	}
	magsq(){
		return This.Mag()**2
	}	
	setMag(in1){
		m:=This.Mag()
		This.X := This.X * in1/m
		This.Y := This.Y * in1/m
		return This
	}
	mult(in1,in2:="",in3:="",in4:="",in5:=""){
		if(IsObject(in1)&&in2=""){
			This.X*=In1.X 
			This.Y*=In1.Y 
		}else if(!IsObject(In1)&&In2=""){
			This.X*=In1
			This.Y*=In1
		}else if(!IsObject(In1)&&IsObject(In2)){
			This.X*=In1*In2.X
			This.Y*=In1*In2.Y
		}else if(IsObject(In1)&&IsObject(In2)){
			This.X*=In1.X*In2.X
			This.Y*=In1.Y*In2.Y
		}	
	}
	div(in1,in2:="",in3:="",in4:="",in5:=""){
		if(IsObject(in1)&&in2=""){
			This.X/=In1.X 
			This.Y/=In1.Y 
		}else if(!IsObject(In1)&&In2=""){
			This.X/=In1
			This.Y/=In1
		}else if(!IsObject(In1)&&IsObject(In2)){
			This.X/=In1/In2.X
			This.Y/=In1/In2.Y
		}else if(IsObject(In1)&&IsObject(In2)){
			This.X/=In1.X/In2.X
			This.Y/=In1.Y/In2.Y
		}	
	}
	dist(in1){
		return Sqrt(((This.X-In1.X)**2) + ((This.Y-In1.Y)**2))
	}
	dot(in1){
		return (This.X*in1.X)+(This.Y*In1.Y)
	}
	cross(in1){
		return This.X*In1.Y-This.Y*In1.X
	}
	Norm(){
		m:=This.Mag()
		This.X/=m
		This.Y/=m
	}
}


User avatar
SteveMylo
Posts: 233
Joined: 22 Jun 2021, 00:50
Location: Australia
Contact:

Re: Point of two intersecting lines at 90 degree

Post by SteveMylo » 23 Dec 2021, 22:35

Hellbent wrote:
29 Nov 2021, 23:11
I got it sorted out thanks.
Hey there HellBent! Awesome game haha. I have a problem I can't work out.
I need to find a point of two intersecting lines, although one line has to be extrapolated from it's angle I guess. See pic attached.
I need to click-drag Point 'C' left in the 'X' position along the Boundary box.

I know all the coordinates of all points, and distances can easily be worked out, but I don't know how to extrapolate the line where it hits the boundary box up the top.

I guess I need the angle 1st. I'll paste some formula's down for you to save you time (if you have time) that you might need or call upon.
Don't forget, if the A & B angle is more acute, then Point C would need to be dragged in the 'Y' down position along the boundary box.
IMG_5172.jpg
IMG_5172.jpg (702.56 KiB) Viewed 1933 times
Here is some code I found over my travels that you might want to referee but I know your'e all over this anyways. ;)

*This code I found that wants to mouse-move according to known angle and known length. It already knows the Angle (225) and already knows the exact length it wants to move (1000), (I don't know my length which is the issue)

Code: Select all

GetPosFromAngle(mx,my,960,540,1000,225)
MouseMove,% mx,% my
return
 
GetPosFromAngle(ByRef x2,ByRef y2,x1,y1,len,ang){
    ang := ang * 0.0174532925
    x2 := x1 + len * cos(ang)
    y2 := y1 + len * -sin(ang)
}
This is the code I use to find my angles after drawing a line in other scripts I have, between two points.

Code: Select all

Var1:=% ATan((bY-aY)/(bX-aX))*57.29578      ; For Horizontal
;~ Var1:=% ATan((aX-bX)/(aY-bY))*57.29578*-1        ; For Vertical

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 24 Dec 2021, 12:41

Hi @SteveMylo

If I understand correctly, you are trying to find where a line drawn between two points would hit a border if the line was extended along the same vector.

In this example you can adjust points "A" and "B" and see where the line between them would hit the walls.
Animation.gif
Animation.gif (672.89 KiB) Viewed 1894 times
***This requires the "PopUpWindow" class found in the mini game script***
https://www.autohotkey.com/boards/viewtopic.php?f=76&t=37175#p432457

Code: Select all

;***************************************************************************************************
#Include, <My Altered GDIP LIB>  ;GDIP.ahk
#Include <PopUpWindow_V2> 	
;***************************************************************************************************
#SingleInstance force
#NoEnv
CoordMode, Mouse, Client
SetBatchLines, -1
GDIP_StartUp()

Main := {}

Main.Pen1 := Gdip_CreatePen( "0xFF000000" , 5 )
Main.Pen2 := Gdip_CreatePen( "0xFFFF0000" , 5 )
Main.Pen3 := Gdip_CreatePen( "0xFF00FF00" , 5 )
Main.Brush1 := Gdip_BrushCreateSolid( "0xFF3399aa" ) 
Main.Brush2 := Gdip_BrushCreateSolid( "0xFFFFFF00" ) 
Main.Brush3 := Gdip_BrushCreateSolid( "0xFF000000" ) 
Main.Brush4 := Gdip_BrushCreateSolid( "0xFFFF0000" ) 

Main.Gui1 := New PopUpWindow( { X: 0 , Y: 0 , W: A_ScreenWidth , H: A_ScreenHeight , Options: " -DPIScale +AlwaysOnTop " , AutoShow: 1 } )

Main.Border := {}
Main.Border.Left := { Start: New HB_Vector( 100 , A_ScreenHeight - 100 ) , End: New HB_Vector( 100 , 100 ) }
Main.Border.Top := { Start: New HB_Vector( 100 , 100 ) , End: New HB_Vector( A_ScreenWidth - 100 , 100 ) }
Main.Border.Right := { Start: New HB_Vector( A_ScreenWidth - 100 , 100 ) , End: New HB_Vector( A_ScreenWidth - 100 , A_ScreenHeight - 100 ) }
Main.Border.Bottom := { Start: New HB_Vector( A_ScreenWidth - 100 , A_ScreenHeight - 100 ) , End: New HB_Vector( 100 , A_ScreenHeight - 100 ) }

Main.Points := {}
Main.Points.A := New HB_Vector( 700 , 300 )
Main.Points.B := New HB_Vector( 900 , 200 )
Main.Points.C := New HB_Vector()
Main.Points.D := New HB_Vector()

Main.A_Copy := New HB_Vector()
Main.B_Copy := New HB_Vector()

Main.ExtendedVector := New HB_Vector()
Main.MaxMag := Sqrt( A_ScreenWidth * A_ScreenWidth + A_ScreenHeight * A_ScreenHeight ) + 100

Main.MouseVector := New HB_Vector()
Main.TestLine := { Start: New HB_Vector() , End: New HB_Vector() }

GetBorderPoints( Main )
GetBorderPoints( Main , "B" , "A" , "D" )

Draw( Main )

OnMessage( 0x201 , func( "WatchCursor" ).Bind( Main ) )

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp

;~ RShift::PopUpWindow.Helper()

WatchCursor( obj ){
	local x , y , dist1 , dist2 , selected := "" 
	
	MouseGetPos, x , y
	obj.MouseVector := New HB_Vector( x , y )
	
	if( ( ( dist1 := obj.MouseVector.Dist( obj.Points.A ) ) <= 15 || ( dist2 := obj.MouseVector.Dist( obj.Points.B ) ) <= 15 ) ){
		
		( dist1 && dist2 ) ? ( ( dist1 <= dist2 ) ? ( selected := "A" ) : ( selected := "B" ) ) : ( ( dist1 <= obj.MouseVector.Dist( obj.Points.B ) ) ? ( selected := "A" ) : ( selected := "B" ) )
		
		While( GetKeyState( "LButton" , "P" ) ){
			
			MouseGetPos, x , y
			obj.Points[ Selected ] := New HB_Vector( x , y )
			
			GetBorderPoints( obj )
			GetBorderPoints( obj , "B" , "A" , "D" )
			Draw( obj )
			
		}
	}
}

GetBorderPoints( obj , Point1 := "A" , Point2 := "B" , Point3 := "C" ){
	
	obj.ExtendedVector := New HB_Vector( obj.Points[ Point1 ].X , obj.Points[ Point1 ].Y )
	obj[ Point2 "_Copy" ] := New HB_Vector( obj.Points[ Point2 ].X , obj.Points[ Point2 ].Y )
	obj[ Point2 "_Copy" ].Sub( obj.Points[ Point1 ] )
	obj[ Point2 "_Copy" ].SetMag( obj.MaxMag )
	obj.ExtendedVector.Add( obj[ Point2 "_Copy" ] )
			
	obj.TestLine := { Start: New HB_Vector( obj.ExtendedVector.X , obj.ExtendedVector.Y ) , End: New HB_Vector( obj.Points[ Point2 ].X , obj.Points[ Point2 ].Y ) }
	
	for k , v in obj.Border	{
	
		obj.Intercept := LineIntercept( obj.TestLine , obj.Border[ k ] )
		if( TestIntercept( obj.Intercept , obj.TestLine , obj.Border[ k ] ) ){
			
			obj.Points[ Point3 ].X := obj.Intercept.X , obj.Points[ Point3 ].Y := obj.Intercept.Y
			break
		}
	}
}

Draw( Main ){
	
	local arr := [ [ "B" , "C" ] , [ "A" , "D" ] ]
	Main.Gui1.ClearWindow()
	
	Main.Gui1.PaintBackground( "0x33000000" )
	
	for k, v in Main.Border
		Gdip_DrawLine( Main.Gui1.G , Main.Pen1 , Main.Border[ k ].Start.X , Main.Border[ k ].Start.Y , Main.Border[ k ].End.X , Main.Border[ k ].End.Y )
	
	for k , v in arr
		Gdip_DrawLine( Main.Gui1.G , Main.Pen2 , Main.Points[ arr[ k , 1 ] ].X , Main.Points[ arr[ k , 1 ] ].Y , Main.Points[ arr[ k , 2 ] ].X , Main.Points[ arr[ k , 2 ] ].Y )
	
	Gdip_DrawLine( Main.Gui1.G , Main.Pen3 , Main.Points.B.X , Main.Points.B.Y , Main.Points.A.X , Main.Points.A.Y )
	
	for k , v in [ "A" , "B" , "C" , "D" ]
		Gdip_FillEllipse( Main.Gui1.G , ( A_Index < 3 ) ? ( Main.Brush1 ) : ( Main.Brush2 )  , Main.Points[ v ].X - 15 , Main.Points[ v ].Y - 15 , 31 , 31 )
		, Gdip_TextToGraphics( Main.Gui1.G , v , "s18 Center vCenter Bold c" ( ( A_Index < 3 ) ? ( Main.Brush3 ) : ( Main.Brush4 ) )  " x" Main.Points[ v ].X - 15 " y" Main.Points[ v ].Y - 15 , "Comic Sans MS" , 31 , 31 )
		
	Main.Gui1.UpdateWindow()
}

;****************************************************************

TestIntercept( interceptPoint , TargetLine , CuttingLine ){
	
	for k , v in [ "X" , "Y" ]	
		
		M%v%_Min := min( CuttingLine.Start[ v ] , CuttingLine.End[ v ] )
		, M%v%_Max := max( CuttingLine.Start[ v ] , CuttingLine.End[ v ] )
		, L%v%_Min := min( TargetLine.Start[ v ] , TargetLine.End[ v ] )
		, L%v%_Max := max( TargetLine.Start[ v ] , TargetLine.End[ v ] )
	
	if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
		return 1
	
	return 0
}

LineIntercept( Line1 , Line2 ){
	A1 := Line1.End.Y - Line1.Start.Y
	B1 := Line1.Start.X - Line1.End.X
	C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
	A2 := Line2.End.Y - Line2.Start.Y
	B2 := Line2.Start.X - Line2.End.X
	C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
	Denominator := A1 * B2 - A2 * B1 
	return New HB_Vector( ( ( B2 * C1 - B1 * C2 ) / Denominator )  ,  ( ( A1 * C2 - A2 * C1 ) / Denominator ) )
}

;****************************************************************

Class HB_Vector	{
	__New( x := 0 , y := 0 ){
		This.X := x
		This.Y := y
	}
	Add( Other_HB_Vector ){
		This.X += Other_HB_Vector.X
		This.Y += Other_HB_Vector.Y
	}
	Sub( Other_HB_Vector ){
		This.X -= Other_HB_Vector.X
		This.Y -= Other_HB_Vector.Y
	}
	mag(){
		return Sqrt( This.X * This.X + This.Y * This.Y )
	}
	magsq(){
		return This.Mag()**2
	}	
	setMag(in1){
		local m := This.Mag()
		This.X := This.X * in1 / m
		This.Y := This.Y * in1 / m
		return This
	}
	mult( in1 , in2 := "" , in3 := "" , in4 := "" , in5 := "" ){
		if( IsObject( in1 ) && in2 = "" ){
			This.X *= In1.X 
			This.Y *= In1.Y 
		}else if( !IsObject( In1 ) && In2 = "" ){
			This.X *= In1
			This.Y *= In1
		}else if( !IsObject( In1 ) && IsObject( In2 ) ){
			This.X *= In1 * In2.X
			This.Y *= In1 * In2.Y
		}else if( IsObject( In1 ) && IsObject( In2 ) ){
			This.X *= In1.X * In2.X
			This.Y *= In1.Y * In2.Y
		}	
	}
	div( in1 , in2 := "" , in3 := "" , in4 := "" , in5 := "" ){
		if( IsObject( in1 ) && in2 = "" ){
			This.X /= In1.X 
			This.Y /= In1.Y 
		}else if( !IsObject( In1 ) && In2 = "" ){
			This.X /= In1
			This.Y /= In1
		}else if( !IsObject( In1 ) && IsObject( In2 ) ){
			This.X /= In1 / In2.X
			This.Y /= In1 / In2.Y
		}else if( IsObject( In1 ) && IsObject( In2 ) ){
			This.X /= In1.X / In2.X
			This.Y /= In1.Y / In2.Y
		}	
	}
	dist( in1 ){
		return Sqrt( ( ( This.X - In1.X ) **2 ) + ( ( This.Y - In1.Y ) **2 ) )
	}
	dot( in1 ){
		return ( This.X * in1.X ) + ( This.Y * In1.Y )
	}
	cross( in1 ){
		return This.X * In1.Y - This.Y * In1.X
	}
	Norm(){
		local m := This.Mag()
		This.X /= m
		This.Y /= m
	}
}


The basics of how it works goes like this.

You have two points ( vectors ) "A" and "B". To get "C", get the vector that points between "A" and "B" by subtracting Vector "A" from Vector "B".
20211224122637.png
20211224122637.png (28.71 KiB) Viewed 1894 times

The next step is to extend the new vector ( B-A ) so that no matter what it will be long enough to hit your walls.
Next, take the extended vector and add it together with the "B" vector.
At this point you will have your B vector and a vector that is on the outside of your border giving you the 2 points of a line.
The last step is to check if there is a intercept between your new line and any of the border lines.

If you have any questions feel free to ask.

User avatar
SteveMylo
Posts: 233
Joined: 22 Jun 2021, 00:50
Location: Australia
Contact:

Re: Point of two intersecting lines at 90 degree

Post by SteveMylo » 26 Dec 2021, 03:29

Hellbent wrote:
24 Dec 2021, 12:41
you are trying to find where a line drawn between two points would hit a border if the line was extended along the same vector?
Yes, you are spot on! Although the extrapolated (imaginary) line always needs to hit the border cause I always need to move point C to it every time.
Also...Merry Christmas!!!! :xmas: .... You are doing exactly what I need ( in your code ), I tried your GUI script and got it working. You are a talent. but.......... I tried really really hard to get what I needed out of' your' script and adapt it to mine but I'm a bit lost.
All the GUI and GDIP code has confused me trying to extract the points that I need. ( I did try really hard)
Also, the Vector illustration you drew, all point to a central point in a quadrant and I can't seem to relate that to my needs. I'm probably reading/looking at it wrong :shh:

anyways no matter .... If you see my screenshot below, I'll reiterate mostly what you already know, but I'll tell you 'all' that I need for my script.
  • The RED line is just an example of the extrapolated line.
  • All the GREEN coordinates are known. . The rest can be figured out.
  • My script has to be CoordMode, Mouse, Screen (but prob not relevant)
  • All the other white dot points can be ignored. I'm only interested in points A,B,C.
  • I just need to hit a hotkey and it will MouseClickDrag point C (cXcY) to Unknown X, UnknownY. (Points A & B are always random)
  • The only way it can do that is to know where the extrapolated line from point A to B hits the TOP border (dXcY to cXcY) or the RIGHT Border (cXcY to cXdY)
Obviously your demonstration works perfectly, although I can't have all the GUI / GDIP stuff in my script.
I just wasn't sure which functions and code to keep and delete from your script and which parameter names are 'my coordinates'

looking forward to any wisdom that awaits
Curves3.jpg
Curves3.jpg (32.21 KiB) Viewed 1836 times

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 26 Dec 2021, 16:36

SteveMylo wrote:
26 Dec 2021, 03:29

Yes, you are spot on! Although the extrapolated (imaginary) line always needs to hit the border cause I always need to move point C to it every time.
You just need to make sure that your border lines have full coverage of the perimeter. With that you will get your new c position every time.

Also...Merry Christmas!!!! :xmas: .... You are doing exactly what I need ( in your code ), I tried your GUI script and got it working. You are a talent. but.......... I tried really really hard to get what I needed out of' your' script and adapt it to mine but I'm a bit lost.
All the GUI and GDIP code has confused me trying to extract the points that I need. ( I did try really hard)
Also, the Vector illustration you drew, all point to a central point in a quadrant and I can't seem to relate that to my needs. I'm probably reading/looking at it wrong :shh:
Merry Christmas to you too.

Perhaps a crash course in vectors will help.

Right now you are likely thinking of "A" and "B" as points on a x / y plain, instead you need to think of them as arrows that point from an origin point.
In this case the origin point would be the top left corner of the Screen , Window , or client area of a window [ CoordMode ]

.
Animation.gif
Animation.gif (37.2 KiB) Viewed 1792 times
.

In the case of your computer, the x / y plain has the "Y" axis flipped ( the y values at the bottom of your screen are positive and grow larger the further you go down )

Watch the first few mins of this to get a decent enough grasp of vectors. Once you have a better understanding of the basic concept, the steps that I will explain further down will make A LOT more sense.


.

.

Before we go into working with our vectors, let's first cover the syntax that we will use for our code.

Each of your points has a name and 2 properties ( x and y )
We can write that like this.

Code: Select all


;Example 1

MyVector := {} 		;Point
MyVector.X := 100
MyVector.Y := 150


;Example 2

MyVector := { X: 100 , Y: 150 }		;Point

The examples above would be fine for this, but a few years ago I wrote a class for vectors which includes the same stuff as the examples, but it also has built in functions that can be used with it.

Using the class looks like this.

Code: Select all


MyVector := New HB_Vector( x , y )

;That creates an object the same as this.
MyVector := { X: x , Y: y }

To use the built in functions we just use the name of your object / point followed by the name of the function.

Code: Select all

MyVector.Sub( anotherVector ) ;subtract another vector from this vector.

MyVector.Dist( anotherVector  ) ;get the distance between this vector and another vector

;etc...


Another thing besides vectors, we also have lines.
Lines are pairs of two vectors. They have a starting vector and a ending vector and are written like this.

Code: Select all


Line := { Start: { X: "" , Y: "" } , End: { X: "" , Y: "" }  }


;or as the case is.

Line := { Start: New HB_Vector() , End: New HB_Vector() }


It isn't necessary to use a class, you can just use the math that is contained in the functions to do the same thing, but the class makes life easy.



With the basics covered lets get into what you need to do.

We have two points ( vectors ), to find where a line drawn from "A" through "B" would hit the border we first need to get a vector that points from
"A" to "B", the order of A and B is important because it will determine the direction the new vector will point in.

To get our vector we only need to SUBTRACT vector "A" FROM vector "B"
That gives us a arrow that sits at the origin point and has a length ( magnitude )
of the distance between "A" and "B" [ Dist**2 := Length**2 + Height**2 ]

.
Animation.gif
Animation.gif (174.96 KiB) Viewed 1792 times
.


Now that we have a vector that POINTS FROM "A" TO "B" ( you can also say that we have a vector that "describes" how to move from "A" to "B" ) we can extend ( Scale ) our new vector so that the direction stays the same, but its length is long enough so that no matter where you place the origin within your boundaries , the end of the arrow will always sit outside. In this case I just set it to one million.

Next you take the extended vector and add it together with "A" or "B" ( it really doesn't matter in this case but normally in a situation like this you would add it to "A" )

You now have the two points of a line that goes from inside your boundary to the outside of your boundary.

The last step is to go through each of your boundary lines and test to see if and where the new line crosses your border ( the same thing the mini game does ).

After that you can use the intercept point as one of points in MouseClickDrag


Here is a little example that moves your cursor from your old "C" to the new "C" when you press F1 , you can replace it with mouseclickdrag

Code: Select all

#SingleInstance force
SetBatchLines, -1

CoordMode, Mouse, Screen

Main := {}

Main.Points := {}
Main.Points.A := New HB_Vector( 300 , 500 )
Main.Points.B := New HB_Vector( 800 , 200 )
Main.Points.C := New HB_Vector( A_ScreenWidth - 100 , 120 )
Main.Points.New_C := New HB_Vector()
Main.Points.B_Minus_A := New HB_Vector()


Main.Border := {}
Main.Border.Left := { Start: New HB_Vector( 100 , A_ScreenHeight - 100 ) , End: New HB_Vector( 100 , 100 ) }
Main.Border.Top := { Start: New HB_Vector( 100 , 100 ) , End: New HB_Vector( A_ScreenWidth - 100 , 100 ) }
Main.Border.Right := { Start: New HB_Vector( A_ScreenWidth - 100 , 100 ) , End: New HB_Vector( A_ScreenWidth - 100 , A_ScreenHeight - 100 ) }
Main.Border.Bottom := { Start: New HB_Vector( A_ScreenWidth - 100 , A_ScreenHeight - 100 ) , End: New HB_Vector( 100 , A_ScreenHeight - 100 ) }

Main.MaxMag := 1000000

Main.ProjectedLine := { Start: New HB_Vector() , End: New HB_Vector() }

return
GuiClose:
GuiContextMenu:
*ESC::ExitApp


F1::
GetNewPosition:
	
	Main.Points.B_Minus_A.X := Main.Points.B.X , Main.Points.B_Minus_A.Y := Main.Points.B.Y
	
	Main.Points.B_Minus_A.Sub( Main.Points.A )
	
	Main.Points.B_Minus_A.SetMag( Main.MaxMag )
	
	Main.Points.B_Minus_A.Add( Main.Points.A )
	
	Main.ProjectedLine.Start := Main.Points.A
	Main.ProjectedLine.End := Main.Points.B_Minus_A
	
	for k, v in Main.Border	
		
		if( TestIntercept( ( Main.Points.New_C := LineIntercept( Main.ProjectedLine , Main.Border[ k ] ) ) , Main.ProjectedLine , Main.Border[ k ] ) )
			
			break
	
	MouseMove, Main.Points.C.X , Main.Points.C.Y 
	
	sleep, 500
	
	MouseMove, Main.Points.New_C.X , Main.Points.New_C.Y , 30
	
	return

;****************************************************************

TestIntercept( interceptPoint , TargetLine , CuttingLine ){
	
	for k , v in [ "X" , "Y" ]	
		
		M%v%_Min := min( CuttingLine.Start[ v ] , CuttingLine.End[ v ] )
		, M%v%_Max := max( CuttingLine.Start[ v ] , CuttingLine.End[ v ] )
		, L%v%_Min := min( TargetLine.Start[ v ] , TargetLine.End[ v ] )
		, L%v%_Max := max( TargetLine.Start[ v ] , TargetLine.End[ v ] )
	
	if( !( interceptPoint.X < Mx_Min || interceptPoint.X > Mx_Max || interceptPoint.X < Lx_Min || interceptPoint.X > Lx_Max ) && !( interceptPoint.Y < My_Min || interceptPoint.Y > My_Max || interceptPoint.Y < Ly_Min || interceptPoint.Y > Ly_Max ) )
		return 1
	
	return 0
}

LineIntercept( Line1 , Line2 ){
	A1 := Line1.End.Y - Line1.Start.Y
	B1 := Line1.Start.X - Line1.End.X
	C1 := A1 * Line1.Start.X + B1 * Line1.Start.Y
	A2 := Line2.End.Y - Line2.Start.Y
	B2 := Line2.Start.X - Line2.End.X
	C2 := A2 * Line2.Start.X + B2 * Line2.Start.Y
	Denominator := A1 * B2 - A2 * B1 
	return New HB_Vector( ( ( B2 * C1 - B1 * C2 ) / Denominator )  ,  ( ( A1 * C2 - A2 * C1 ) / Denominator ) )
}

;****************************************************************

;****************************************************************

Class HB_Vector	{
	__New( x := 0 , y := 0 ){
		This.X := x
		This.Y := y
	}
	Add( Other_HB_Vector ){
		This.X += Other_HB_Vector.X
		This.Y += Other_HB_Vector.Y
	}
	Sub( Other_HB_Vector ){
		This.X -= Other_HB_Vector.X
		This.Y -= Other_HB_Vector.Y
	}
	mag(){
		return Sqrt( This.X * This.X + This.Y * This.Y )
	}
	magsq(){
		return This.Mag()**2
	}	
	setMag(in1){
		local m := This.Mag()
		This.X := This.X * in1 / m
		This.Y := This.Y * in1 / m
		return This
	}
	mult( in1 , in2 := "" , in3 := "" , in4 := "" , in5 := "" ){
		if( IsObject( in1 ) && in2 = "" ){
			This.X *= In1.X 
			This.Y *= In1.Y 
		}else if( !IsObject( In1 ) && In2 = "" ){
			This.X *= In1
			This.Y *= In1
		}else if( !IsObject( In1 ) && IsObject( In2 ) ){
			This.X *= In1 * In2.X
			This.Y *= In1 * In2.Y
		}else if( IsObject( In1 ) && IsObject( In2 ) ){
			This.X *= In1.X * In2.X
			This.Y *= In1.Y * In2.Y
		}	
	}
	div( in1 , in2 := "" , in3 := "" , in4 := "" , in5 := "" ){
		if( IsObject( in1 ) && in2 = "" ){
			This.X /= In1.X 
			This.Y /= In1.Y 
		}else if( !IsObject( In1 ) && In2 = "" ){
			This.X /= In1
			This.Y /= In1
		}else if( !IsObject( In1 ) && IsObject( In2 ) ){
			This.X /= In1 / In2.X
			This.Y /= In1 / In2.Y
		}else if( IsObject( In1 ) && IsObject( In2 ) ){
			This.X /= In1.X / In2.X
			This.Y /= In1.Y / In2.Y
		}	
	}
	dist( in1 ){
		return Sqrt( ( ( This.X - In1.X ) **2 ) + ( ( This.Y - In1.Y ) **2 ) )
	}
	dot( in1 ){
		return ( This.X * in1.X ) + ( This.Y * In1.Y )
	}
	cross( in1 ){
		return This.X * In1.Y - This.Y * In1.X
	}
	Norm(){
		local m := This.Mag()
		This.X /= m
		This.Y /= m
	}
}

anyways no matter .... If you see my screenshot below, I'll reiterate mostly what you already know, but I'll tell you 'all' that I need for my script.
  • The RED line is just an example of the extrapolated line.
  • All the GREEN coordinates are known. . The rest can be figured out.
  • My script has to be CoordMode, Mouse, Screen (but prob not relevant)
  • All the other white dot points can be ignored. I'm only interested in points A,B,C.
  • I just need to hit a hotkey and it will MouseClickDrag point C (cXcY) to Unknown X, UnknownY. (Points A & B are always random)
  • The only way it can do that is to know where the extrapolated line from point A to B hits the TOP border (dXcY to cXcY) or the RIGHT Border (cXcY to cXdY)
Obviously your demonstration works perfectly, although I can't have all the GUI / GDIP stuff in my script.
I just wasn't sure which functions and code to keep and delete from your script and which parameter names are 'my coordinates'

looking forward to any wisdom that awaits

Curves3.jpg
I think that I have the bases covered.

I put all the variable declarations up at the top of the script and show where the vectors get used to make things a bit easier to work with.

If you have any questions feel free.

User avatar
SteveMylo
Posts: 233
Joined: 22 Jun 2021, 00:50
Location: Australia
Contact:

Re: Point of two intersecting lines at 90 degree

Post by SteveMylo » 27 Dec 2021, 06:25

Hellbent wrote:
26 Dec 2021, 16:36
I think that I have the bases covered.
Absolute legend :clap: Watched the videos and read your comments about 20 times.
Took me a few goes to realise that I had to put my own coordinates in the Main.Border := {} section of choice. I kept thinking it needed any Border to have a vector of origin but nope, it was my 'main border' of my curve graph it needed. It's obvious now.
Thanks again and love your youtube videos.
This script I created is a game-changer in my industry and pretty excited.

Cheers from Australia Down Under! :thumbup:
Steve.

User avatar
Hellbent
Posts: 2102
Joined: 23 Sep 2017, 13:34

Re: Point of two intersecting lines at 90 degree

Post by Hellbent » 31 Dec 2021, 16:26

SteveMylo wrote:
27 Dec 2021, 06:25
Hellbent wrote:
26 Dec 2021, 16:36
I think that I have the bases covered.
Absolute legend :clap: Watched the videos and read your comments about 20 times.
Took me a few goes to realise that I had to put my own coordinates in the Main.Border := {} section of choice. I kept thinking it needed any Border to have a vector of origin but nope, it was my 'main border' of my curve graph it needed. It's obvious now.
Thanks again and love your youtube videos.
This script I created is a game-changer in my industry and pretty excited.

Cheers from Australia Down Under! :thumbup:
Steve.
Happy New Year.

I'm glad that I was able to help.

The origin point is the reference point that gives your numbers meaning. For you, the origin point would be based on the [coordMode] that you use. Setting the mode sets where 0,0 is and that is the position that gives a value of say 300 a meaning of 300 as you see it.

A second point is that your monitor only shows / uses one quadrant of a x/y grid, and the Y axis is flipped. So if your monitor has 0,0 in the top left corner then you only see the bottom left quad of the grid.

Another point is that the vector subtraction, adding, extending, etc. is just to get a vector that is on the outside of your border ( as you know now, the border is a set of lines that you set the values for ), the rest is just using the line intercept equation that was used in the examples just before your question. In other words, the question of finding where your line crossed the border was already answered in this thread, you were only missing how to get the points of your line, which is what the subtracting , extending, and adding vectors does.

Post Reply

Return to “Ask for Help (v1)”