I want to modify a script that I am working on such that it ends a loop when there is an intersection/collision (I'm not sure how best to describe the actual intersection event in this particular situation since the objects are inside each other) between two planes (plane A and plane B). The loop rotates plane A and at a certain degree of rotation plane A intersects plane B, which is static.
I've seen/tried to use solutions that involve BHVtree but I haven't been able to get them working. I've also tried boolean operations (intersect, subtract, etc), but they don't seem to do anything differently from when the objects intersect (or 'stop intersecting'?).
I am working with primative 2d planes and plane A is inside plane B. In the below wireframe images, the 'yellow' selected object and the 'red' selected object are what I am referring to as plane A and plane B, respectively.
This image shows a given rotation in which plane A DOES NOT intersect with plane B
This image shows a second rotation in which plane A DOES intersect with plane B. I would like to be able to identity when this event occurs within my script.
UPDATED: Based on batFINGER's suggestion, I looked into intersect_line_sphere_2d from mathutils.geometry. Thank you very much for pointing me to it.
I wrote a script based on that particular function, which works but not correctly. I think my math/trig is off somewhere because the angle reported is larger than expected, and the angle should decrease as the scale is increased.
Below is the script:
# testing script for predicting rotation-based collision angle thresholds
# output is not correct. Increasing scale should give lower roll angle tolerance, also roll angle values are not accurate as compared by other methods. Code needs to be adjusted.
#--------
# imports
#--------
import bpy
import numpy as np
from math import cos
from math import sin
import mathutils
from mathutils.geometry import intersect_line_sphere_2d
#----------
# functions
#----------
# function converts from degrees to radians
def radians(num):
result = (num) * (np.pi/180)
return result
# function converts from radians to degrees
def degrees(num):
result = (num) * (180/np.pi)
return result
#----------
# variables
#----------
relativeRadius = 0.3 #relevant for actual objects being tested
scalePercentage = 0.80 #percentage
radiusOne=relativeRadius*0.1 #relevant to actual objects being tested
leftAdjustment = (radiusOne)*(1-scalePercentage)*(0.5) #relevant to placement of actual object
theta = 225.0 #represents starting point on the circumference of the rotational pathway, e.g., bottom left corner of square
radTheta = radians(theta) #convert to radians for trig functions
# variables for the intersect_line_sphere_2d function
lineA = mathutils.Vector (( -radiusOne+leftAdjustment, -radiusOne)) #bottom left and moved to the right to compensate for the left adjustment that is typically applied to the actual object
lineB = mathutils.Vector (( -radiusOne+leftAdjustment, radiusOne)) #top left and moved to the right to compensate for the left adjustment that is typically applied to the actual object
xPos=cos(radTheta)*radiusOne
yPos=sin(radTheta)*radiusOne
locationCircle = mathutils.Vector ((xPos, yPos))
radiusCircle = 0.0000001 #very small to make it a 2d 'point' rather than a circle
#amount of change in degrees for testing roll angle tolerance
incrementsInDegrees= 0
incrementInRadians= radians(incrementsInDegrees)
numberOfTests=0 #added in case scale is TOO SMALL in which case the loop would continue without end and probably crash blender; an alternative would be to just use something like a 90 degree angle check as security against an infinite loop
#----------
# main loop:
#----------
#set beginning of intersect_line_ function to starting position of object bottom left corner
i = intersect_line_sphere_2d(lineA, lineB, locationCircle, radiusCircle)
while i[0] == None and i[0] == None and numberOfTests < 50000:
numberOfTests += 1
incrementsInDegrees += 0.01
incrementInRadians= radians(incrementsInDegrees)
xPos = cos(radTheta-incrementInRadians)*radiusOne
yPos = sin(radTheta-incrementInRadians)*radiusOne
locationCircle = mathutils.Vector ((xPos, yPos))
i = intersect_line_sphere_2d(lineA, lineB, locationCircle, radiusCircle)
#--------------------------
# print results to console:
#--------------------------
rollAngleToleranceInDegrees = str(incrementsInDegrees)
numberOfAnglesAttempted = str(numberOfTests)
print("roll angle tolerance is: %s" % (rollAngleToleranceInDegrees))
print("number of angles attempted: %s" % (numberOfAnglesAttempted))
mathutls.geometry
. in particular intersect line with circle. Given a pivot point calculate the paths of each corner (the circle) , where they hit "the lines" or edges of other planes., and hence the range of rotation possible before you rotate, rather than checking for collision while you are rotating Oh and I always recommend pasting script , or link to, of what you have so far $\endgroup$