Notifications
Clear all

[Closed] measure angle

I trying to write simple tool for measure angle and show the show (draw) ang. value in viewpor.
I found some example by DenisT and make some minor modifications. For now everything works fine except angle calculation.
– When I hold Shift key at the first click point appears green rectangle
– This rectangle will change color to red every time when the angle has a value of 0,45,90,135,180,225,270,315 deg.
– In 3D view (perspective, user and camera) value of the angle is displayed correctly but in 2D view not.
Next image shows what I want to achive

#1 For now angle value is in the range 0 – 180deg and need to be in the range 0 – 360deg
#2 Support for angle snap (when shift is pressed) 5deg
#3 To works correctly in 2D and 3D views (parallel to view plane)


try(destroydialog ::testRoll) catch()
unRegisterRedrawViewsCallback drawTest
rollout testRoll "Measure"
(
	global world_points = #(), mt_ir = undefined
	fn getAngle a: b: c: = ((acos(dot ((b-a)/distance a b) ((c-a)/distance a c))) as float)
	fn pointPlaneProj p1: p2: n: = p2+((dot (p1-p2) n)*n)
	
	fn drawTest = if world_points.count > 0 and mt_ir != undefined do
	(
		if world_points.count == 2 do free world_points
		gw.setTransform (matrix3 1)
		local gw_points = for p in world_points collect (gw.transPoint p)
		append gw_points (gw.transPoint mt_ir.pos)
		if keyboard.shiftpressed then 
		(
			local ang = getAngle a:gw_points[1] b:(gw_points[1]+[30,0,0]) c:(pointPlaneProj p1:gw_points[1] p2:gw_points[gw_points.count] n:mt_ir.dir) as string
			gw.wPolyline #((gw_points[1]+[30,0,0]) , (gw_points[1]+[0,-30,0]) , (gw_points[1]+[-30,0,0]) , (gw_points[1]+[0,30,0])) on \
			rgb:(if findItem #("0.0","45.0","90.0","135.0","180.0") ang != 0 then #(red,red,red,red) else #(green,green,green,green))
			gw.wText (gw_points[1]+[-10,20,-1e5]) (ang+"°") color:white
		)
		for k = 2 to gw_points.count do 
		(
			gw.wPolyline #(gw_points[k-1], gw_points[k]) off rgb:#(green,green)
			gw.wMarker gw_points[k-1] #circle color:yellow
			gw.wMarker gw_points[k] #circle color:yellow
			gw.wText (gw_points[k]+[10,-5,-1e5]) (units.formatValue (distance world_points[1] mt_ir.pos)) color:white
		)
		gw.enlargeUpdateRect #whole
		gw.updateScreen()
	)
	fn mouseTracking msg ir obj faceNum shift ctrl alt =
	(
		mt_ir = ir
		if ctrl do (actionMan.executeAction 1261319018 "Viewports" )
		case of
		(
			(msg == #freeMove or msg == #mouseMove): if world_points.count > 0 do completeRedraw()
			(msg == #mousePoint): append world_points ir.pos
		)
		if msg == #mouseAbort then #abort else #continue
	)
	button btn "T E S T" pos:[5,5] width:140 height:40
	on btn pressed do
	(
		world_points = #()
		registerRedrawViewsCallback drawTest
		mouseTrack trackCallback:mouseTracking snap:#3D
		unRegisterRedrawViewsCallback drawTest ; completeRedraw()
	)
)	
createDialog testRoll 150 50 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)

I don’t know is it possible to achive similal behavior with scripted manipulator.