1 Star 0 Fork 2

chenyp401/CAM

forked from zzthfut/CAM 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
GeomAlgo.py 7.23 KB
一键复制 编辑 原始数据 按行查看 历史
zzthfut 提交于 2023-08-15 15:49 . 9-16
from GeomBase import Matrix3D, Point3D, Vector3D, epsilon
from Ray import Ray
from Segment import Segment
from Line import Line
from Polyline import Polyline
from Plane import Plane
from Triangle import Triangle
import math
def nearZero(x):
if math.fabs(x) < epsilon:
return True
else:
return False
def distance(obj1, obj2):
if isinstance(obj1, Point3D) and isinstance(obj2, Line):
P, Q, V = obj2.P, obj1, obj2.V
t = P.pointTo(Q).dotProduct(V)
R = P + V.amplified(t)
return Q.distance(R)
elif isinstance(obj1, Point3D) and isinstance(obj2, Ray):
P, Q, V = obj2.P, obj1, obj2.V
t = P.pointTo(Q).dotProduct(V)
if t > 0:
R = P + V.amplified(t)
return Q.distance(R)
return Q.distance(P)
elif isinstance(obj1, Point3D) and isinstance(obj2, Segment):
Q, P, P1, V = obj1, obj2.A, obj2.B, obj2.direction().normalized()
L = obj2.length()
t = P.pointTo(Q).dotProduct(V)
if t <= 0:
return Q.distance(P)
elif t >= L:
return Q.distance(P1)
else:
R = P + V.amplified(t)
return Q.distance(R)
elif isinstance(obj1, Point3D) and isinstance(obj2, Plane):
P, Q, N = obj2.P, obj1, obj2.N
angle = N.getAngle(P.pointTo(Q))
return P.distance(Q) * math.cos(angle)
elif isinstance(obj1, Line) and isinstance(obj2, Line):
P1, V1, P2, V2 = obj1.P, obj1.V, obj2.P, obj2.V
N = V1.crossProduct(V2)
if N.isZeroVector():
return distance(P1, obj2)
return distance(P1, Plane(P2, N))
elif isinstance(obj1, Line) and isinstance(obj2, Plane):
if obj1.V.crossProduct(obj2.N).isZeroVector():
return distance(obj1.P, obj2)
else:
return 0
elif isinstance(obj1, Ray) and isinstance(obj2, Plane):
pass
elif isinstance(obj1, Segment) and isinstance(obj2, Plane):
pass
def intersectLineLine(line1: Line, line2: Line):
P1, V1, P2, V2 = line1.P, line1.V, line2.P, line2.V
P1P2 = P1.pointTo(P2)
deno = V1.dy * V2.dx - V1.dx * V2.dy
if deno != 0:
t1 = -(-P1P2.dy * V2.dx + P1P2.dx * V2.dy) / deno
t2 = -(-P1P2.dy * V1.dx + P1P2.dx * V1.dy) / deno
return P1 + V1.amplified(t1), t1, t2
else:
deno = V1.dz * V2.dy - V1.dy * V2.dz
if deno != 0:
t1 = -(-P1P2.dz * V2.dy + P1P2.dy * V2.dz) / deno
t2 = -(-P1P2.dz * V1.dy + P1P2.dy * V1.dz) / deno
return P1 + V1.amplified(t1), t1, t2
return None, 0, 0
def intersectSegmentPlane(seg: Segment, plane: Plane):
A, B, P, N = seg.A, seg.B, plane.P, plane.N
V = A.pointTo(B)
PA = P.pointTo(A)
if V.dotProduct(N) == 0:
return None
else:
t = -(PA.dotProduct(N)) / V.dotProduct(N)
if t >= 0 and t <= 1:
return A + (V.amplified(t))
return None
def intersect(obj1, obj2):
if isinstance(obj1, Line) and isinstance(obj2, Line):
P, t1, t2 = intersectLineLine(obj1, obj2)
return P
elif isinstance(obj1, Segment) and isinstance(obj2, Segment):
line1, line2 = Line(obj1.A, obj1.direction()), Line(obj2.A, obj2.direction())
P, t1, t2 = intersectLineLine(line1, line2)
if P is not None:
if t1 >= 0 and t1 <= obj1.length() and t2 >= 0 and t2 <= obj2.length():
return P
return None
elif isinstance(obj1, Line) and isinstance(obj2, Segment):
line1, line2 = obj1, Line(obj2.A, obj2.direction())
P, t1, t2 = intersectLineLine(line1, line2)
if P:
if t2 >= 0 and t2 <= obj2.length():
return P
else:
return None
elif isinstance(obj1, Line) and isinstance(obj2, Ray):
pass
elif isinstance(obj1, Ray) and isinstance(obj2, Segment):
pass
elif isinstance(obj1, Ray) and isinstance(obj2, Ray):
pass
elif isinstance(obj1, Line) and isinstance(obj2, Plane):
P1, V, P2, N = obj1.P, obj1.V, obj2.P, obj2.N
dotPro = V.dotProduct(N)
if dotPro != 0:
t = P1.pointTo(P2).dotProduct(N) / dotPro
return P1 + V.amplified(t)
return None
elif isinstance(obj1, Ray) and isinstance(obj2, Plane):
pass
elif isinstance(obj1, Segment) and isinstance(obj2, Plane):
return intersectSegmentPlane(obj1, obj2)
pass
def pointOnRay(p: Point3D, ray: Ray):
v = ray.P.pointTo(p)
return (
True
if v.dotProduct(ray.V) >= 0 and v.crossProduct(ray.V).isZeroVector()
else False
)
def pointInPolygon(p: Point3D, polygon: Polyline):
passCount = 0
ray = Ray(p, Vector3D(1, 0, 0))
segments = []
for i in range(polygon.count() - 1):
seg = Segment(polygon.point(i), polygon.point(i + 1))
segments.append(seg)
for seg in segments:
line1, line2 = Line(ray.P, ray.V), Line(seg.A, seg.direction())
P, t1, t2 = intersectLineLine(line1, line2)
if P is not None:
if nearZero(t1):
return -1
elif (
seg.A.y != p.y
and seg.B.y != p.y
and t1 > 0
and t2 > 0
and t2 < seg.length()
):
passCount += 1
upSegments, downSegments = [], []
for seg in segments:
if seg.A.isIdentical(ray.P) or seg.B.isIdentical(ray.P):
return -1
elif pointOnRay(seg.A, ray) ^ pointOnRay(seg.B, ray):
if seg.A.y >= p.y and seg.B.y >= p.y:
upSegments.append(seg)
elif seg.A.y <= p.y and seg.B.y <= p.y:
downSegments.append(seg)
passCount += min(len(upSegments), len(downSegments))
if passCount % 2 == 1:
return 1
return 0
def intersectTrianglePlane(triangle, plane):
AB = Segment(triangle.A, triangle.B)
AC = Segment(triangle.A, triangle.C)
BC = Segment(triangle.B, triangle.C)
c1 = intersectSegmentPlane(AB, plane)
c2 = intersectSegmentPlane(AC, plane)
c3 = intersectSegmentPlane(BC, plane)
if c1 is None:
if c2 is not None and c3 is not None:
if c2.distance(c3) != 0:
return Segment(c2, c3)
elif c2 is None:
if c1 is not None and c3 is not None:
if c1.distance(c3) != 0:
return Segment(c1, c3)
elif c3 is None:
if c2 is not None and c1 is not None:
if c1.distance(c2) != 0:
return Segment(c1, c2)
if c1 and c2 and c3:
if c1.distance(c2) != 0:
return Segment(c1, c2)
else:
return Segment(c1, c3)
return None
def intersectTriangleZPlane(triangle: Triangle, z):
if triangle.zMinPnt() > z:
return None
if triangle.zMaxPnt() < z:
return None
return intersectTrianglePlane(triangle, Plane.zPlane(z))
def rotatePolygons(polygons, angle, center=None):
dx = 0 if not center else center.x
dy = 0 if not center else center.y
mt = Matrix3D.createTranlsateMatrix(-dx, -dy, 0)
mr = Matrix3D.createRotateMatrix("Z", angle)
mb = Matrix3D.createTranlsateMatrix(dx, dy, 0)
m = mt * mr * mb
newpolys = []
for poly in polygons:
newpolys.append(poly.multiplied(m))
return newpolys
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/chenyp401/cam.git
git@gitee.com:chenyp401/cam.git
chenyp401
cam
CAM
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385