I have this swift code:
x = Float(arc4random_uniform(30))
y = Float(arc4random_uniform(30))
z = Float(arc4random_uniform(30))
coords.x = 0.00 - x
coords.y = 0.00 - y
coords.z = 0.00 - z
print("\(coords.x) \(coords.y) \(coords.z) xyz")
For some reason it always outputs the numbers as positive, I have also tried:
x = -Float(arc4random_uniform(30))
y = -Float(arc4random_uniform(30))
z = -Float(arc4random_uniform(30))
coords.x = x
coords.y = y
coords.z = z
and...
x = -1 * Float(arc4random_uniform(30))
y = -1 * Float(arc4random_uniform(30))
z = -1 * Float(arc4random_uniform(30))
coords.x = x
coords.y = y
coords.z = z
...and even one more where I had to cast the random number as an Int to multiply it by -1 within the Float cast.
x = Float(-1*Int(arc4random_uniform(30)))
...
The console output is always something like:
24.0 27.0 29.0 xyz
...no negative numbers.
What am I doing wrong?
EDIT
coords is of type MyDict which I created:
class MyDict : NSDictionary {
var x: Float = 0.0
var y: Float = 0.0
var z: Float = 0.0
}
This is how I am printing the values:
print("\(coords.x) \(coords.y) \(coords.z) xyz")
EDIT
MyDict is now:
struct Coords {
var x: Float = 0.0
var y: Float = 0.0
var z: Float = 0.0
}
EDIT
Code for context - this is happening in a loop:
for nodeInnermost in nodeInner.childNodes {
if (nodeInnermost.name?.localizedStandardContains("ship"))! {
print(nodeInnermost.childNodes.first ?? "FIRST DOESNT EXIST")
var seqArray = [fadeOut, fadeIn]
var displacements = [] as Array<Coords>
var count = 0
var coords = Coords()
while count < 5 {
if childCount < 5 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 4 && childCount < 10 {
coords.x = -Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 9 && childCount < 15 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 14 && childCount < 20 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 19 && childCount < 25 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 24 && childCount < 30 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 29 && childCount < 35 {
coords.x = Float(arc4random_uniform(30))
coords.y = Float(arc4random_uniform(30))
coords.z = Float(arc4random_uniform(30))
}
else if childCount > 34 && childCount < 40 {
coords.x = -Float(arc4random_uniform(30))
coords.y = -Float(arc4random_uniform(30))
coords.z = -Float(arc4random_uniform(30))
}
//print("\(x) \(y) \(z) xyz")
displacements.append(coords)
print("\(coords.x) \(coords.y) \(coords.z) xyz")
let moveBy = SCNAction.move(by: SCNVector3Make(coords.x, coords.y, coords.z), duration: 0.5)
seqArray.append(fadeOut)
seqArray.append(moveBy)
seqArray.append(fadeIn)
count+=1
}
while count < 10 {
let moveBy = SCNAction.move(by: SCNVector3Make(displacements[9 - count].x, displacements[9 - count].y, displacements[9 - count].z), duration: 0.5)
seqArray.append(fadeOut)
seqArray.append(moveBy)
seqArray.append(fadeIn)
count+=1
}
let sequence = SCNAction.sequence(seqArray)
let animation = SCNAction.repeatForever(sequence)
nodeInnermost.childNodes.first?.runAction(animation)
}
}
SAMPLE OUTPUT:
https://pastebin.com/Ak1pb6wP
It makes no sense for your MyDict to extend NSDictionary nor should it be a class. Once you make it a proper struct, your code works fine.
struct MyDict {
var x: Float = 0.0
var y: Float = 0.0
var z: Float = 0.0
}
var coords = MyDict()
coords.x = -Float(arc4random_uniform(30))
coords.y = -Float(arc4random_uniform(30))
coords.z = -Float(arc4random_uniform(30))
print("\(coords.x) \(coords.y) \(coords.z) xyz")
Output:
-24.0 -28.0 -4.0 xyz
Related
When some values are small in QML pie chart, slice labels are messed up:
How can I arrange slice labels like this?
Note that this is available in telerik and /or dev components for c#.
I used of #luffy 's comment and with some modification, I reached to following code and result:
import QtQuick 2.4
Rectangle {
id: root
// public
property string fontFamily: "sans-serif"
property int fontPointSize: 9
property double donutHoleSize: 0.4 //0~1
property string title: 'title'
property variant points: []//[['Zero', 60, 'red'], ['One', 40, 'blue']] // y values don't need to add to 100
width: 500
height: 700
// private
onPointsChanged: myCanvas.requestPaint()
Canvas {
id: myCanvas
anchors.fill: parent
property double factor: Math.min(width, height)
Text { // title
text: title
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 0.03 * myCanvas.factor
}
onPaint: {
var context = getContext("2d")
var total = 0 // automatically calculated from points.y
var start = -Math.PI / 2 // Start from vertical. 0 is 3 o'clock and positive is clockwise
var radius = 0.25 * myCanvas.factor
var pixelSize = 0.03 * myCanvas.factor // text
context.font = root.fontPointSize + 'pt ' + root.fontFamily
var i = 0;
for(i = 0; i < points.length; i++) total += points[i][1] // total
context.clearRect(0, 0, width, height) // new points data
//--------------------------------------------------------
var end = 0;
var center = 0;
var angle = 0;
var midSlice = 0;
var point = 0;
var topRightCnt = 0
var bottomRightCnt = 0
var topLeftCnt = 0
var bottomLeftCnt = 0
var itemsPos = []
center = Qt.vector2d(width / 2, height / 2) // center
for(i = 0; i < points.length; i++) {
end = start + 2 * Math.PI * points[i][1] / total // radians
angle = (start + end) / 2 // of line
midSlice = Qt.vector2d(Math.cos((end + start) / 2), Math.sin((end + start) / 2)).times(radius) // point on edge/middle of slice
point = midSlice.times(1 + 1.4 * (1 - Math.abs(Math.cos(angle)))).plus(center) // elbow of line
if(point.x<center.x && point.y<=center.y) {
topLeftCnt++;
itemsPos[i] = "tl"
}
else if(point.x<center.x && point.y>center.y) {
bottomLeftCnt++;
itemsPos[i] = "bl"
}
else if(point.x>=center.x && point.y<=center.y) {
topRightCnt++;
itemsPos[i] = "tr"
}
else {
bottomRightCnt++;
itemsPos[i] = "br"
}
start = end // radians
}
//--------------------------------------------------------
end = 0;
angle = 0;
midSlice = 0;
point = 0;
var itemPosCounterTR = 0;
var itemPosCounterTL = 0;
var itemPosCounterBR = 0;
var itemPosCounterBL = 0;
for(i = 0; i < points.length; i++) {
end = start + 2 * Math.PI * points[i][1] / total // radians
// pie
context.fillStyle = points[i][2]
context.beginPath()
midSlice = Qt.vector2d(Math.cos((end + start) / 2), Math.sin((end + start) / 2)).times(radius) // point on edge/middle of slice
context.arc(center.x, center.y, radius, start, end) // x, y, radius, startingAngle (radians), endingAngle (radians)
context.lineTo(center.x, center.y) // center
context.fill()
// text
context.fillStyle = points[i][2]
angle = (start + end) / 2 // of line
point = midSlice.times(1 + 1.4 * (1 - Math.abs(Math.cos(angle)))).plus(center) // elbow of line
//---------------------------------------------
var textX = 0;
var textY = 0;
var dis = 0;
var percent = points[i][1] / total * 100
var text = points[i][0] + ': ' + (percent < 1? '< 1': Math.round(percent)) + '%' // display '< 1%' if < 1
var textWidth = context.measureText(text).width
var textHeight = 15
var diameter = radius * 2
var topCircle = center.y - radius
var leftCircle = center.x - radius
if(itemsPos[i] === "tr") {
textX = leftCircle + 1.15 * diameter
dis = Math.floor((1.15*radius) / topRightCnt) //Math.floor((height/2) / topRightCnt)
dis = (dis < 20 ? 20 : dis)
textY = topCircle -(0.15*diameter) + (itemPosCounterTR*dis) + (textHeight/2)
itemPosCounterTR++
}
else if(itemsPos[i] === "br") {
textX = leftCircle + 1.15 * diameter
dis = Math.floor((1.15*radius) / bottomRightCnt)
dis = (dis < 20 ? 20 : dis)
textY = topCircle+(1.15*diameter) - ((bottomRightCnt-itemPosCounterBR-1)*dis) - (textHeight/2)
itemPosCounterBR++
}
else if(itemsPos[i] === "tl") {
textX = leftCircle - (0.15 * diameter) - textWidth
dis = Math.floor((1.15*radius) / topLeftCnt)
dis = (dis < 20 ? 20 : dis)
textY = topCircle-(0.15*diameter) + ((topLeftCnt-itemPosCounterTL-1)*dis) + (textHeight/2)
itemPosCounterTL++;
}
else {
textX = leftCircle - (0.15 * diameter) - textWidth //-0.2 * width - textWidth
dis = Math.floor((1.15*radius) / bottomLeftCnt)
dis = (dis < 20 ? 20 : dis)
textY = topCircle+(1.15*diameter) - (itemPosCounterBL*dis) - (textHeight/2)
itemPosCounterBL++
}
//---------------------------------------------
context.fillText(text, textX, textY)
// line
context.lineWidth = 1
context.strokeStyle = points[i][2]
context.beginPath()
context.moveTo(center.x + midSlice.x, center.y + midSlice.y) // center
var endLineX = (point.x < center.x ? (textWidth + 0.5 * pixelSize) : (-0.5 * pixelSize)) + textX;
context.lineTo(endLineX, textY+3)
context.lineTo(endLineX + (point.x < center.x? -1: 1) * ((0.5 * pixelSize)+textWidth), textY+3) // horizontal
context.stroke()
start = end // radians
}
if(root.donutHoleSize > 0) {
root.donutHoleSize = Math.min(0.99, root.donutHoleSize);
var holeRadius = root.donutHoleSize * radius;
context.fillStyle = root.color
context.beginPath()
context.arc(center.x, center.y, holeRadius, 0, 2*Math.PI) // x, y, radius, startingAngle (radians), endingAngle (radians)
//context.lineTo(center.x, center.y) // center
context.fill()
}
}
}
}
And it's result:
Thanks #luffy.
I have a small problem in rounded numbers to the nearest 10
var finalResult = Int(textfield.text!)
let x = Double(finalResult)
let y = x.rounded() / 5
print(x) // 18.0
print(y) // 3.6
i want result to be like this
// if x = 6.0 ... 14.0
// y = 2
// if x = 15.0
// y = 3
// if x = 16.0 ... 24.0
// y = 4
// if x = 25.0
// y = 5
// if x = 26.0 ... 34.0
// y = 6
I hope I have asked a question that benefits me and others
I hope that I have explained the question well
You need to use round function and x % 5 == 0 check.
let values = (6...100).map({ Double($0) })
func round(_ value: Double, toNearest: Double) -> Double {
return round(value / toNearest) * toNearest
}
for x in values {
if x.truncatingRemainder(dividingBy: 5) == 0 {
print("x - \(x), y - \(Int(x / 5))")
} else {
let rounded = round(x, toNearest: 10.0)
print("x - \(x), y - \(Int(rounded / 5))")
}
}
I just created a rectangle using four vertices in metal. I just need to rotate it. So I use a model metrics.Here is my vertex shader.
vertex VertexOutTexture vertex_shader_texture(const VertexInTexture vertices [[stage_in]],
constant ModelConstant &modelConstants[[buffer(1)]],
VertexOutTexture v;
v.position = modelConstants.modelMatrix*float4(vertices.position,1);
v.color = vertices.color;
v.textureCoordinates = vertices.textureCoordinates;
return v;
}
it rotate. But shape is changed. So I used projection transformation which converts the node’s coordinates from camera coordinates to normalized coordinates.
I create projrction matrix:
var sceneConstants = ScenceConstants()
set its value:
sceneConstants.projectionMatrix = matrix_float4x4(prespectiveDegreesFov:45, aspectRatio:Float(1.0),nearZ:0.1,farZ:100)
where init mathod is in math.h
init(prespectiveDegreesFov degreesFov:Float, aspectRatio:Float,nearZ:Float,farZ:Float){
let fov = radians(fromDegrees: degreesFov)
let y = 1/tan(fov*0.5)
let x = y/aspectRatio
let z1 = farZ/(nearZ - farZ)
let w = (z1*nearZ)
columns = (
float4(x, 0, 0, 0),
float4(0, y, 0, 0),
float4(0, 0, z1,-1),
float4(0, 0, w, 0)
)
}
send commands to GPU:
commandEncoder.setVertexBytes(&sceneConstants, length: MemoryLayout<ScenceConstants>.stride, index: 2)
change my vertex shader:
v.position = sceneConstants.projectionMatrix* modelConstants.modelMatrix*float4(vertices.position ,1 );
But it did not work.
before rotation:
after rotation:
I have atached math functions I am using below.
func radians(fromDegrees degrees:Float) ->Float{
return (degrees/100)*Float(Double.pi)
}
extension matrix_float4x4 {
init(prespectiveDegreesFov degreesFov:Float, aspectRatio:Float,nearZ:Float,farZ:Float){
let fov = radians(fromDegrees: degreesFov)
let y = 1/tan(fov*0.5)
let x = y/aspectRatio
let z1 = farZ/(nearZ - farZ)
let w = (z1*nearZ)
columns = (
float4(x, 0, 0, 0),
float4(0, y, 0, 0),
float4(0, 0, z1,-1),
float4(0, 0, w, 0)
)
}
mutating func scale(axis: float3){
var result = matrix_identity_float4x4
let x :Float = axis.x
let y :Float = axis.y
let z :Float = axis.z
result.columns = (
float4(x,0,0,0),
float4(0,y,0,0),
float4(0,0,z,0),
float4(0,0,0,1)
)
print("self:\(self)")
self = matrix_multiply(self, result)
}
mutating func translate(direction: float3){
var result = matrix_identity_float4x4
let x :Float = direction.x
let y :Float = direction.y
let z :Float = direction.z
result.columns = (
float4(1,0,0,0),
float4(0,1,0,0),
float4(0,0,1,0),
float4(x,y,z,1)
)
print("self:\(self)")
self = matrix_multiply(self, result)
}
mutating func rotate(angle: Float ,axis: float3){
var result = matrix_identity_float4x4
let x :Float = axis.x
let y :Float = axis.y
let z :Float = axis.z
let c: Float = cos(angle)
let s:Float = sin(angle)
let mc :Float = (1 - c)
let r1c1: Float = x * x * mc + c
let r2c1: Float = x * y * mc + z * s
let r3c1: Float = x * z * mc - y * s
let r4c1: Float = 0.0
let r1c2: Float = y * x * mc - z * s
let r2c2: Float = y * y * mc + c
let r3c2: Float = y * z * mc + x * s
let r4c2: Float = 0.0
let r1c3: Float = z * x * mc + y * s
let r2c3: Float = z * y * mc - x * s
let r3c3: Float = z * z * mc + c
let r4c3: Float = 0.0
let r1c4: Float = 0.0
let r2c4: Float = 0.0
let r3c4: Float = 0.0
let r4c4: Float = 1.0
result.columns = (
float4(r1c1,r2c1,r3c1,r4c1),
float4(r1c2,r2c2,r3c2,r4c2),
float4(r1c3,r2c3,r3c3,r4c3),
float4(r1c4,r2c4,r3c4,r4c4)
)
print("Result:\(result)")
self = matrix_multiply(self, result)
}
}
How can I fix this issue?Any suggestions please?
I tried to translate the MATLAB language on Cordic wikipedia webpage
However when I type those:
print(cordic(beta: Double.pi/9, n: 20))
print(cordic(beta: Double.pi/8, n: 20))
I get
[-0.17163433840184755, 0.98516072489744066]
[-0.17163433840184755, 0.98516072489744066]
It's always giving me a constant answer. Why? I'm sure that the "angle" and "Kvalues" arrays are properly calculated.
Here's the code:
import Foundation
var angles: [Double] = []
for i: Double in stride(from: 0, to: 27, by: 1) {
angles.append(atan(pow(2, -i)))
}
var Kvalues: [Double] = []
for i: Double in stride(from: 0, to: 23, by: 1) {
Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i))))
if i > 0 {
Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2]
}
}
func min(_ a: Int, _ b: Int) -> Int {
return a > b ? b : a
}
func cordic(beta: Double, n: Int) -> [Double] {
var beta1 = beta
let Kn = Kvalues[min(n, Kvalues.count - 1)]
var v: [Double] = [1,0]
var poweroftwo: Double = 1
var angle = angles[0]
for j in 0 ..< n {
let sigma: Double = beta < 0 ? -1 : 1
let factor: Double = sigma * poweroftwo
v = [v[0] - v[1] * factor, v[1] + v[0] * factor]
beta1 -= sigma * angle
poweroftwo /= 2
angle = j + 2 > angles.count ? angle / 2 : angles[j + 2]
}
return [v[0] * Kn, v[1] * Kn]
}
print(cordic(beta: Double.pi/9, n: 20))
print(cordic(beta: Double.pi/8, n: 20))
You get the same result for different input because in
let sigma: Double = beta < 0 ? -1 : 1
beta should be beta1, which is the local variable that is
updated in the loop.
But even after fixing that the results are not correct, and that is
caused by two "off-by-one" index errors. The arrays in the algorithm
description are 1-based and Swift arrays are 0-based. So
let Kn = Kvalues[min(n, Kvalues.count - 1)]
// should be
let Kn = Kvalues[min(n-1, Kvalues.count - 1)]
and
angle = j + 2 > angles.count ? angle / 2 : angles[j + 2]
// should be
angle = j + 1 >= angles.count ? angle / 2 : angles[j + 1]
The angles and Kvalues arrays should be defined for i from 0 up to and including 27 resp. 23.
Finally, there is no need to define your own min function as there is one in the Swift standard library.
Putting it all together your code would be:
var angles: [Double] = []
for i: Double in stride(from: 0, through: 27, by: 1) {
angles.append(atan(pow(2, -i)))
}
var Kvalues: [Double] = []
for i: Double in stride(from: 0, through: 23, by: 1) {
Kvalues.append(1/sqrt(abs(Double(1) + pow(2,-2 * i))))
if i > 0 {
Kvalues[Kvalues.count - 1] *= Kvalues[Kvalues.count - 2]
}
}
func cordic(beta: Double, n: Int) -> [Double] {
var beta1 = beta
let Kn = Kvalues[min(n-1, Kvalues.count - 1)]
var v: [Double] = [1,0]
var poweroftwo: Double = 1
var angle = angles[0]
for j in 0 ..< n {
let sigma: Double = beta1 < 0 ? -1 : 1
let factor: Double = sigma * poweroftwo
v = [v[0] - v[1] * factor, v[1] + v[0] * factor]
beta1 -= sigma * angle
poweroftwo /= 2
angle = j + 1 >= angles.count ? angle / 2 : angles[j + 1]
}
return [v[0] * Kn, v[1] * Kn]
}
And that produces good approximations:
print(cordic(beta: Double.pi/9, n: 20)) // [0.93969210812600046, 0.34202155184390554]
print(cordic(beta: Double.pi/8, n: 20)) // [0.92388022188807306, 0.38268176805806309]
The exact values are
print(cos(Double.pi/9), sin(Double.pi/9)) // 0.939692620785908 0.342020143325669
print(cos(Double.pi/8), sin(Double.pi/8)) // 0.923879532511287 0.38268343236509
var xAxisImpulse = 0
var yAxisImpulse = 0
if angleToShoot < 90 && angleToShoot > 0 {
xAxisImpulse = cos(angleToShoot)*45 //cos is in radians
}
There is an error at the cos(). It says that because the angleToShoot var is an int, it can not be executed. How can I change this so that this can work?
You need to use CGFloat or Double as that this the data type used by the cos function.
var angleToShoot : CGFloat = 0.0
var xAxisImpulse : CGFloat = 0.0
var yAxisImpulse : CGFloat = 0.0
if angleToShoot < 90 && angleToShoot > 0 {
xAxisImpulse = cos(angleToShoot)*45 //cos is in radians
}