ChartsOrg / ChartsOrg/Charts

[Unknown process name] CGAffineTransformInvert: singular matrix

Open
#5,160 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
28k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

```
class StencilQuadView: UIImageView {
var addFreeTool: (() -> ())?

override init(frame: CGRect) {
super.init(frame: frame)
self.layer.anchorPoint = .zero
self.isUserInteractionEnabled = true
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.anchorPoint = .zero
}

// Function to transform the view to fit specified quad
func transformToFitQuadTopLeft(tl: CGPoint, tr: CGPoint, bl: CGPoint, br: CGPoint) {
guard self.layer.anchorPoint == .zero else {
return
}
let b = boundingBoxForQuadTR(tl, tr, bl, br)
self.frame = b
self.layer.transform = rectToQuad(bounds,
.init(x: tl.x-b.origin.x, y: tl.y-b.origin.y),
.init(x: tr.x-b.origin.x, y: tr.y-b.origin.y),
.init(x: bl.x-b.origin.x, y: bl.y-b.origin.y),
.init(x: br.x-b.origin.x, y: br.y-b.origin.y))
}

// Helper function to calculate bounding box for the quad
private func boundingBoxForQuadTR(_ tl: CGPoint, _ tr: CGPoint, _ bl: CGPoint, _ br: CGPoint) -> CGRect {
let xmin = min(tl.x, tr.x, bl.x, br.x)
let ymin = min(tl.y, tr.y, bl.y, br.y)
let xmax = max(tl.x, tr.x, bl.x, br.x)
let ymax = max(tl.y, tr.y, bl.y, br.y)
return CGRect(x: xmin, y: ymin, width: xmax - xmin, height: ymax - ymin)
}

// Function to calculate the CATransform3D for a quad
func rectToQuad(_ rect: CGRect,
_ topLeft: CGPoint, _ topRight: CGPoint, _ bottomLeft: CGPoint, _ bottomRight: CGPoint) -> CATransform3D {
rectToQuadCalculation(rect,
topLeft.x, topLeft.y,
topRight.x, topRight.y,
bottomLeft.x, bottomLeft.y,
bottomRight.x, bottomRight.y)
}

// Function to perform the rect to quad calculation
func rectToQuadCalculation(_ rect: CGRect,
_ x1a: CGFloat, _ y1a: CGFloat,
_ x2a: CGFloat, _ y2a: CGFloat,
_ x3a: CGFloat, _ y3a: CGFloat,
_ x4a: CGFloat, _ y4a: CGFloat) -> CATransform3D {
let XX = rect.origin.x
let YY = rect.origin.y
let WW = rect.size.width
let HH = rect.size.height

let y21 = y2a - y1a
let y32 = y3a - y2a
let y43 = y4a - y3a
let y14 = y1a - y4a
let y31 = y3a - y1a
let y42 = y4a - y2a

let a = -HH * (x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42)
let b = WW * (x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43)

let c0 = -HH * WW * x1a * (x4a*y32 - x3a*y42 + x2a*y43)
let cx = HH * XX * (x2a*x3a*y14 + x2a*x4a*y31 - x1a*x4a*y32 + x1a*x3a*y42)
let cy = -WW * YY * (x2a*x3a*y14 + x3a*x4a*y21 + x1a*x4a*y32 + x1a*x2a*y43)
let c = c0 + cx + cy
let d = HH * (-x4a*y21*y3a + x2a*y1a*y43 - x1a*y2a*y43 - x3a*y1a*y4a + x3a*y2a*y4a)
let e = WW * (x4a*y2a*y31 - x3a*y1a*y42 - x2a*y31*y4a + x1a*y3a*y42)

let f0 = -WW * HH * (x4a * y1a * y32 - x3a * y1a * y42 + x2a * y1a * y43)
let fx = HH * XX * (x4a * y21 * y3a - x2a * y1a * y43 - x3a * y21 * y4a + x1a * y2a * y43)
let fy = -WW * YY * (x4a * y2a * y31 - x3a * y1a * y42 - x2a * y31 * y4a + x1a * y3a * y42)
let f = f0 + fx + fy
let g = HH * (x3a * y21 - x4a * y21 + (-x1a + x2a) * y43)
let h = WW * (-x2a * y31 + x4a * y31 + (x1a - x3a) * y42)

let iy = WW * YY * (x2a * y31 - x4a * y31 - x1a * y42 + x3a * y42)
let ix = HH * XX * (x4a * y21 - x3a * y21 + x1a * y43 - x2a * y43)
let i0 = HH * WW * (x3a * y42 - x4a * y32 - x2a * y43)
var i = i0 + ix + iy
let kEpsilon: CGFloat = 0.0001
if abs(i) < kEpsilon {
i = kEpsilon * (i > 0 ? 1 : -1)
}

return CATransform3D(
m11: a/i, m12: d/i, m13: 0, m14: g/i,
m21: b/i, m22: e/i, m23: 0, m24: h/i,
m31: 0, m32: 0, m33: 1, m34: 0,
m41: c/i, m42: f/i, m43: 0, m44: 1.0)
}
}

struct DragView{
var cornerTag: Int?
var frame: CGRect?
var radius: Int?
var stencilId: Int?
var center: CGPoint?
var updatedIndex: Int?
var stencilQuadView: StencilQuadView?
}

class DraggableCorner: UIView {

var drag: ((CGPoint) -> Void)?
var isDragDone: (((Bool, CGPoint, Int)) -> Void)?
var stencilId: Int = 0

override init(frame: CGRect) {
super.init(frame: frame)
initialize()
}

required init?(coder: NSCoder) {
super.init(coder: coder)
initialize()
}

private func initialize() {
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
self.addGestureRecognizer(panGesture)
}

@objc private func panGestureAction(_ gesture: UIPanGestureRecognizer) {
let translation = gesture.translation(in: self.superview)
guard let superview = superview else { return }
self.center = CGPoint(x: self.center.x + translation.x, y: self.center.y + translation.y)
gesture.setTranslation(.zero, in: superview)
if gesture.state == .ended {
isDragDone?((true, self.center, stencilId))
}
else{
drag?(self.center)
}
}
}

```
From the above code I have attached four new corners for the image view and as soon as I drag the image is changing to any quadrilateral but when I do more operation the image is hiding and the error is showing please anyone help!

Contributor guide

Open the contributing guide

Research direction

Start with the supplied StencilQuadView.transformToFitQuadTopLeft and rectToQuadCalculation code, then reproduce repeated corner drags that produce the CGAffineTransformInvert warning. Compare the quad inputs and calculated transform before the image hides; done means identifying a reproducible cause and documenting a project-specific fix or test.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
mobile
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.